📄 make_move.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 + -