1
0
Fork 0

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>
sf_2.3.1_base
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);
Bitboards::init();
Position::init();
Zobrist::init();
Bitbases::init_kpk();
Search::init();
Threads.init();

View File

@ -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.

View File

@ -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 {

View File

@ -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;