#ifndef QUADBOARD_H_INCLUDED
#define QUADBOARD_H_INCLUDED

#include "ramjet.h"
#include "bitboard.h"

// the quadboard datatype
typedef struct {
    // bb[0]: pawn, bishop, queen
    // bb[1]: knight, bishop, king
    // bb[2]: rook, queen, king
    // bb[3]: black pieces
    BITBOARD bb[4];
} QUADBOARD;

// set parts of the quadboard to zero
void qb_clear_all(QUADBOARD* qb);
void qb_clear_many(QUADBOARD* qb, BITBOARD bb);

// set or get the piece on a particular square
int qb_get_sq_pt(const QUADBOARD* qb, SQUARE sq);
int qb_get_sq_pc(const QUADBOARD* qb, SQUARE sq);
void qb_set_sq_pc(QUADBOARD* qb, SQUARE sq, int pc); // sq is assumed empty

// extract the specified subset from the quadboard
#define BB_MASK_PL(qb, pl) ((~(qb)->bb[3]) ^ BB_ALL(pl)) // warning: may contain empty squares
BITBOARD qb_get_bb_tot(const QUADBOARD* qb);
BITBOARD qb_get_bb_pl(const QUADBOARD* qb, PLAYER pl);
BITBOARD qb_get_bb_pt(const QUADBOARD* qb, PIECETYPE pt);

// return the king's square
int qb_get_k_sq(const QUADBOARD* qb, PLAYER pl);

// input-output in FEN format
void qb_scan_fen(const char* fen, QUADBOARD* qb);
void qb_print_fen(char* fen, const QUADBOARD* qb);

// compute a hash digest of the quadboard
HASHKEY qb_hash(const QUADBOARD* qb);

// find the location of the attackers of a particular square
BITBOARD bb_atk_sq(const QUADBOARD* qb, SQUARE sq, PLAYER foe);

// king under check
int is_k_in_check(const QUADBOARD* qb, PLAYER pl);

// sanity check on the quadboard
int is_qb_bad(const QUADBOARD* qb);

// test the functions above
int qb_test();

#endif // QUADBOARD_H_INCLUDED
