1
0
Fork 0
mirror of https://github.com/sockspls/badfish synced 2025-04-30 08:43:09 +00:00

Have fun with union in book.cpp

Fancy way to use an union to map polyglot
zobrist keys in one go.

Also some renaming while there.

No functional change.
This commit is contained in:
Marco Costalba 2013-01-05 15:24:18 +01:00
parent bff65a211f
commit 9b1cf3cf43
4 changed files with 34 additions and 33 deletions

View file

@ -38,7 +38,7 @@ namespace {
// A Polyglot book is a series of "entries" of 16 bytes. All integers are // A Polyglot book is a series of "entries" of 16 bytes. All integers are
// stored in big-endian format, with highest byte first (regardless of size). // stored in big-endian format, with highest byte first (regardless of size).
// The entries are ordered according to the key in ascending order. // The entries are ordered according to the key in ascending order.
struct BookEntry { struct Entry {
uint64_t key; uint64_t key;
uint16_t move; uint16_t move;
uint16_t count; uint16_t count;
@ -46,7 +46,15 @@ namespace {
}; };
// Random numbers from PolyGlot, used to compute book hash keys // Random numbers from PolyGlot, used to compute book hash keys
const Key PolyGlotRandoms[781] = { const union {
Key PolyGlotRandoms[781];
struct {
Key psq[12][64]; // [piece][square]
Key castle[4]; // [castle right]
Key enpassant[8]; // [file]
Key turn;
} Zobrist;
} PG = {{
0x9D39247E33776D41ULL, 0x2AF7398005AAA5C7ULL, 0x44DB015024623547ULL, 0x9D39247E33776D41ULL, 0x2AF7398005AAA5C7ULL, 0x44DB015024623547ULL,
0x9C15F73E62A76AE2ULL, 0x75834465489C0C89ULL, 0x3290AC3A203001BFULL, 0x9C15F73E62A76AE2ULL, 0x75834465489C0C89ULL, 0x3290AC3A203001BFULL,
0x0FBBAD1F61042279ULL, 0xE83A908FF2FB60CAULL, 0x0D7E765D58755C10ULL, 0x0FBBAD1F61042279ULL, 0xE83A908FF2FB60CAULL, 0x0D7E765D58755C10ULL,
@ -308,47 +316,40 @@ namespace {
0x003A93D8B2806962ULL, 0x1C99DED33CB890A1ULL, 0xCF3145DE0ADD4289ULL, 0x003A93D8B2806962ULL, 0x1C99DED33CB890A1ULL, 0xCF3145DE0ADD4289ULL,
0xD0E4427A5514FB72ULL, 0x77C621CC9FB3A483ULL, 0x67A34DAC4356550BULL, 0xD0E4427A5514FB72ULL, 0x77C621CC9FB3A483ULL, 0x67A34DAC4356550BULL,
0xF8D626AAAF278509ULL 0xF8D626AAAF278509ULL
}; }};
// Offsets to the PolyGlotRandoms[] array of zobrist keys // polyglot_key() returns the PolyGlot hash key of the given position
const Key* ZobPiece = PolyGlotRandoms; Key polyglot_key(const Position& pos) {
const Key* ZobCastle = ZobPiece + 12 * 64; // Pieces * squares
const Key* ZobEnPassant = ZobCastle + 4; // Castle flags
const Key* ZobTurn = ZobEnPassant + 8; // Number of files
// book_key() returns the PolyGlot hash key of the given position Key key = 0;
uint64_t book_key(const Position& pos) {
uint64_t key = 0;
Bitboard b = pos.pieces(); Bitboard b = pos.pieces();
while (b) while (b)
{ {
// In PolyGlotRandoms[] pieces are stored in the following sequence:
// BP = 0, WP = 1, BN = 2, WN = 3, ... BK = 10, WK = 11
Square s = pop_lsb(&b); Square s = pop_lsb(&b);
Piece p = pos.piece_on(s); Piece p = pos.piece_on(s);
int pieceOfs = 2 * (type_of(p) - 1) + (color_of(p) == WHITE);
key ^= ZobPiece[64 * pieceOfs + s]; // PolyGlot pieces are: BP = 0, WP = 1, BN = 2, ... BK = 10, WK = 11
key ^= PG.Zobrist.psq[2 * (type_of(p) - 1) + (color_of(p) == WHITE)][s];
} }
b = pos.can_castle(ALL_CASTLES); b = pos.can_castle(ALL_CASTLES);
while (b) while (b)
key ^= ZobCastle[pop_lsb(&b)]; key ^= PG.Zobrist.castle[pop_lsb(&b)];
if (pos.ep_square() != SQ_NONE) if (pos.ep_square() != SQ_NONE)
key ^= ZobEnPassant[file_of(pos.ep_square())]; key ^= PG.Zobrist.enpassant[file_of(pos.ep_square())];
if (pos.side_to_move() == WHITE) if (pos.side_to_move() == WHITE)
key ^= ZobTurn[0]; key ^= PG.Zobrist.turn;
return key; return key;
} }
} // namespace } // namespace
PolyglotBook::PolyglotBook() : RKiss(Time::now() % 10000) {} PolyglotBook::PolyglotBook() : rkiss(Time::now() % 10000) {}
PolyglotBook::~PolyglotBook() { if (is_open()) close(); } PolyglotBook::~PolyglotBook() { if (is_open()) close(); }
@ -366,7 +367,7 @@ template<typename T> PolyglotBook& PolyglotBook::operator>>(T& n) {
return *this; return *this;
} }
template<> PolyglotBook& PolyglotBook::operator>>(BookEntry& e) { template<> PolyglotBook& PolyglotBook::operator>>(Entry& e) {
return *this >> e.key >> e.move >> e.count >> e.learn; return *this >> e.key >> e.move >> e.count >> e.learn;
} }
@ -396,13 +397,13 @@ Move PolyglotBook::probe(const Position& pos, const string& fName, bool pickBest
if (fileName != fName && !open(fName.c_str())) if (fileName != fName && !open(fName.c_str()))
return MOVE_NONE; return MOVE_NONE;
BookEntry e; Entry e;
uint16_t best = 0; uint16_t best = 0;
unsigned sum = 0; unsigned sum = 0;
Move move = MOVE_NONE; Move move = MOVE_NONE;
uint64_t key = book_key(pos); Key key = polyglot_key(pos);
seekg(find_first(key) * sizeof(BookEntry), ios_base::beg); seekg(find_first(key) * sizeof(Entry), ios_base::beg);
while (*this >> e, e.key == key && good()) while (*this >> e, e.key == key && good())
{ {
@ -412,7 +413,7 @@ Move PolyglotBook::probe(const Position& pos, const string& fName, bool pickBest
// Choose book move according to its score. If a move has a very // Choose book move according to its score. If a move has a very
// high score it has higher probability to be choosen than a move // high score it has higher probability to be choosen than a move
// with lower score. Note that first entry is always chosen. // with lower score. Note that first entry is always chosen.
if ( (sum && RKiss.rand<unsigned>() % sum < e.count) if ( (sum && rkiss.rand<unsigned>() % sum < e.count)
|| (pickBest && e.count == best)) || (pickBest && e.count == best))
move = Move(e.move); move = Move(e.move);
} }
@ -447,12 +448,12 @@ Move PolyglotBook::probe(const Position& pos, const string& fName, bool pickBest
/// the book file for the given key. Returns the index of the leftmost book /// the book file for the given key. Returns the index of the leftmost book
/// entry with the same key as the input. /// entry with the same key as the input.
size_t PolyglotBook::find_first(uint64_t key) { size_t PolyglotBook::find_first(Key key) {
seekg(0, ios::end); // Move pointer to end, so tellg() gets file's size seekg(0, ios::end); // Move pointer to end, so tellg() gets file's size
size_t low = 0, mid, high = (size_t)tellg() / sizeof(BookEntry) - 1; size_t low = 0, mid, high = (size_t)tellg() / sizeof(Entry) - 1;
BookEntry e; Entry e;
assert(low <= high); assert(low <= high);
@ -462,7 +463,7 @@ size_t PolyglotBook::find_first(uint64_t key) {
assert(mid >= low && mid < high); assert(mid >= low && mid < high);
seekg(mid * sizeof(BookEntry), ios_base::beg); seekg(mid * sizeof(Entry), ios_base::beg);
*this >> e; *this >> e;
if (key <= e.key) if (key <= e.key)

View file

@ -36,9 +36,9 @@ private:
template<typename T> PolyglotBook& operator>>(T& n); template<typename T> PolyglotBook& operator>>(T& n);
bool open(const char* fName); bool open(const char* fName);
size_t find_first(uint64_t key); size_t find_first(Key key);
RKISS RKiss; RKISS rkiss;
std::string fileName; std::string fileName;
}; };

View file

@ -112,7 +112,7 @@ class Endgames {
public: public:
Endgames(); Endgames();
~Endgames(); ~Endgames();
template<typename T> T probe(Key key, T& eg) template<typename T> T probe(Key key, T& eg)
{ return eg = map(eg).count(key) ? map(eg)[key] : NULL; } { return eg = map(eg).count(key) ? map(eg)[key] : NULL; }

View file

@ -97,7 +97,7 @@ class TranspositionTable {
public: public:
TranspositionTable(); TranspositionTable();
~TranspositionTable(); ~TranspositionTable();
void set_size(size_t mbSize); void set_size(size_t mbSize);
void clear(); void clear();
void store(const Key posKey, Value v, Bound type, Depth d, Move m, Value statV, Value kingD); void store(const Key posKey, Value v, Bound type, Depth d, Move m, Value statV, Value kingD);