bool is_pinned(const board_t * board, int from, int to, int colour) { int king; int inc; int sq, piece; ASSERT(board!=NULL); ASSERT(square_is_ok(from)); ASSERT(square_is_ok(to)); ASSERT(colour_is_ok(colour)); king = king_pos(board,colour); inc = DELTA_INC(king-from); if (inc == IncNone) return false; // not a line sq = from; do sq += inc; while (board->square[sq] == Empty); if (sq != king) return false; // blocker sq = from; do sq -= inc; while ((piece=board->square[sq]) == Empty); return square_is_ok(sq) && (piece & DELTA_MASK(king-sq)) != 0 && piece_colour(piece) == colour_opp(colour) && DELTA_INC(king-to) != inc; }
bool is_in_check(const board_t * board, int colour) { ASSERT(board_is_ok(board)); ASSERT(colour_is_ok(colour)); return is_attacked(board,king_pos(board,colour),colour_opp(colour)); }
int king_pos(const board_t * board, int colour) { ASSERT(board_is_ok(board)); ASSERT(colour_is_ok(colour)); return board->list[colour][0]; }
bool is_attacked(const board_t * board, int to, int colour) { const uint8 * ptr; int from, piece; ASSERT(board_is_ok(board)); ASSERT(square_is_ok(to)); ASSERT(colour_is_ok(colour)); for (ptr = board->list[colour]; (from=*ptr) != SquareNone; ptr++) { piece = board->square[from]; ASSERT(colour_equal(piece,colour)); if (piece_attack(board,piece,from,to)) return true; } return false; }
int colour_opp(int colour) { ASSERT(colour_is_ok(colour)); return colour ^ (BlackFlag^WhiteFlag); }
bool colour_equal(int colour_1, int colour_2) { ASSERT(colour_is_ok(colour_2)); return (colour_1 & colour_2) != 0; }
bool colour_is_black(int colour) { ASSERT(colour_is_ok(colour)); return colour == Black; }
bool colour_is_white(int colour) { ASSERT(colour_is_ok(colour)); return colour == White; }
bool board_is_ok(const board_t * board) { int sq, piece; int colour, pos; int king, rook; if (board == NULL) return false; // optional heavy DEBUG mode if (!UseSlowDebug) return true; // squares for (sq = 0; sq < SquareNb; sq++) { piece = board->square[sq]; if (square_is_ok(sq)) { pos = board->pos[sq]; if (piece == Empty) { if (pos != -1) return false; } else { if (pos < 0) return false; if (board->list[piece_colour(piece)][pos] != sq) return false; } } else { if (piece != Knight64) return false; } } // white piece list colour = White; pos = 0; if (board->list_size[colour] <= 0 || board->list_size[colour] > 16) return false; sq = board->list[colour][pos]; if (sq == SquareNone) return false; if (board->pos[sq] != pos) return false; piece = board->square[sq]; if (!colour_equal(piece,colour) || !piece_is_king(piece)) return false; for (pos++; pos < board->list_size[colour]; pos++) { sq = board->list[colour][pos]; if (sq == SquareNone) return false; if (board->pos[sq] != pos) return false; if (!colour_equal(board->square[sq],colour)) return false; } sq = board->list[colour][pos]; if (sq != SquareNone) return false; // black piece list colour = Black; pos = 0; if (board->list_size[colour] <= 0 || board->list_size[colour] > 16) return false; sq = board->list[colour][pos]; if (sq == SquareNone) return false; if (board->pos[sq] != pos) return false; piece = board->square[sq]; if (!colour_equal(piece,colour) || !piece_is_king(piece)) return false; for (pos++; pos < board->list_size[colour]; pos++) { sq = board->list[colour][pos]; if (sq == SquareNone) return false; if (board->pos[sq] != pos) return false; if (!colour_equal(board->square[sq],colour)) return false; } sq = board->list[colour][pos]; if (sq != SquareNone) return false; // TODO: material if (board->number[WhiteKing12] != 1) return false; if (board->number[BlackKing12] != 1) return false; if (!colour_is_ok(board->turn)) return false; // castling status if (board->castle[White][SideH] != SquareNone) { king = board->list[White][0]; if (king < A1 || king > H1) return false; if (board->square[king] != WhiteKing256) return false; rook = board->castle[White][SideH]; if (rook < A1 || rook > H1) return false; if (board->square[rook] != WhiteRook256) return false; if (rook <= king) return false; } if (board->castle[White][SideA] != SquareNone) { king = board->list[White][0]; if (king < A1 || king > H1) return false; if (board->square[king] != WhiteKing256) return false; rook = board->castle[White][SideA]; if (rook < A1 || rook > H1) return false; if (board->square[rook] != WhiteRook256) return false; if (rook >= king) return false; } if (board->castle[Black][SideH] != SquareNone) { king = board->list[Black][0]; if (king < A8 || king > H8) return false; if (board->square[king] != BlackKing256) return false; rook = board->castle[Black][SideH]; if (rook < A8 || rook > H8) return false; if (board->square[rook] != BlackRook256) return false; if (rook <= king) return false; } if (board->castle[Black][SideA] != SquareNone) { king = board->list[Black][0]; if (king < A8 || king > H8) return false; if (board->square[king] != BlackKing256) return false; rook = board->castle[Black][SideA]; if (rook < A8 || rook > H8) return false; if (board->square[rook] != BlackRook256) return false; if (rook >= king) return false; } return true; }
int piece_make_pawn(int colour) { ASSERT(colour_is_ok(colour)); return MakePawn[colour]; }