mirror of
https://github.com/sockspls/badfish
synced 2025-07-11 19:49:14 +00:00
Rewrite do_null_move()
Use a more traditional approach, along the same lines of do_move(). It is true that we copy more in do_null_move(), but we save the work in undo_null_move(). Speed test shows the new code to be even a bit faster. No functional change.
This commit is contained in:
parent
76a0d3c05a
commit
2218a5836a
3 changed files with 35 additions and 44 deletions
|
@ -953,10 +953,7 @@ void Position::undo_move(Move m) {
|
||||||
sideToMove = ~sideToMove;
|
sideToMove = ~sideToMove;
|
||||||
|
|
||||||
if (type_of(m) == CASTLE)
|
if (type_of(m) == CASTLE)
|
||||||
{
|
return do_castle_move<false>(m);
|
||||||
do_castle_move<false>(m);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Color us = sideToMove;
|
Color us = sideToMove;
|
||||||
Color them = ~us;
|
Color them = ~us;
|
||||||
|
@ -1082,11 +1079,9 @@ void Position::do_castle_move(Move m) {
|
||||||
byColorBB[us] ^= k_from_to_bb ^ r_from_to_bb;
|
byColorBB[us] ^= k_from_to_bb ^ r_from_to_bb;
|
||||||
|
|
||||||
// Update board
|
// Update board
|
||||||
Piece king = make_piece(us, KING);
|
|
||||||
Piece rook = make_piece(us, ROOK);
|
|
||||||
board[kfrom] = board[rfrom] = NO_PIECE;
|
board[kfrom] = board[rfrom] = NO_PIECE;
|
||||||
board[kto] = king;
|
board[kto] = make_piece(us, KING);
|
||||||
board[rto] = rook;
|
board[rto] = make_piece(us, ROOK);
|
||||||
|
|
||||||
// Update piece lists
|
// Update piece lists
|
||||||
pieceList[us][KING][index[kfrom]] = kto;
|
pieceList[us][KING][index[kfrom]] = kto;
|
||||||
|
@ -1101,8 +1096,8 @@ void Position::do_castle_move(Move m) {
|
||||||
st->capturedType = NO_PIECE_TYPE;
|
st->capturedType = NO_PIECE_TYPE;
|
||||||
|
|
||||||
// Update incremental scores
|
// Update incremental scores
|
||||||
st->psqScore += psq_delta(king, kfrom, kto);
|
st->psqScore += psq_delta(make_piece(us, KING), kfrom, kto);
|
||||||
st->psqScore += psq_delta(rook, rfrom, rto);
|
st->psqScore += psq_delta(make_piece(us, ROOK), rfrom, rto);
|
||||||
|
|
||||||
// Update hash key
|
// Update hash key
|
||||||
st->key ^= Zobrist::psq[us][KING][kfrom] ^ Zobrist::psq[us][KING][kto];
|
st->key ^= Zobrist::psq[us][KING][kfrom] ^ Zobrist::psq[us][KING][kto];
|
||||||
|
@ -1132,47 +1127,42 @@ void Position::do_castle_move(Move m) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Position::do_null_move() is used to do/undo a "null move": It flips the side
|
/// Position::do(undo)_null_move() is used to do(undo) a "null move": It flips
|
||||||
/// to move and updates the hash key without executing any move on the board.
|
/// the side to move without executing any move on the board.
|
||||||
template<bool Do>
|
|
||||||
void Position::do_null_move(StateInfo& backupSt) {
|
void Position::do_null_move(StateInfo& newSt) {
|
||||||
|
|
||||||
assert(!checkers());
|
assert(!checkers());
|
||||||
|
|
||||||
// Back up the information necessary to undo the null move to the supplied
|
memcpy(&newSt, st, sizeof(StateInfo)); // Fully copy here
|
||||||
// StateInfo object. Note that differently from normal case here backupSt
|
|
||||||
// is actually used as a backup storage not as the new state. This reduces
|
|
||||||
// the number of fields to be copied.
|
|
||||||
StateInfo* src = Do ? st : &backupSt;
|
|
||||||
StateInfo* dst = Do ? &backupSt : st;
|
|
||||||
|
|
||||||
dst->key = src->key;
|
newSt.previous = st;
|
||||||
dst->epSquare = src->epSquare;
|
st = &newSt;
|
||||||
dst->psqScore = src->psqScore;
|
|
||||||
dst->rule50 = src->rule50;
|
if (st->epSquare != SQ_NONE)
|
||||||
dst->pliesFromNull = src->pliesFromNull;
|
{
|
||||||
|
st->key ^= Zobrist::enpassant[file_of(st->epSquare)];
|
||||||
|
st->epSquare = SQ_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
st->key ^= Zobrist::side;
|
||||||
|
prefetch((char*)TT.first_entry(st->key));
|
||||||
|
|
||||||
|
st->rule50++;
|
||||||
|
st->pliesFromNull = 0;
|
||||||
|
|
||||||
sideToMove = ~sideToMove;
|
sideToMove = ~sideToMove;
|
||||||
|
|
||||||
if (Do)
|
|
||||||
{
|
|
||||||
if (st->epSquare != SQ_NONE)
|
|
||||||
st->key ^= Zobrist::enpassant[file_of(st->epSquare)];
|
|
||||||
|
|
||||||
st->key ^= Zobrist::side;
|
|
||||||
prefetch((char*)TT.first_entry(st->key));
|
|
||||||
|
|
||||||
st->epSquare = SQ_NONE;
|
|
||||||
st->rule50++;
|
|
||||||
st->pliesFromNull = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(pos_is_ok());
|
assert(pos_is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Explicit template instantiations
|
void Position::undo_null_move() {
|
||||||
template void Position::do_null_move<false>(StateInfo& backupSt);
|
|
||||||
template void Position::do_null_move<true>(StateInfo& backupSt);
|
assert(!checkers());
|
||||||
|
|
||||||
|
st = st->previous;
|
||||||
|
sideToMove = ~sideToMove;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Position::see() is a static exchange evaluator: It tries to estimate the
|
/// Position::see() is a static exchange evaluator: It tries to estimate the
|
||||||
|
|
|
@ -154,7 +154,8 @@ public:
|
||||||
void do_move(Move m, StateInfo& st);
|
void do_move(Move m, StateInfo& st);
|
||||||
void do_move(Move m, StateInfo& st, const CheckInfo& ci, bool moveIsCheck);
|
void do_move(Move m, StateInfo& st, const CheckInfo& ci, bool moveIsCheck);
|
||||||
void undo_move(Move m);
|
void undo_move(Move m);
|
||||||
template<bool Do> void do_null_move(StateInfo& st);
|
void do_null_move(StateInfo& st);
|
||||||
|
void undo_null_move();
|
||||||
|
|
||||||
// Static exchange evaluation
|
// Static exchange evaluation
|
||||||
int see(Move m) const;
|
int see(Move m) const;
|
||||||
|
|
|
@ -667,12 +667,12 @@ namespace {
|
||||||
if (eval - PawnValueMg > beta)
|
if (eval - PawnValueMg > beta)
|
||||||
R += ONE_PLY;
|
R += ONE_PLY;
|
||||||
|
|
||||||
pos.do_null_move<true>(st);
|
pos.do_null_move(st);
|
||||||
(ss+1)->skipNullMove = true;
|
(ss+1)->skipNullMove = true;
|
||||||
nullValue = depth-R < ONE_PLY ? -qsearch<NonPV, false>(pos, ss+1, -beta, -alpha, DEPTH_ZERO)
|
nullValue = depth-R < ONE_PLY ? -qsearch<NonPV, false>(pos, ss+1, -beta, -alpha, DEPTH_ZERO)
|
||||||
: - search<NonPV>(pos, ss+1, -beta, -alpha, depth-R);
|
: - search<NonPV>(pos, ss+1, -beta, -alpha, depth-R);
|
||||||
(ss+1)->skipNullMove = false;
|
(ss+1)->skipNullMove = false;
|
||||||
pos.do_null_move<false>(st);
|
pos.undo_null_move();
|
||||||
|
|
||||||
if (nullValue >= beta)
|
if (nullValue >= beta)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Reference in a new issue