1
0
Fork 0
mirror of https://github.com/sockspls/badfish synced 2025-05-01 17:19:36 +00: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:
Marco Costalba 2012-08-20 18:09:57 +01:00
parent ec9038b7b4
commit 7c8b7222f5
4 changed files with 98 additions and 92 deletions

View file

@ -34,7 +34,7 @@ int main(int argc, char* argv[]) {
UCI::init(Options); UCI::init(Options);
Bitboards::init(); Bitboards::init();
Position::init(); Zobrist::init();
Bitbases::init_kpk(); Bitbases::init_kpk();
Search::init(); Search::init();
Threads.init(); Threads.init();

View file

@ -36,13 +36,8 @@ using std::string;
using std::cout; using std::cout;
using std::endl; using std::endl;
Key Position::zobrist[2][8][64]; // To convert a Piece to and from a FEN char
Key Position::zobEp[8]; static const string PieceToChar(" PNBRQK pnbrqk");
Key Position::zobCastle[16];
Key Position::zobSideToMove;
Key Position::zobExclusion;
Score Position::pieceSquareTable[16][64];
// Material values arrays, indexed by Piece // Material values arrays, indexed by Piece
const Value PieceValueMidgame[17] = { const Value PieceValueMidgame[17] = {
@ -63,8 +58,62 @@ const Value PieceValueEndgame[17] = {
RookValueEndgame, QueenValueEndgame RookValueEndgame, QueenValueEndgame
}; };
// To convert a Piece to and from a FEN char CACHE_LINE_ALIGNMENT
static const string PieceToChar(" PNBRQK pnbrqk");
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 /// CheckInfo c'tor
@ -709,7 +758,7 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI
st = &newSt; st = &newSt;
// Update side to move // Update side to move
k ^= zobSideToMove; k ^= Zobrist::side;
// Increment the 50 moves rule draw counter. Resetting it to zero in the // 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. // 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; board[capsq] = NO_PIECE;
} }
st->pawnKey ^= zobrist[them][PAWN][capsq]; st->pawnKey ^= Zobrist::psq[them][PAWN][capsq];
} }
else else
st->npMaterial[them] -= PieceValueMidgame[capture]; 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; pieceList[them][capture][pieceCount[them][capture]] = SQ_NONE;
// Update hash keys // Update hash keys
k ^= zobrist[them][capture][capsq]; k ^= Zobrist::psq[them][capture][capsq];
st->materialKey ^= zobrist[them][capture][pieceCount[them][capture]]; st->materialKey ^= Zobrist::psq[them][capture][pieceCount[them][capture]];
// Update incremental scores // Update incremental scores
st->psqScore -= pieceSquareTable[make_piece(them, capture)][capsq]; 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 // 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 // Reset en passant square
if (st->epSquare != SQ_NONE) if (st->epSquare != SQ_NONE)
{ {
k ^= zobEp[file_of(st->epSquare)]; k ^= Zobrist::enpassant[file_of(st->epSquare)];
st->epSquare = SQ_NONE; 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])) if (st->castleRights && (castleRightsMask[from] | castleRightsMask[to]))
{ {
int cr = castleRightsMask[from] | castleRightsMask[to]; int cr = castleRightsMask[from] | castleRightsMask[to];
k ^= zobCastle[st->castleRights & cr]; k ^= Zobrist::castle[st->castleRights & cr];
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))) && (attacks_from<PAWN>(from + pawn_push(us), us) & pieces(them, PAWN)))
{ {
st->epSquare = Square((from + to) / 2); st->epSquare = Square((from + to) / 2);
k ^= zobEp[file_of(st->epSquare)]; k ^= Zobrist::enpassant[file_of(st->epSquare)];
} }
if (type_of(m) == PROMOTION) 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; pieceList[us][promotion][index[to]] = to;
// Update hash keys // Update hash keys
k ^= zobrist[us][PAWN][to] ^ zobrist[us][promotion][to]; k ^= Zobrist::psq[us][PAWN][to] ^ Zobrist::psq[us][promotion][to];
st->pawnKey ^= zobrist[us][PAWN][to]; st->pawnKey ^= Zobrist::psq[us][PAWN][to];
st->materialKey ^= zobrist[us][promotion][pieceCount[us][promotion]++] st->materialKey ^= Zobrist::psq[us][promotion][pieceCount[us][promotion]++]
^ zobrist[us][PAWN][pieceCount[us][PAWN]]; ^ Zobrist::psq[us][PAWN][pieceCount[us][PAWN]];
// Update incremental score // Update incremental score
st->psqScore += pieceSquareTable[make_piece(us, promotion)][to] 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 // 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 // Reset rule 50 draw counter
st->rule50 = 0; st->rule50 = 0;
@ -1089,18 +1138,18 @@ void Position::do_castle_move(Move m) {
st->psqScore += psq_delta(rook, rfrom, rto); st->psqScore += psq_delta(rook, rfrom, rto);
// Update hash key // Update hash key
st->key ^= zobrist[us][KING][kfrom] ^ zobrist[us][KING][kto]; st->key ^= Zobrist::psq[us][KING][kfrom] ^ Zobrist::psq[us][KING][kto];
st->key ^= zobrist[us][ROOK][rfrom] ^ zobrist[us][ROOK][rto]; st->key ^= Zobrist::psq[us][ROOK][rfrom] ^ Zobrist::psq[us][ROOK][rto];
// Clear en passant square // Clear en passant square
if (st->epSquare != SQ_NONE) if (st->epSquare != SQ_NONE)
{ {
st->key ^= zobEp[file_of(st->epSquare)]; st->key ^= Zobrist::enpassant[file_of(st->epSquare)];
st->epSquare = SQ_NONE; st->epSquare = SQ_NONE;
} }
// Update castling rights // Update castling rights
st->key ^= zobCastle[st->castleRights & castleRightsMask[kfrom]]; st->key ^= Zobrist::castle[st->castleRights & castleRightsMask[kfrom]];
st->castleRights &= ~castleRightsMask[kfrom]; st->castleRights &= ~castleRightsMask[kfrom];
// Update checkers BB // Update checkers BB
@ -1141,9 +1190,9 @@ void Position::do_null_move(StateInfo& backupSt) {
if (Do) if (Do)
{ {
if (st->epSquare != SQ_NONE) 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)); prefetch((char*)TT.first_entry(st->key));
st->epSquare = SQ_NONE; st->epSquare = SQ_NONE;
@ -1320,19 +1369,19 @@ void Position::put_piece(Piece p, Square s) {
Key Position::compute_key() const { Key Position::compute_key() const {
Key k = zobCastle[st->castleRights]; Key k = Zobrist::castle[st->castleRights];
for (Bitboard b = pieces(); b; ) for (Bitboard b = pieces(); b; )
{ {
Square s = pop_lsb(&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) if (ep_square() != SQ_NONE)
k ^= zobEp[file_of(ep_square())]; k ^= Zobrist::enpassant[file_of(ep_square())];
if (sideToMove == BLACK) if (sideToMove == BLACK)
k ^= zobSideToMove; k ^= Zobrist::side;
return k; return k;
} }
@ -1351,7 +1400,7 @@ Key Position::compute_pawn_key() const {
for (Bitboard b = pieces(PAWN); b; ) for (Bitboard b = pieces(PAWN); b; )
{ {
Square s = pop_lsb(&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; return k;
@ -1371,7 +1420,7 @@ Key Position::compute_material_key() const {
for (Color c = WHITE; c <= BLACK; c++) for (Color c = WHITE; c <= BLACK; c++)
for (PieceType pt = PAWN; pt <= QUEEN; pt++) for (PieceType pt = PAWN; pt <= QUEEN; pt++)
for (int cnt = 0; cnt < piece_count(c, pt); cnt++) for (int cnt = 0; cnt < piece_count(c, pt); cnt++)
k ^= zobrist[c][pt][cnt]; k ^= Zobrist::psq[c][pt][cnt];
return k; return k;
} }
@ -1455,50 +1504,6 @@ template bool Position::is_draw<false>() const;
template bool Position::is_draw<true>() 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 /// Position::flip() flips position with the white and black sides reversed. This
/// is only useful for debugging especially for finding evaluation symmetry bugs. /// is only useful for debugging especially for finding evaluation symmetry bugs.

View file

@ -189,9 +189,6 @@ public:
bool pos_is_ok(int* failedStep = NULL) const; bool pos_is_ok(int* failedStep = NULL) const;
void flip(); void flip();
// Global initialization
static void init();
private: private:
// Initialization helpers (used while setting up a position) // Initialization helpers (used while setting up a position)
void clear(); void clear();
@ -230,14 +227,6 @@ private:
Thread* thisThread; Thread* thisThread;
StateInfo* st; StateInfo* st;
int chess960; 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 { inline int64_t Position::nodes_searched() const {
@ -366,7 +355,7 @@ inline Key Position::key() const {
} }
inline Key Position::exclusion_key() const { inline Key Position::exclusion_key() const {
return st->key ^ zobExclusion; return st->key ^ Zobrist::exclusion;
} }
inline Key Position::pawn_key() const { inline Key Position::pawn_key() const {

View file

@ -321,9 +321,21 @@ inline Score apply_weight(Score v, Score w) {
#undef ENABLE_OPERATORS_ON #undef ENABLE_OPERATORS_ON
#undef ENABLE_SAFE_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 PieceValueMidgame[17]; // Indexed by Piece or PieceType
extern const Value PieceValueEndgame[17]; extern const Value PieceValueEndgame[17];
extern int SquareDistance[64][64];
struct MoveStack { struct MoveStack {
Move move; Move move;