Skip to content

Commit 7c8b722

Browse files
committed
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>
1 parent ec9038b commit 7c8b722

4 files changed

Lines changed: 98 additions & 92 deletions

File tree

src/main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ int main(int argc, char* argv[]) {
3434

3535
UCI::init(Options);
3636
Bitboards::init();
37-
Position::init();
37+
Zobrist::init();
3838
Bitbases::init_kpk();
3939
Search::init();
4040
Threads.init();

src/position.cpp

Lines changed: 83 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,8 @@ using std::string;
3636
using std::cout;
3737
using std::endl;
3838

39-
Key Position::zobrist[2][8][64];
40-
Key Position::zobEp[8];
41-
Key Position::zobCastle[16];
42-
Key Position::zobSideToMove;
43-
Key Position::zobExclusion;
44-
45-
Score Position::pieceSquareTable[16][64];
39+
// To convert a Piece to and from a FEN char
40+
static const string PieceToChar(" PNBRQK pnbrqk");
4641

4742
// Material values arrays, indexed by Piece
4843
const Value PieceValueMidgame[17] = {
@@ -63,8 +58,62 @@ const Value PieceValueEndgame[17] = {
6358
RookValueEndgame, QueenValueEndgame
6459
};
6560

66-
// To convert a Piece to and from a FEN char
67-
static const string PieceToChar(" PNBRQK pnbrqk");
61+
CACHE_LINE_ALIGNMENT
62+
63+
Score pieceSquareTable[16][64];
64+
65+
namespace Zobrist {
66+
67+
Key psq[2][8][64]; // [color][pieceType][square]/[piece count]
68+
Key enpassant[8]; // [file]
69+
Key castle[16]; // [castleRight]
70+
Key side;
71+
Key exclusion;
72+
73+
/// init() initializes at startup the various arrays used to compute hash keys
74+
/// and the piece square tables. The latter is a two-step operation: First, the
75+
/// white halves of the tables are copied from PSQT[] tables. Second, the black
76+
/// halves of the tables are initialized by flipping and changing the sign of
77+
/// the white scores.
78+
79+
void init() {
80+
81+
RKISS rk;
82+
83+
for (Color c = WHITE; c <= BLACK; c++)
84+
for (PieceType pt = PAWN; pt <= KING; pt++)
85+
for (Square s = SQ_A1; s <= SQ_H8; s++)
86+
psq[c][pt][s] = rk.rand<Key>();
87+
88+
for (File f = FILE_A; f <= FILE_H; f++)
89+
enpassant[f] = rk.rand<Key>();
90+
91+
for (int cr = CASTLES_NONE; cr <= ALL_CASTLES; cr++)
92+
{
93+
Bitboard b = cr;
94+
while (b)
95+
{
96+
Key k = castle[1ULL << pop_lsb(&b)];
97+
castle[cr] ^= k ? k : rk.rand<Key>();
98+
}
99+
}
100+
101+
side = rk.rand<Key>();
102+
exclusion = rk.rand<Key>();
103+
104+
for (PieceType pt = PAWN; pt <= KING; pt++)
105+
{
106+
Score v = make_score(PieceValueMidgame[pt], PieceValueEndgame[pt]);
107+
108+
for (Square s = SQ_A1; s <= SQ_H8; s++)
109+
{
110+
pieceSquareTable[make_piece(WHITE, pt)][ s] = (v + PSQT[pt][s]);
111+
pieceSquareTable[make_piece(BLACK, pt)][~s] = -(v + PSQT[pt][s]);
112+
}
113+
}
114+
}
115+
116+
} // namespace Zobrist
68117

69118

70119
/// CheckInfo c'tor
@@ -709,7 +758,7 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI
709758
st = &newSt;
710759

711760
// Update side to move
712-
k ^= zobSideToMove;
761+
k ^= Zobrist::side;
713762

714763
// Increment the 50 moves rule draw counter. Resetting it to zero in the
715764
// 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
756805
board[capsq] = NO_PIECE;
757806
}
758807

759-
st->pawnKey ^= zobrist[them][PAWN][capsq];
808+
st->pawnKey ^= Zobrist::psq[them][PAWN][capsq];
760809
}
761810
else
762811
st->npMaterial[them] -= PieceValueMidgame[capture];
@@ -779,8 +828,8 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI
779828
pieceList[them][capture][pieceCount[them][capture]] = SQ_NONE;
780829

