bool pseudo_is_legal(int move, board_t * board) { int me, opp; int from, to; int piece; bool legal; int king; undo_t undo[1]; ASSERT(move_is_ok(move)); ASSERT(board!=NULL); // init me = board->turn; opp = COLOUR_OPP(me); from = MOVE_FROM(move); to = MOVE_TO(move); piece = board->square[from]; ASSERT(COLOUR_IS(piece,me)); // slow test for en-passant captures if (MOVE_IS_EN_PASSANT(move)) { move_do(board,move,undo); legal = !IS_IN_CHECK(board,me); move_undo(board,move,undo); return legal; } // king moves (including castle) if (PIECE_IS_KING(piece)) { legal = !is_attacked(board,to,opp); if (DEBUG) { ASSERT(board->square[from]==piece); board->square[from] = Empty; ASSERT(legal==!is_attacked(board,to,opp)); board->square[from] = piece; } return legal; } // pins if (is_pinned(board,from,me)) { king = KING_POS(board,me); return DELTA_INC_LINE(king-to) == DELTA_INC_LINE(king-from); // does not discover the line } return true; }
static void add_check(list_t * list, int move, board_t * board) { undo_t undo[1]; ASSERT(list!=NULL); ASSERT(move_is_ok(move)); ASSERT(board!=NULL); move_do(board,move,undo); if (IS_IN_CHECK(board,board->turn)) LIST_ADD(list,move); move_undo(board,move,undo); }
bool move_is_check(int move, board_t * board) { undo_t undo[1]; bool check; int me, opp, king; int from, to, piece; ASSERT(move_is_ok(move)); ASSERT(board!=NULL); // slow test for complex moves if (MOVE_IS_SPECIAL(move)) { move_do(board,move,undo); check = IS_IN_CHECK(board,board->turn); move_undo(board,move,undo); return check; } // init me = board->turn; opp = COLOUR_OPP(me); king = KING_POS(board,opp); from = MOVE_FROM(move); to = MOVE_TO(move); piece = board->square[from]; ASSERT(COLOUR_IS(piece,me)); // direct check if (PIECE_ATTACK(board,piece,to,king)) return true; // indirect check if (is_pinned(board,from,opp) && DELTA_INC_LINE(king-to) != DELTA_INC_LINE(king-from)) { return true; } return false; }
bool board_is_stalemate(board_t * board) { list_t list[1]; int i, move; ASSERT(board!=NULL); // init if (IS_IN_CHECK(board,board->turn)) return false; // in check => not stalemate // move loop gen_moves(list,board); for (i = 0; i < LIST_SIZE(list); i++) { move = LIST_MOVE(list,i); if (pseudo_is_legal(move,board)) return false; // legal move => not stalemate } return true; // in check and no legal move => mate }
bool board_is_check(const board_t * board) { ASSERT(board!=NULL); return IS_IN_CHECK(board,board->turn); }
bool board_is_legal(const board_t * board) { ASSERT(board!=NULL); return !IS_IN_CHECK(board,COLOUR_OPP(board->turn)); }