1
0
Fork 0
mirror of https://github.com/sockspls/badfish synced 2025-05-01 17:19:36 +00:00

Space inflate book.cpp

Also document most interesting parts.

No functional change.

Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This commit is contained in:
Marco Costalba 2009-05-06 10:28:17 +02:00
parent 92ca97d121
commit afadc33fb4
3 changed files with 120 additions and 100 deletions

View file

@ -49,6 +49,10 @@ Book OpeningBook;
namespace { namespace {
/// Book entry size in bytes
const int EntrySize = 16;
/// Random numbers from PolyGlot, used to compute book hash keys. /// Random numbers from PolyGlot, used to compute book hash keys.
const uint64_t Random64[781] = { const uint64_t Random64[781] = {
@ -324,13 +328,6 @@ namespace {
const int RandomTurn = 780; const int RandomTurn = 780;
/// Convert pieces to the range 0..1
const int PieceTo12[] = {
0, 0, 2, 4, 6, 8, 10, 0, 0, 1, 3, 5, 7, 9, 11
};
/// Prototypes /// Prototypes
uint64_t book_key(const Position& pos); uint64_t book_key(const Position& pos);
@ -355,7 +352,7 @@ namespace {
Book::Book() : bookSize(0) {} Book::Book() : bookSize(0) {}
/// Book::open() opens a book file with a given file name. /// Book::open() opens a book file with a given file name
void Book::open(const std::string& fName) { void Book::open(const std::string& fName) {
@ -364,19 +361,21 @@ void Book::open(const std::string &fName) {
if (!bookFile.is_open()) if (!bookFile.is_open())
return; return;
// get the book size in number of entries
bookFile.seekg(0, std::ios::end); bookFile.seekg(0, std::ios::end);
bookSize = bookFile.tellg() / 16; bookSize = bookFile.tellg() / EntrySize;
bookFile.seekg(0, std::ios::beg); bookFile.seekg(0, std::ios::beg);
if (!bookFile.good()) if (!bookFile.good())
{ {
std::cerr << "Failed to open book file " << fileName << std::endl; std::cerr << "Failed to open book file " << fileName << std::endl;
bookFile.close();
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} }
/// Book::close() closes the currently open book file. /// Book::close() closes the currently open book file
void Book::close() { void Book::close() {
@ -398,7 +397,7 @@ bool Book::is_open() const {
const std::string Book::file_name() const { const std::string Book::file_name() const {
return bookFile.is_open() ? fileName : ""; return is_open() ? fileName : "";
} }
@ -406,33 +405,41 @@ const std::string Book::file_name() const {
/// MOVE_NONE if no book move is found. /// MOVE_NONE if no book move is found.
Move Book::get_move(const Position& pos) const { Move Book::get_move(const Position& pos) const {
if(this->is_open()) {
int bestMove = 0, bestScore = 0, move, score; if (!is_open())
return MOVE_NONE;
int bookMove = 0, scoresSum = 0;
uint64_t key = book_key(pos); uint64_t key = book_key(pos);
BookEntry entry; BookEntry entry;
for(int i = this->find_key(key); i < bookSize; i++) { // Choose a book move among the possible moves for the given position
this->read_entry(entry, i); for (int i = find_key(key); i < bookSize; i++)
{
read_entry(entry, i);
if (entry.key != key) if (entry.key != key)
break; break;
move = entry.move;
score = entry.count; int score = entry.count;
assert(score > 0); assert(score > 0);
bestScore += score; // Choose book move according to its score. If a move has a very
if(int(genrand_int32() % bestScore) < score) // high score it has more probability to be choosen then a one with
bestMove = move; // lower score. Note that first entry is always chosen.
scoresSum += score;
if (int(genrand_int32() % scoresSum) < score)
bookMove = entry.move;
} }
if (!bookMove)
return MOVE_NONE;
if(bestMove != 0) {
MoveStack moves[256]; MoveStack moves[256];
int n, j; int n = generate_legal_moves(pos, moves);
n = generate_legal_moves(pos, moves); for (int j = 0; j < n; j++)
for(j = 0; j < n; j++) if ((int(moves[j].move) & 07777) == bookMove)
if((int(moves[j].move) & 07777) == bestMove)
return moves[j].move; return moves[j].move;
}
}
return MOVE_NONE; return MOVE_NONE;
} }
@ -443,6 +450,7 @@ Move Book::get_move(const Position &pos) const {
/// found in the book file, bookSize is returned. /// found in the book file, bookSize is returned.
int Book::find_key(uint64_t key) const { int Book::find_key(uint64_t key) const {
int left, right, mid; int left, right, mid;
BookEntry entry; BookEntry entry;
@ -452,22 +460,21 @@ int Book::find_key(uint64_t key) const {
assert(left <= right); assert(left <= right);
while(left < right) { while(left < right)
{
mid = (left + right) / 2; mid = (left + right) / 2;
assert(mid >= left && mid < right); assert(mid >= left && mid < right);
this->read_entry(entry, mid); read_entry(entry, mid);
if (key <= entry.key) if (key <= entry.key)
right = mid; right = mid;
else else
left = mid + 1; left = mid + 1;
} }
assert(left == right); assert(left == right);
this->read_entry(entry, left); read_entry(entry, left);
return (entry.key == key)? left : bookSize; return (entry.key == key)? left : bookSize;
} }
@ -479,12 +486,13 @@ int Book::find_key(uint64_t key) const {
void Book::read_entry(BookEntry& entry, int n) const { void Book::read_entry(BookEntry& entry, int n) const {
assert(n >= 0 && n < bookSize); assert(n >= 0 && n < bookSize);
assert(bookFile.is_open()); assert(is_open());
bookFile.seekg(n*16, std::ios_base::beg); bookFile.seekg(n * EntrySize, std::ios_base::beg);
if (!bookFile.good()) if (!bookFile.good())
{ {
std::cerr << "Failed to read book entry at index " << n << std::endl; std::cerr << "Failed to read book entry at index " << n << std::endl;
bookFile.close();
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
entry.key = read_integer64(bookFile); entry.key = read_integer64(bookFile);
@ -502,15 +510,18 @@ void Book::read_entry(BookEntry& entry, int n) const {
namespace { namespace {
uint64_t book_key(const Position& pos) { uint64_t book_key(const Position& pos) {
uint64_t result = 0ULL; uint64_t result = 0ULL;
for(Color c = WHITE; c <= BLACK; c++) { for (Color c = WHITE; c <= BLACK; c++)
{
Bitboard b = pos.pieces_of_color(c); Bitboard b = pos.pieces_of_color(c);
Square s;
Piece p; while (b != EmptyBoardBB)
while(b != EmptyBoardBB) { {
s = pop_1st_bit(&b); Square s = pop_1st_bit(&b);
p = pos.piece_on(s); Piece p = pos.piece_on(s);
assert(piece_is_ok(p)); assert(piece_is_ok(p));
assert(color_of_piece(p) == c); assert(color_of_piece(p) == c);
@ -521,39 +532,46 @@ namespace {
result ^= book_castle_key(pos); result ^= book_castle_key(pos);
result ^= book_ep_key(pos); result ^= book_ep_key(pos);
result ^= book_color_key(pos); result ^= book_color_key(pos);
return result; return result;
} }
uint64_t book_piece_key(Piece p, Square s) { uint64_t book_piece_key(Piece p, Square s) {
/// Convert pieces to the range 0..11
static const int PieceTo12[] = { 0, 0, 2, 4, 6, 8, 10, 0, 0, 1, 3, 5, 7, 9, 11 };
return Random64[RandomPiece + (PieceTo12[int(p)]^1) * 64 + int(s)]; return Random64[RandomPiece + (PieceTo12[int(p)]^1) * 64 + int(s)];
} }
uint64_t book_castle_key(const Position& pos) { uint64_t book_castle_key(const Position& pos) {
uint64_t result = 0ULL; uint64_t result = 0ULL;
if (pos.can_castle_kingside(WHITE)) if (pos.can_castle_kingside(WHITE))
result ^= Random64[RandomCastle+0]; result ^= Random64[RandomCastle+0];
if (pos.can_castle_queenside(WHITE)) if (pos.can_castle_queenside(WHITE))
result ^= Random64[RandomCastle+1]; result ^= Random64[RandomCastle+1];
if (pos.can_castle_kingside(BLACK)) if (pos.can_castle_kingside(BLACK))
result ^= Random64[RandomCastle+2]; result ^= Random64[RandomCastle+2];
if (pos.can_castle_queenside(BLACK)) if (pos.can_castle_queenside(BLACK))
result ^= Random64[RandomCastle+3]; result ^= Random64[RandomCastle+3];
return result; return result;
} }
uint64_t book_ep_key(const Position& pos) { uint64_t book_ep_key(const Position& pos) {
return (pos.ep_square() == SQ_NONE)? return (pos.ep_square() == SQ_NONE ? 0ULL : Random64[RandomEnPassant + square_file(pos.ep_square())]);
0ULL : Random64[RandomEnPassant + square_file(pos.ep_square())];
} }
uint64_t book_color_key(const Position& pos) { uint64_t book_color_key(const Position& pos) {
return (pos.side_to_move() == WHITE)? Random64[RandomTurn] : 0ULL; return (pos.side_to_move() == WHITE ? Random64[RandomTurn] : 0ULL);
} }
@ -578,11 +596,12 @@ namespace {
if (!file.good()) if (!file.good())
{ {
std::cerr << "Failed to read " << size << " bytes from book file" std::cerr << "Failed to read " << size << " bytes from book file" << std::endl;
<< std::endl; file.close();
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
// Numbers are stored in little endian format
// Numbers are stored on disk in big endian format
uint64_t n = 0ULL; uint64_t n = 0ULL;
for (int i = 0; i < size; i++) for (int i = 0; i < size; i++)
n = (n << 8) + (unsigned char)buf[i]; n = (n << 8) + (unsigned char)buf[i];

View file

@ -38,6 +38,7 @@
# include <windows.h> # include <windows.h>
# include <time.h> # include <time.h>
# include "dos.h" # include "dos.h"
static int gettimeofday(struct timeval* tp, struct timezone*) static int gettimeofday(struct timeval* tp, struct timezone*)
{ {
SYSTEMTIME systime; SYSTEMTIME systime;