⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 make_move.cpp

📁 超强国际象棋引擎
💻 CPP
字号:
// move_do.cpp

// includes

#include "hash.h"
#include "move.h"
#include "make_move.h"
#include "pawn.h"
#include "position.h"
#include "random.h"
#include "values.h"

// variables

static int castle_mask[256];

// prototypes

static void square_clear(board_t *board, int square, int piece, bool update);
static void square_set(board_t *board, int square, int piece, int pos, bool update);
static void square_move(board_t *board, int from, int to, int piece, bool update);

// functions

// move_do_init()

void move_do_init()
    {

    int sq;

    for ( sq = 0; sq < 256; sq++ )
        castle_mask[sq] = 0xF;

    castle_mask[(0x48)] &= ~(1 << 0);
    castle_mask[(0x4B)] &= ~(1 << 0);

    castle_mask[(0x48)] &= ~(1 << 1);
    castle_mask[(0x44)] &= ~(1 << 1);

    castle_mask[(0xB8)] &= ~(1 << 2);
    castle_mask[(0xBB)] &= ~(1 << 2);

    castle_mask[(0xB8)] &= ~(1 << 3);
    castle_mask[(0xB4)] &= ~(1 << 3);
    }

// move_do()

void move_do(board_t *board, int move, undo_t *undo)
    {

    int me, opp;
    int from, to;
    int piece, pos, capture;
    int old_flags, new_flags;
    int delta;
    int sq;
    int pawn, rook;

    // initialise undo

    undo->capture = false;

    undo->turn = board->turn;
    undo->flags = board->flags;
    undo->ep_square = board->ep_square;
    undo->ply_nb = board->ply_nb;

    undo->cap_sq = board->cap_sq;
    undo->moving_piece = board->moving_piece;

    undo->opening = board->opening;
    undo->endgame = board->endgame;

    undo->key = board->key;
    undo->pawn_key = board->pawn_key;
    undo->material_key = board->material_key;

    // init

    me = board->turn;
    opp = COLOUR_OPP(me);

    from = MOVE_FROM(move);
    to = MOVE_TO(move);

    piece = board->square[from];
    board->moving_piece = piece;

    // update key stack

    board->stack[board->sp++] = board->key;

    // update turn

    board->turn = opp;
    board->key ^= RANDOM_64(780);

    // update castling rights

    old_flags = board->flags;
    new_flags = old_flags & castle_mask[from] & castle_mask[to];

    board->flags = new_flags;
    board->key ^= castle_64[new_flags ^ old_flags];

    // update en-passant square

    if((sq = board->ep_square) != 0)
        {
        board->key ^= RANDOM_64(772 + SQUARE_FILE(sq) - (0x4));
        board->ep_square = 0;
        }

    if(PIECE_IS_PAWN(piece))
        {

        delta = to - from;

        if(delta == +32 || delta == -32)
            {
            pawn = PAWN_MAKE(opp);

            if(board->square[to - 1] == pawn || board->square[to + 1] == pawn)
                {
                board->ep_square = (from + to) / 2;
                board->key ^= RANDOM_64(772 + SQUARE_FILE(to) - (0x4));
                }
            }
        }

    // update move number (captures are handled later)

    board->ply_nb++;

    if(PIECE_IS_PAWN(piece))
        board->ply_nb = 0; // conversion

    // update last square

    board->cap_sq = 0;

    // remove the captured piece

    sq = to;

    if(MOVE_IS_EN_PASSANT(move))
        sq = SQUARE_EP_DUAL(sq);

    if((capture = board->square[sq]) != 0)
        {

        undo->capture = true;
        undo->capture_square = sq;
        undo->capture_piece = capture;
        undo->capture_pos = board->pos[sq];

        square_clear(board, sq, capture, true);

        board->ply_nb = 0; // conversion
        board->cap_sq = to;
        }

    // move the piece

    if(MOVE_IS_PROMOTE(move))
        {

        // promote

        undo->pawn_pos = board->pos[from];

        square_clear(board, from, piece, true);

        piece = move_promote(move);

        // insert the promote piece in MV order

        for ( pos = board->piece_size[me]; pos > 0 && piece > board->square[board->piece[me][pos - 1]]; pos-- )
        ;

        square_set(board, to, piece, pos, true);

        board->cap_sq = to;
        }
    else
        {

        // normal move

        square_move(board, from, to, piece, true);
        }

    // move the rook in case of castling

    if(MOVE_IS_CASTLE(move))
        {

        rook = (1 << 6) | COLOUR_FLAG(me);

        if(to == (0x4A))
            {
            square_move(board, (0x4B), (0x49), rook, true);
            }
        else if(to == (0x46))
            {
            square_move(board, (0x44), (0x47), rook, true);
            }
        else if(to == (0xBA))
            {
            square_move(board, (0xBB), (0xB9), rook, true);
            }
        else if(to == (0xB6))
            {
            square_move(board, (0xB4), (0xB7), rook, true);
            }
        else { }
        }
    }

