From: Marco Costalba Date: Mon, 20 Aug 2012 17:09:57 +0000 (+0100) Subject: Move zobrist keys out of Position X-Git-Url: https://git.sesse.net/?p=stockfish;a=commitdiff_plain;h=7c8b7222f5eea024ab480abb2d9289fd1e42da9c Move zobrist keys out of Position Are used by Position but do not belong to that class, there is only one instance of them (that's why were defined as static), so move to a proper namespace instead. No functional change. Signed-off-by: Marco Costalba --- diff --git a/src/main.cpp b/src/main.cpp index d0e593da..ad68ca35 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -34,7 +34,7 @@ int main(int argc, char* argv[]) { UCI::init(Options); Bitboards::init(); - Position::init(); + Zobrist::init(); Bitbases::init_kpk(); Search::init(); Threads.init(); diff --git a/src/position.cpp b/src/position.cpp index 4d3f32a4..60bdeafb 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -36,13 +36,8 @@ using std::string; using std::cout; using std::endl; -Key Position::zobrist[2][8][64]; -Key Position::zobEp[8]; -Key Position::zobCastle[16]; -Key Position::zobSideToMove; -Key Position::zobExclusion; - -Score Position::pieceSquareTable[16][64]; +// To convert a Piece to and from a FEN char +static const string PieceToChar(" PNBRQK pnbrqk"); // Material values arrays, indexed by Piece const Value PieceValueMidgame[17] = { @@ -63,8 +58,62 @@ const Value PieceValueEndgame[17] = { RookValueEndgame, QueenValueEndgame }; -// To convert a Piece to and from a FEN char -static const string PieceToChar(" PNBRQK pnbrqk"); +CACHE_LINE_ALIGNMENT + +Score pieceSquareTable[16][64]; + +namespace Zobrist { + +Key psq[2][8][64]; // [color][pieceType][square]/[piece count] +Key enpassant[8]; // [file] +Key castle[16]; // [castleRight] +Key side; +Key exclusion; + +/// init() initializes at startup the various arrays used to compute hash keys +/// and the piece square tables. The latter is a two-step operation: First, the +/// white halves of the tables are copied from PSQT[] tables. Second, the black +/// halves of the tables are initialized by flipping and changing the sign of +/// the white scores. + +void init() { + + RKISS rk; + + for (Color c = WHITE; c <= BLACK; c++) + for (PieceType pt = PAWN; pt <= KING; pt++) + for (Square s = SQ_A1; s <= SQ_H8; s++) + psq[c][pt][s] = rk.rand(); + + for (File f = FILE_A; f <= FILE_H; f++) + enpassant[f] = rk.rand(); + + for (int cr = CASTLES_NONE; cr <= ALL_CASTLES; cr++) + { + Bitboard b = cr; + while (b) + { + Key k = castle[1ULL << pop_lsb(&b)]; + castle[cr] ^= k ? k : rk.rand(); + } + } + + side = rk.rand(); + exclusion = rk.rand(); + + for (PieceType pt = PAWN; pt <= KING; pt++) + { + Score v = make_score(PieceValueMidgame[pt], PieceValueEndgame[pt]); + + for (Square s = SQ_A1; s <= SQ_H8; s++) + { + pieceSquareTable[make_piece(WHITE, pt)][ s] = (v + PSQT[pt][s]); + pieceSquareTable[make_piece(BLACK, pt)][~s] = -(v + PSQT[pt][s]); + } + } +} + +} // namespace Zobrist /// CheckInfo c'tor @@ -709,7 +758,7 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI st = &newSt; // Update side to move - k ^= zobSideToMove; + k ^= Zobrist::side; // Increment the 50 moves rule draw counter. Resetting it to zero in the // case of a capture or a pawn move is taken care of later. @@ -756,7 +805,7 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI board[capsq] = NO_PIECE; } - st->pawnKey ^= zobrist[them][PAWN][capsq]; + st->pawnKey ^= Zobrist::psq[them][PAWN][capsq]; } else st->npMaterial[them] -= PieceValueMidgame[capture]; @@ -779,8 +828,8 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI pieceList[them][capture][pieceCount[them][capture]] = SQ_NONE; // Update hash keys - k ^= zobrist[them][capture][capsq]; - st->materialKey ^= zobrist[them][capture][pieceCount[them][capture]]; + k ^= Zobrist::psq[them][capture][capsq]; + st->materialKey ^= Zobrist::psq[them][capture][pieceCount[them][capture]]; // Update incremental scores st->psqScore -= pieceSquareTable[make_piece(them, capture)][capsq]; @@ -790,12 +839,12 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI } // Update hash key - k ^= zobrist[us][pt][from] ^ zobrist[us][pt][to]; + k ^= Zobrist::psq[us][pt][from] ^ Zobrist::psq[us][pt][to]; // Reset en passant square if (st->epSquare != SQ_NONE) { - k ^= zobEp[file_of(st->epSquare)]; + k ^= Zobrist::enpassant[file_of(st->epSquare)]; st->epSquare = SQ_NONE; } @@ -803,7 +852,7 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI if (st->castleRights && (castleRightsMask[from] | castleRightsMask[to])) { int cr = castleRightsMask[from] | castleRightsMask[to]; - k ^= zobCastle[st->castleRights & cr]; + k ^= Zobrist::castle[st->castleRights & cr]; st->castleRights &= ~cr; } @@ -832,7 +881,7 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI && (attacks_from(from + pawn_push(us), us) & pieces(them, PAWN))) { st->epSquare = Square((from + to) / 2); - k ^= zobEp[file_of(st->epSquare)]; + k ^= Zobrist::enpassant[file_of(st->epSquare)]; } if (type_of(m) == PROMOTION) @@ -857,10 +906,10 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI pieceList[us][promotion][index[to]] = to; // Update hash keys - k ^= zobrist[us][PAWN][to] ^ zobrist[us][promotion][to]; - st->pawnKey ^= zobrist[us][PAWN][to]; - st->materialKey ^= zobrist[us][promotion][pieceCount[us][promotion]++] - ^ zobrist[us][PAWN][pieceCount[us][PAWN]]; + k ^= Zobrist::psq[us][PAWN][to] ^ Zobrist::psq[us][promotion][to]; + st->pawnKey ^= Zobrist::psq[us][PAWN][to]; + st->materialKey ^= Zobrist::psq[us][promotion][pieceCount[us][promotion]++] + ^ Zobrist::psq[us][PAWN][pieceCount[us][PAWN]]; // Update incremental score st->psqScore += pieceSquareTable[make_piece(us, promotion)][to] @@ -871,7 +920,7 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI } // Update pawn hash key - st->pawnKey ^= zobrist[us][PAWN][from] ^ zobrist[us][PAWN][to]; + st->pawnKey ^= Zobrist::psq[us][PAWN][from] ^ Zobrist::psq[us][PAWN][to]; // Reset rule 50 draw counter st->rule50 = 0; @@ -1089,18 +1138,18 @@ void Position::do_castle_move(Move m) { st->psqScore += psq_delta(rook, rfrom, rto); // Update hash key - st->key ^= zobrist[us][KING][kfrom] ^ zobrist[us][KING][kto]; - st->key ^= zobrist[us][ROOK][rfrom] ^ zobrist[us][ROOK][rto]; + st->key ^= Zobrist::psq[us][KING][kfrom] ^ Zobrist::psq[us][KING][kto]; + st->key ^= Zobrist::psq[us][ROOK][rfrom] ^ Zobrist::psq[us][ROOK][rto]; // Clear en passant square if (st->epSquare != SQ_NONE) { - st->key ^= zobEp[file_of(st->epSquare)]; + st->key ^= Zobrist::enpassant[file_of(st->epSquare)]; st->epSquare = SQ_NONE; } // Update castling rights - st->key ^= zobCastle[st->castleRights & castleRightsMask[kfrom]]; + st->key ^= Zobrist::castle[st->castleRights & castleRightsMask[kfrom]]; st->castleRights &= ~castleRightsMask[kfrom]; // Update checkers BB @@ -1141,9 +1190,9 @@ void Position::do_null_move(StateInfo& backupSt) { if (Do) { if (st->epSquare != SQ_NONE) - st->key ^= zobEp[file_of(st->epSquare)]; + st->key ^= Zobrist::enpassant[file_of(st->epSquare)]; - st->key ^= zobSideToMove; + st->key ^= Zobrist::side; prefetch((char*)TT.first_entry(st->key)); st->epSquare = SQ_NONE; @@ -1320,19 +1369,19 @@ void Position::put_piece(Piece p, Square s) { Key Position::compute_key() const { - Key k = zobCastle[st->castleRights]; + Key k = Zobrist::castle[st->castleRights]; for (Bitboard b = pieces(); b; ) { Square s = pop_lsb(&b); - k ^= zobrist[color_of(piece_on(s))][type_of(piece_on(s))][s]; + k ^= Zobrist::psq[color_of(piece_on(s))][type_of(piece_on(s))][s]; } if (ep_square() != SQ_NONE) - k ^= zobEp[file_of(ep_square())]; + k ^= Zobrist::enpassant[file_of(ep_square())]; if (sideToMove == BLACK) - k ^= zobSideToMove; + k ^= Zobrist::side; return k; } @@ -1351,7 +1400,7 @@ Key Position::compute_pawn_key() const { for (Bitboard b = pieces(PAWN); b; ) { Square s = pop_lsb(&b); - k ^= zobrist[color_of(piece_on(s))][PAWN][s]; + k ^= Zobrist::psq[color_of(piece_on(s))][PAWN][s]; } return k; @@ -1371,7 +1420,7 @@ Key Position::compute_material_key() const { for (Color c = WHITE; c <= BLACK; c++) for (PieceType pt = PAWN; pt <= QUEEN; pt++) for (int cnt = 0; cnt < piece_count(c, pt); cnt++) - k ^= zobrist[c][pt][cnt]; + k ^= Zobrist::psq[c][pt][cnt]; return k; } @@ -1455,50 +1504,6 @@ template bool Position::is_draw() const; template bool Position::is_draw() const; -/// Position::init() is a static member function which initializes at startup -/// the various arrays used to compute hash keys and the piece square tables. -/// The latter is a two-step operation: First, the white halves of the tables -/// are copied from PSQT[] tables. Second, the black halves of the tables are -/// initialized by flipping and changing the sign of the white scores. - -void Position::init() { - - RKISS rk; - - for (Color c = WHITE; c <= BLACK; c++) - for (PieceType pt = PAWN; pt <= KING; pt++) - for (Square s = SQ_A1; s <= SQ_H8; s++) - zobrist[c][pt][s] = rk.rand(); - - for (File f = FILE_A; f <= FILE_H; f++) - zobEp[f] = rk.rand(); - - for (int cr = CASTLES_NONE; cr <= ALL_CASTLES; cr++) - { - Bitboard b = cr; - while (b) - { - Key k = zobCastle[1ULL << pop_lsb(&b)]; - zobCastle[cr] ^= k ? k : rk.rand(); - } - } - - zobSideToMove = rk.rand(); - zobExclusion = rk.rand(); - - for (PieceType pt = PAWN; pt <= KING; pt++) - { - Score v = make_score(PieceValueMidgame[pt], PieceValueEndgame[pt]); - - for (Square s = SQ_A1; s <= SQ_H8; s++) - { - pieceSquareTable[make_piece(WHITE, pt)][ s] = (v + PSQT[pt][s]); - pieceSquareTable[make_piece(BLACK, pt)][~s] = -(v + PSQT[pt][s]); - } - } -} - - /// Position::flip() flips position with the white and black sides reversed. This /// is only useful for debugging especially for finding evaluation symmetry bugs. diff --git a/src/position.h b/src/position.h index ed25c090..7418b0d3 100644 --- a/src/position.h +++ b/src/position.h @@ -189,9 +189,6 @@ public: bool pos_is_ok(int* failedStep = NULL) const; void flip(); - // Global initialization - static void init(); - private: // Initialization helpers (used while setting up a position) void clear(); @@ -230,14 +227,6 @@ private: Thread* thisThread; StateInfo* st; int chess960; - - // Static variables - static Score pieceSquareTable[16][64]; // [piece][square] - static Key zobrist[2][8][64]; // [color][pieceType][square]/[piece count] - static Key zobEp[8]; // [file] - static Key zobCastle[16]; // [castleRight] - static Key zobSideToMove; - static Key zobExclusion; }; inline int64_t Position::nodes_searched() const { @@ -366,7 +355,7 @@ inline Key Position::key() const { } inline Key Position::exclusion_key() const { - return st->key ^ zobExclusion; + return st->key ^ Zobrist::exclusion; } inline Key Position::pawn_key() const { diff --git a/src/types.h b/src/types.h index a9aa514c..d67b2eea 100644 --- a/src/types.h +++ b/src/types.h @@ -321,9 +321,21 @@ inline Score apply_weight(Score v, Score w) { #undef ENABLE_OPERATORS_ON #undef ENABLE_SAFE_OPERATORS_ON +namespace Zobrist { + + extern Key psq[2][8][64]; // [color][pieceType][square]/[piece count] + extern Key enpassant[8]; // [file] + extern Key castle[16]; // [castleRight] + extern Key side; + extern Key exclusion; + + void init(); +} + +extern Score pieceSquareTable[16][64]; +extern int SquareDistance[64][64]; extern const Value PieceValueMidgame[17]; // Indexed by Piece or PieceType extern const Value PieceValueEndgame[17]; -extern int SquareDistance[64][64]; struct MoveStack { Move move;