781830
// Update hash keys
782-
k ^= zobrist[them][capture][capsq];
783-
st->materialKey ^= zobrist[them][capture][pieceCount[them][capture]];
831+
k ^= Zobrist::psq[them][capture][capsq];
832+
st->materialKey ^= Zobrist::psq[them][capture][pieceCount[them][capture]];
784833

785834
// Update incremental scores
786835
st->psqScore -= pieceSquareTable[make_piece(them, capture)][capsq];
@@ -790,20 +839,20 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI
790839
}
791840

792841
// Update hash key
793-
k ^= zobrist[us][pt][from] ^ zobrist[us][pt][to];
842+
k ^= Zobrist::psq[us][pt][from] ^ Zobrist::psq[us][pt][to];
794843

795844
// Reset en passant square
796845
if (st->epSquare != SQ_NONE)
797846
{
798-
k ^= zobEp[file_of(st->epSquare)];
847+
k ^= Zobrist::enpassant[file_of(st->epSquare)];
799848
st->epSquare = SQ_NONE;
800849
}
801850

802851
// Update castle rights if needed
803852
if (st->castleRights && (castleRightsMask[from] | castleRightsMask[to]))
804853
{
805854
int cr = castleRightsMask[from] | castleRightsMask[to];
806-
k ^= zobCastle[st->castleRights & cr];
855+
k ^= Zobrist::castle[st->castleRights & cr];
807856
st->castleRights &= ~cr;
808857
}
809858

@@ -832,7 +881,7 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI
832881
&& (attacks_from<PAWN>(from + pawn_push(us), us) & pieces(them, PAWN)))
833882
{
834883
st->epSquare = Square((from + to) / 2);
835-
k ^= zobEp[file_of(st->epSquare)];
884+
k ^= Zobrist::enpassant[file_of(st->epSquare)];
836885
}
837886

838887
if (type_of(m) == PROMOTION)
@@ -857,10 +906,10 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI
857906
pieceList[us][promotion][index[to]] = to;
858907

859908
// Update hash keys
860-
k ^= zobrist[us][PAWN][to] ^ zobrist[us][promotion][to];
861-
st->pawnKey ^= zobrist[us][PAWN][to];
862-
st->materialKey ^= zobrist[us][promotion][pieceCount[us][promotion]++]
863-
^ zobrist[us][PAWN][pieceCount[us][PAWN]];
909+
k ^= Zobrist::psq[us][PAWN][to] ^ Zobrist::psq[us][promotion][to];
910+
st->pawnKey ^= Zobrist::psq[us][PAWN][to];
911+
st->materialKey ^= Zobrist::psq[us][promotion][pieceCount[us][promotion]++]
912+
^ Zobrist::psq[us][PAWN][pieceCount[us][PAWN]];
864913

865914
// Update incremental score
866915
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
871920
}
872921

873922
// Update pawn hash key
874-
st->pawnKey ^= zobrist[us][PAWN][from] ^ zobrist[us][PAWN][to];
923+
st->pawnKey ^= Zobrist::psq[us][PAWN][from] ^ Zobrist::psq[us][PAWN][to];
875924