// move_undo()

void move_undo(board_t *board, int move, const undo_t *undo)
    {

    int me;
    int from, to;
    int piece, pos;
    int rook;

    // init

    me = undo->turn;

    from = MOVE_FROM(move);
    to = MOVE_TO(move);

    piece = board->square[to];

    // castle

    if(MOVE_IS_CASTLE(move))
        {

        rook = (1 << 6) | COLOUR_FLAG(me);

        if(to == (0x4A))
            {
            square_move(board, (0x49), (0x4B), rook, false);
            }
        else if(to == (0x46))
            {
            square_move(board, (0x47), (0x44), rook, false);
            }
        else if(to == (0xBA))
            {
            square_move(board, (0xB9), (0xBB), rook, false);
            }
        else if(to == (0xB6))
            {
            square_move(board, (0xB7), (0xB4), rook, false);
            }
        else { }
        }

    // move the piece backward

    if(MOVE_IS_PROMOTE(move))
        {

        // promote

        square_clear(board, to, piece, false);

        piece = PAWN_MAKE(me);
        pos = undo->pawn_pos;

        square_set(board, from, piece, pos, false);
        }
    else
        {

        // normal move

        square_move(board, to, from, piece, false);
        }

    // put the captured piece back

    if(undo->capture)
        {
        square_set(board, undo->capture_square, undo->capture_piece, undo->capture_pos, false);
        }

    // update board info

    board->turn = undo->turn;
    board->flags = undo->flags;
    board->ep_square = undo->ep_square;
    board->ply_nb = undo->ply_nb;

    board->cap_sq = undo->cap_sq;
    board->moving_piece = undo->moving_piece;

    board->opening = undo->opening;
    board->endgame = undo->endgame;

    board->key = undo->key;
    board->pawn_key = undo->pawn_key;
    board->material_key = undo->material_key;

    // update key stack

    board->sp--;
    }

// move_do_null()

void move_do_null(board_t *board, undo_t *undo)
    {

    int sq;

    // initialise undo

    undo->turn = board->turn;
    undo->ep_square = board->ep_square;
    undo->ply_nb = board->ply_nb;
    undo->cap_sq = board->cap_sq;
    undo->moving_piece = board->moving_piece;
    undo->key = board->key;

    // update key stack

    board->stack[board->sp++] = board->key;

    // update turn

    board->turn = COLOUR_OPP(board->turn);
    board->key ^= RANDOM_64(780);

    // update en-passant square

    sq = board->ep_square;

    if(sq != 0)
        {
        board->key ^= RANDOM_64(772 + SQUARE_FILE(sq) - (0x4));
        board->ep_square = 0;
        }

    // update move number

    board->ply_nb = 0;

    // update last square

    board->cap_sq = 0;
    board->moving_piece = 0;
    }

// move_undo_null()

void move_undo_null(board_t *board, const undo_t *undo)
    {

    // update board info

    board->turn = undo->turn;
    board->ep_square = undo->ep_square;
    board->ply_nb = undo->ply_nb;
    board->cap_sq = undo->cap_sq;
    board->moving_piece = undo->moving_piece;
    board->key = undo->key;

    // update key stack

    board->sp--;
    }

// square_clear()

static void square_clear(board_t *board, int square, int piece, bool update)
    {

    int pos, piece_12, color;
    int sq;
    int i, size;
    int sq_64;
    uint64 hash_xor;

    // init

    pos = board->pos[square];
    piece_12 = PIECE_TO_12(piece);
    color = PIECE_COLOUR(piece);

    // square

    board->square[square] = 0;

    // piece list

    if(!PIECE_IS_PAWN(piece))
        {

        // init

        size = board->piece_size[color];

        // stable swap

        board->pos[square] = -1;

        for ( i = pos; i < size - 1; i++ )
            {

            sq = board->piece[color][i + 1];
            board->piece[color][i] = sq;
            board->pos[sq] = i;
            }

        // size

        size--;

        board->piece[color][size] = 0;
        board->piece_size[color] = size;
        }
    else
        {

        // init

        size = board->pawn_size[color];

        // stable swap

        board->pos[square] = -1;

        for ( i = pos; i < size - 1; i++ )
            {

            sq = board->pawn[color][i + 1];
            board->pawn[color][i] = sq;
            board->pos[sq] = i;
            }

        // size

        size--;

        board->pawn[color][size] = 0;
        board->pawn_size[color] = size;

        // pawn "bitboard"

        board->pawn_file[color][SQUARE_FILE(square)] ^= BIT(PAWN_RANK(square, color));
        }

    // material

    board->piece_nb--;
    board->number[piece_12]--;
    board->piece_material[color] -= VALUE_PIECE(piece);

    // update

    if(update)
        {

        // init

        sq_64 = SQUARE_TO_64(square);

        // PST

        board->opening -= PST(piece_12, sq_64, 0);
        board->endgame -= PST(piece_12, sq_64, 1);

        // hash key

        hash_xor = RANDOM_64(0 + (piece_12 ^ 1) * 64 + sq_64);

        board->key ^= hash_xor;

        if(PIECE_IS_PAWN(piece))
            board->pawn_key ^= hash_xor;

        // material key

        board->material_key ^= RANDOM_64(piece_12 * 16 + board->number[piece_12]);
        }
    }

