/* Undoes a move on a board. */ void undo_move(board_t* board, move_t move) { #define UNDO_CASTLE(color, king_side_from, king_side_to, queen_side_from, queen_side_to) \ if (to_square > from_square) { UPDATE_CASTLE_BITBOARDS(color, color##_ROOK, king_side_from, king_side_to); } \ else { UPDATE_CASTLE_BITBOARDS(color, color##_ROOK, queen_side_from, queen_side_to); } #define UNDO_CAPTURE(other_color, square_offset) int captured_square = to_square; \ if (IS_ENPASSANT(move)) { \ captured_square += square_offset; \ } \ board->color_bitboard[other_color] |= SQUARE_MASK[captured_square]; \ board->piece_bitboard[captured_piece] |= SQUARE_MASK[captured_square]; \ board->pieces[captured_square] = captured_piece; #define UNDO_PROMOTION(pawn) board->piece_bitboard[promotion_piece] ^= SQUARE_MASK[to_square]; \ board->piece_bitboard[pawn] |= SQUARE_MASK[to_square]; board->state_index--; board->can_castle = board->state[board->state_index].can_castle; board->passed_square = board->state[board->state_index].passed_square; board->fifty_move_rule_counter = board->state[board->state_index].fifty_move_rule_counter; board->material[WHITE] = board->state[board->state_index].material[WHITE]; board->material[BLACK] = board->state[board->state_index].material[BLACK]; board->hash_key = board->state[board->state_index].hash_key; int from_square = MOVE_FROM(move), to_square = MOVE_TO(move), moving_piece = MOVING_PIECE(move), captured_piece = CAPTURED_PIECE(move), promotion_piece = PROMOTION_PIECE(move); bitboard_t from_to_bitboard = SQUARE_MASK[from_square] | SQUARE_MASK[to_square]; board->pieces[from_square] = moving_piece; board->pieces[to_square] = EMPTY; if (board->to_move == BLACK) { board->color_bitboard[WHITE] ^= from_to_bitboard; if (IS_CASTLE(move)) { UNDO_CASTLE(WHITE, H1, F1, A1, D1); } if (IS_PROMOTION(move)) { UNDO_PROMOTION(WHITE_PAWN); } if (captured_piece) { UNDO_CAPTURE(BLACK, -8); } if (moving_piece == WHITE_KING) board->king_position[WHITE] = from_square; else board->piece_bitboard[moving_piece] ^= from_to_bitboard; board->to_move = WHITE; } else { board->color_bitboard[BLACK] ^= from_to_bitboard; if (IS_CASTLE(move)) { UNDO_CASTLE(BLACK, H8, F8, A8, D8); } if (IS_PROMOTION(move)) { UNDO_PROMOTION(BLACK_PAWN); } if (captured_piece) { UNDO_CAPTURE(WHITE, 8); } if (moving_piece == BLACK_KING) board->king_position[BLACK] = from_square; else board->piece_bitboard[moving_piece] ^= from_to_bitboard; board->to_move = BLACK; } board->all_pieces_bitboard = board->color_bitboard[WHITE] | board->color_bitboard[BLACK]; }
static void movePawnExtra(position *pos, const move * const m, const int player) { /* if ep, remove the opponents pawn */ if(IS_EP(m)) { if(WHITE == player) { CLR_BIT(pos->pieces[BLACK], pos->epSquare - 8); CLR_BIT(pos->pawns[BLACK], pos->epSquare - 8); pos->board[pos->epSquare - 8] = 0; } else { CLR_BIT(pos->pieces[WHITE], pos->epSquare + 8); CLR_BIT(pos->pawns[WHITE], pos->epSquare + 8); pos->board[pos->epSquare + 8] = 0; } } else if(IS_PROMOTION(m)) { /* if promotion, replace 'to' pawn by promoted piece */ pos->board[m->to] = m->promoteTo; /* change board */ CLR_BIT(pos->pawns[player], m->to); /* pawn gone */ /* add new piece to its bitmap */ if(IS_KNIGHT(m->promoteTo)) { SET_BIT(pos->knights[player], m->to); } else if(IS_BISHOP(m->promoteTo)) { SET_BIT(pos->bishops[player], m->to); } else if(IS_ROOK(m->promoteTo)) { SET_BIT(pos->rooks[player], m->to); } else if(IS_QUEEN(m->promoteTo)) { SET_BIT(pos->queens[player], m->to); } else { assert(0); } } else { /* check if double advance and set ep square */ if(16 == abs(m->to - m->from)) { if(WHITE == player) { pos->epSquare = m->to - 8; } else { pos->epSquare = m->to + 8; } } } }