876925
// Reset rule 50 draw counter
877926
st->rule50 = 0;
@@ -1089,18 +1138,18 @@ void Position::do_castle_move(Move m) {
10891138
st->psqScore += psq_delta(rook, rfrom, rto);
10901139

10911140
// Update hash key
1092-
st->key ^= zobrist[us][KING][kfrom] ^ zobrist[us][KING][kto];
1093-
st->key ^= zobrist[us][ROOK][rfrom] ^ zobrist[us][ROOK][rto];
1141+
st->key ^= Zobrist::psq[us][KING][kfrom] ^ Zobrist::psq[us][KING][kto];
1142+
st->key ^= Zobrist::psq[us][ROOK][rfrom] ^ Zobrist::psq[us][ROOK][rto];
10941143

10951144
// Clear en passant square
10961145
if (st->epSquare != SQ_NONE)
10971146
{
1098-
st->key ^= zobEp[file_of(st->epSquare)];
1147+
st->key ^= Zobrist::enpassant[file_of(st->epSquare)];
10991148
st->epSquare = SQ_NONE;
11001149
}
11011150

11021151
// Update castling rights
1103-
st->key ^= zobCastle[st->castleRights & castleRightsMask[kfrom]];
1152+
st->key ^= Zobrist::castle[st->castleRights & castleRightsMask[kfrom]];
11041153
st->castleRights &= ~castleRightsMask[kfrom];
11051154

11061155
// Update checkers BB
@@ -1141,9 +1190,9 @@ void Position::do_null_move(StateInfo& backupSt) {
11411190
if (Do)
11421191
{
11431192
if (st->epSquare != SQ_NONE)
1144-
st->key ^= zobEp[file_of(st->epSquare)];
1193+
st->key ^= Zobrist::enpassant[file_of(st->epSquare)];
11451194

1146-
st->key ^= zobSideToMove;
1195+
st->key ^= Zobrist::side;
11471196
prefetch((char*)TT.first_entry(st->key));
11481197

11491198
st->epSquare = SQ_NONE;
@@ -1320,19 +1369,19 @@ void Position::put_piece(Piece p, Square s) {
13201369

13211370
Key Position::compute_key() const {
13221371

1323-
Key k = zobCastle[st->castleRights];
1372+
Key k = Zobrist::castle[st->castleRights];
13241373

13251374
for (Bitboard b = pieces(); b; )
13261375
{
13271376
Square s = pop_lsb(&b);
1328-
k ^= zobrist[color_of(piece_on(s))][type_of(piece_on(s))][s];
1377+
k ^= Zobrist::psq[color_of(piece_on(s))][type_of(piece_on(s))][s];
13291378
}
13301379

13311380
if (ep_square() != SQ_NONE)
1332-
k ^= zobEp[file_of(ep_square())];
1381+
k ^= Zobrist::enpassant[file_of(ep_square())];
13331382

13341383
if (sideToMove == BLACK)
1335-
k ^= zobSideToMove;
1384+
k ^= Zobrist::side;
13361385

13371386
return k;
13381387
}
@@ -1351,7 +1400,7 @@ Key Position::compute_pawn_key() const {
13511400
for (Bitboard b = pieces(PAWN); b; )
13521401
{
13531402
Square s = pop_lsb(&b);
1354-
k ^= zobrist[color_of(piece_on(s))][PAWN][s];
1403+
k ^= Zobrist::psq[color_of(piece_on(s))][PAWN][s];
13551404
}
13561405

13571406
return k;
@@ -1371,7 +1420,7 @@ Key Position::compute_material_key() const {
13711420
for (Color c = WHITE; c <= BLACK; c++)
13721421
for (PieceType pt = PAWN; pt <= QUEEN; pt++)
13731422
for (int cnt = 0; cnt < piece_count(c, pt); cnt++)
1374-
k ^= zobrist[c][pt][cnt];
1423+
k ^= Zobrist::psq[c][pt][cnt];
13751424

13761425
return k;
13771426
}
@@ -1455,50 +1504,6 @@ template bool Position::is_draw<false>() const;
14551504
template bool Position::is_draw<true>() const;
14561505

14571506

1458-
/// Position::init() is a static member function which initializes at startup
1459-
/// the various arrays used to compute hash keys and the piece square tables.
1460-
/// The latter is a two-step operation: First, the white halves of the tables
1461-
/// are copied from PSQT[] tables. Second, the black halves of the tables are
1462-
/// initialized by flipping and changing the sign of the white scores.
1463-
1464-
void Position::init() {
1465-
1466-
RKISS rk;
1467-
1468-
for (Color c = WHITE; c <= BLACK; c++)
1469-
for (PieceType pt = PAWN; pt <= KING; pt++)
1470-
for (Square s = SQ_A1; s <= SQ_H8; s++)
1471-
zobrist[c][pt][s] = rk.rand<Key>();
1472-
1473-
for (File f = FILE_A; f <= FILE_H; f++)
1474-
zobEp[f] = rk.rand<Key>();
1475-
1476-
for (int cr = CASTLES_NONE; cr <= ALL_CASTLES; cr++)
1477-
{
1478-
Bitboard b = cr;
1479-
while (b)
1480-
{
1481-
Key k = zobCastle[1ULL << pop_lsb(&b)];
1482-
zobCastle[cr] ^= k ? k : rk.rand<Key>();
1483-
}
1484-
}
1485-
1486-
zobSideToMove = rk.rand<Key>();
1487-
zobExclusion = rk.rand<Key>();
1488-
1489-
for (PieceType pt = PAWN; pt <= KING; pt++)
1490-
{
1491-
Score v = make_score(PieceValueMidgame[pt], PieceValueEndgame[pt]);
1492-
1493-
for (Square s = SQ_A1; s <= SQ_H8; s++)
1494-
{
1495-
pieceSquareTable[make_piece(WHITE, pt)][ s] = (v + PSQT[pt][s]);
1496-
pieceSquareTable[make_piece(BLACK, pt)][~s] = -(v + PSQT[pt][s]);
1497-
}
1498-
}
1499-
}
1500-
1501-
15021507
/// Position::flip() flips position with the white and black sides reversed. This
15031508
/// is only useful for debugging especially for finding evaluation symmetry bugs.
15041509

src/position.h

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -189,9 +189,6 @@ class Position {
189189
bool pos_is_ok(int* failedStep = NULL) const;
190190
void flip();
191191

192-
// Global initialization
193-
static void init();
194-
195192
private:
196193
// Initialization helpers (used while setting up a position)
197194
void clear();
@@ -230,14 +227,6 @@ class Position {
230227
Thread* thisThread;
231228
StateInfo* st;
232229
int chess960;
233-
234-
// Static variables
235-
static Score pieceSquareTable[16][64]; // [piece][square]
236-
static Key zobrist[2][8][64]; // [color][pieceType][square]/[piece count]
237-
static Key zobEp[8]; // [file]
238-
static Key zobCastle[16]; // [castleRight]
239-
static Key zobSideToMove;
240-
static Key zobExclusion;
241230
};
242231

243232
inline int64_t Position::nodes_searched() const {
@@ -366,7 +355,7 @@ inline Key Position::key() const {
366355
}
367356

368357
inline Key Position::exclusion_key() const {
369-
return st->key ^ zobExclusion;
358+
return st->key ^ Zobrist::exclusion;
370359
}
371360

372361
inline Key Position::pawn_key() const {

src/types.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,9 +321,21 @@ inline Score apply_weight(Score v, Score w) {
321321
#undef ENABLE_OPERATORS_ON
322322
#undef ENABLE_SAFE_OPERATORS_ON
323323

324+
namespace Zobrist {
325+
326+
extern Key psq[2][8][64]; // [color][pieceType][square]/[piece count]
327+
extern Key enpassant[8]; // [file]
328+
extern Key castle[16]; // [castleRight]
329+
extern Key side;
330+
extern Key exclusion;
331+
332+
void init();
333+
}
334+
335+
extern Score pieceSquareTable[16][64];
336+
extern int SquareDistance[64][64];
324337
extern const Value PieceValueMidgame[17]; // Indexed by Piece or PieceType
325338
extern const Value PieceValueEndgame[17];
326-
extern int SquareDistance[64][64];
327339

328340
struct MoveStack {
329341
Move move;

0 commit comments

Comments
 (0)