// square_set()

static void square_set(board_t *board, int square, int piece, int pos, bool update)
    {

    int piece_12, color;
    int sq;
    int i, size;
    int sq_64;
    uint64 hash_xor;

    // init

    piece_12 = PIECE_TO_12(piece);
    color = PIECE_COLOUR(piece);

    // square

    board->square[square] = piece;

    // piece list

    if(!PIECE_IS_PAWN(piece))
        {

        // init

        size = board->piece_size[color];

        // size

        size++;

        board->piece[color][size] = 0;
        board->piece_size[color] = size;

        // stable swap

        for ( i = size - 1; i > pos; i-- )
            {

            sq = board->piece[color][i - 1];
            board->piece[color][i] = sq;
            board->pos[sq] = i;
            }

        board->piece[color][pos] = square;

        board->pos[square] = pos;
        }
    else
        {

        // init

        size = board->pawn_size[color];

        // size

        size++;

        board->pawn[color][size] = 0;
        board->pawn_size[color] = size;

        // stable swap

        for ( i = size - 1; i > pos; i-- )
            {

            sq = board->pawn[color][i - 1];
            board->pawn[color][i] = sq;
            board->pos[sq] = i;
            }

        board->pawn[color][pos] = square;
        board->pos[square] = pos;

        // pawn "bitboard"

        board->pawn_file[color][SQUARE_FILE(square)] ^= BIT(PAWN_RANK(square, color));
        }

    // material

    board->piece_nb++;
    ;

    board->number[piece_12]++;
    board->piece_material[color] += VALUE_PIECE(piece);

    // update

    if(update)
        {

        // init

        sq_64 = SQUARE_TO_64(square);

        // PST

        board->opening += PST(piece_12, sq_64, 0);
        board->endgame += PST(piece_12, sq_64, 1);

        // hash key

        hash_xor = RANDOM_64(0 + (piece_12 ^ 1) * 64 + sq_64);

        board->key ^= hash_xor;

        if(PIECE_IS_PAWN(piece))
            board->pawn_key ^= hash_xor;

        // material key

        board->material_key ^= RANDOM_64(piece_12 * 16 + (board->number[piece_12] - 1));
        }
    }

// square_move()

static void square_move(board_t *board, int from, int to, int piece, bool update)
    {

    int color;
    int pos;
    int from_64, to_64;
    int piece_12;
    int piece_index;
    uint64 hash_xor;

    // init

    color = PIECE_COLOUR(piece);
    pos = board->pos[from];

    // from

    board->square[from] = 0;
    board->pos[from] = -1; // not needed

    // to

    board->square[to] = piece;
    board->pos[to] = pos;

    // piece list

    if(!PIECE_IS_PAWN(piece))
        {
        board->piece[color][pos] = to;
        }
    else
        {
        board->pawn[color][pos] = to;

        // pawn "bitboard"

        board->pawn_file[color][SQUARE_FILE(from)] ^= BIT(PAWN_RANK(from, color));
        board->pawn_file[color][SQUARE_FILE(to)] ^= BIT(PAWN_RANK(to, color));
        }

    // update

    if(update)
        {

        // init

        from_64 = SQUARE_TO_64(from);
        to_64 = SQUARE_TO_64(to);
        piece_12 = PIECE_TO_12(piece);

        // PST

        board->opening += PST(piece_12, to_64, 0) - PST(piece_12, from_64, 0);
        board->endgame += PST(piece_12, to_64, 1) - PST(piece_12, from_64, 1);

        // hash key

        piece_index = 0 + (piece_12 ^ 1) * 64;

        hash_xor = RANDOM_64(piece_index + to_64) ^ RANDOM_64(piece_index + from_64);

        board->key ^= hash_xor;

        if(PIECE_IS_PAWN(piece))
            board->pawn_key ^= hash_xor;
        }
    }

// end of move_do.cpp

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -