From: Marco Costalba Date: Sun, 27 Jan 2013 10:45:01 +0000 (+0100) Subject: Rewrite do_null_move() X-Git-Url: https://git.sesse.net/?p=stockfish;a=commitdiff_plain;h=2218a5836a48a764e9b57f5996520b48e0b3d236 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. --- diff --git a/src/position.cpp b/src/position.cpp index f3eb76f8..2cdcb4ae 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -953,10 +953,7 @@ void Position::undo_move(Move m) { sideToMove = ~sideToMove; if (type_of(m) == CASTLE) - { - do_castle_move(m); - return; - } + return do_castle_move(m); Color us = sideToMove; Color them = ~us; @@ -1082,11 +1079,9 @@ void Position::do_castle_move(Move m) { byColorBB[us] ^= k_from_to_bb ^ r_from_to_bb; // Update board - Piece king = make_piece(us, KING); - Piece rook = make_piece(us, ROOK); board[kfrom] = board[rfrom] = NO_PIECE; - board[kto] = king; - board[rto] = rook; + board[kto] = make_piece(us, KING); + board[rto] = make_piece(us, ROOK); // Update piece lists pieceList[us][KING][index[kfrom]] = kto; @@ -1101,8 +1096,8 @@ void Position::do_castle_move(Move m) { st->capturedType = NO_PIECE_TYPE; // Update incremental scores - st->psqScore += psq_delta(king, kfrom, kto); - st->psqScore += psq_delta(rook, rfrom, rto); + st->psqScore += psq_delta(make_piece(us, KING), kfrom, kto); + st->psqScore += psq_delta(make_piece(us, ROOK), rfrom, rto); // Update hash key 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 -/// to move and updates the hash key without executing any move on the board. -template -void Position::do_null_move(StateInfo& backupSt) { +/// Position::do(undo)_null_move() is used to do(undo) a "null move": It flips +/// the side to move without executing any move on the board. - assert(!checkers()); +void Position::do_null_move(StateInfo& newSt) { - // Back up the information necessary to undo the null move to the supplied - // 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; + assert(!checkers()); - dst->key = src->key; - dst->epSquare = src->epSquare; - dst->psqScore = src->psqScore; - dst->rule50 = src->rule50; - dst->pliesFromNull = src->pliesFromNull; + memcpy(&newSt, st, sizeof(StateInfo)); // Fully copy here - sideToMove = ~sideToMove; + newSt.previous = st; + st = &newSt; - if (Do) + if (st->epSquare != SQ_NONE) { - 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->key ^= Zobrist::enpassant[file_of(st->epSquare)]; st->epSquare = SQ_NONE; - st->rule50++; - st->pliesFromNull = 0; } + st->key ^= Zobrist::side; + prefetch((char*)TT.first_entry(st->key)); + + st->rule50++; + st->pliesFromNull = 0; + + sideToMove = ~sideToMove; + assert(pos_is_ok()); } -// Explicit template instantiations -template void Position::do_null_move(StateInfo& backupSt); -template void Position::do_null_move(StateInfo& backupSt); +void Position::undo_null_move() { + + assert(!checkers()); + + st = st->previous; + sideToMove = ~sideToMove; +} /// Position::see() is a static exchange evaluator: It tries to estimate the diff --git a/src/position.h b/src/position.h index b05d466e..235cc825 100644 --- a/src/position.h +++ b/src/position.h @@ -154,7 +154,8 @@ public: void do_move(Move m, StateInfo& st); void do_move(Move m, StateInfo& st, const CheckInfo& ci, bool moveIsCheck); void undo_move(Move m); - template void do_null_move(StateInfo& st); + void do_null_move(StateInfo& st); + void undo_null_move(); // Static exchange evaluation int see(Move m) const; diff --git a/src/search.cpp b/src/search.cpp index cfc15736..15c3b15a 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -667,12 +667,12 @@ namespace { if (eval - PawnValueMg > beta) R += ONE_PLY; - pos.do_null_move(st); + pos.do_null_move(st); (ss+1)->skipNullMove = true; nullValue = depth-R < ONE_PLY ? -qsearch(pos, ss+1, -beta, -alpha, DEPTH_ZERO) : - search(pos, ss+1, -beta, -alpha, depth-R); (ss+1)->skipNullMove = false; - pos.do_null_move(st); + pos.undo_null_move(); if (nullValue >= beta) {