mirror of
https://github.com/HChaZZY/Stockfish.git
synced 2025-12-19 00:26:33 +08:00
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 <mcostalba@gmail.com>
This commit is contained in:
161
src/position.cpp
161
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<Key>();
|
||||
|
||||
for (File f = FILE_A; f <= FILE_H; f++)
|
||||
enpassant[f] = rk.rand<Key>();
|
||||
|
||||
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<Key>();
|
||||
}
|
||||
}
|
||||
|
||||
side = rk.rand<Key>();
|
||||
exclusion = rk.rand<Key>();
|
||||
|
||||
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<PAWN>(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<false>() const;
|
||||
template bool Position::is_draw<true>() 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<Key>();
|
||||
|
||||
for (File f = FILE_A; f <= FILE_H; f++)
|
||||
zobEp[f] = rk.rand<Key>();
|
||||
|
||||
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<Key>();
|
||||
}
|
||||
}
|
||||
|
||||
zobSideToMove = rk.rand<Key>();
|
||||
zobExclusion = rk.rand<Key>();
|
||||
|
||||
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.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user