Beispiel #1
0
/*
    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];
}
Beispiel #2
0
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;
            }
        }
    }
}