mirror of
https://github.com/sockspls/badfish
synced 2025-05-01 01:03:09 +00:00
Rewrite Book implementation
Let Book be derived directly from std::ifstream and rewrite the functions accordingly. Also simplify file reading by use of operator>>() No functional change. Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This commit is contained in:
parent
afadc33fb4
commit
a03b8074c8
2 changed files with 58 additions and 102 deletions
135
src/book.cpp
135
src/book.cpp
|
@ -35,6 +35,7 @@
|
||||||
#include "mersenne.h"
|
#include "mersenne.h"
|
||||||
#include "movegen.h"
|
#include "movegen.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
////
|
////
|
||||||
//// Global variables
|
//// Global variables
|
||||||
|
@ -53,7 +54,7 @@ namespace {
|
||||||
const int EntrySize = 16;
|
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] = {
|
||||||
0x9D39247E33776D41ULL, 0x2AF7398005AAA5C7ULL, 0x44DB015024623547ULL,
|
0x9D39247E33776D41ULL, 0x2AF7398005AAA5C7ULL, 0x44DB015024623547ULL,
|
||||||
|
@ -335,10 +336,6 @@ namespace {
|
||||||
uint64_t book_castle_key(const Position& pos);
|
uint64_t book_castle_key(const Position& pos);
|
||||||
uint64_t book_ep_key(const Position& pos);
|
uint64_t book_ep_key(const Position& pos);
|
||||||
uint64_t book_color_key(const Position& pos);
|
uint64_t book_color_key(const Position& pos);
|
||||||
|
|
||||||
uint16_t read_integer16(std::ifstream& file);
|
|
||||||
uint64_t read_integer64(std::ifstream& file);
|
|
||||||
uint64_t read_integer(std::ifstream& file, int size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -347,55 +344,43 @@ namespace {
|
||||||
////
|
////
|
||||||
|
|
||||||
|
|
||||||
/// Constructor
|
|
||||||
|
|
||||||
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 string& fName) {
|
||||||
|
|
||||||
fileName = fName;
|
fileName = fName;
|
||||||
bookFile.open(fileName.c_str(), std::ifstream::in | std::ifstream::binary);
|
ifstream::open(fileName.c_str(), ifstream::in | ifstream::binary);
|
||||||
if (!bookFile.is_open())
|
if (!is_open())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// get the book size in number of entries
|
// Get the book size in number of entries
|
||||||
bookFile.seekg(0, std::ios::end);
|
seekg(0, ios::end);
|
||||||
bookSize = bookFile.tellg() / EntrySize;
|
bookSize = tellg() / EntrySize;
|
||||||
bookFile.seekg(0, std::ios::beg);
|
seekg(0, ios::beg);
|
||||||
|
|
||||||
if (!bookFile.good())
|
if (!good())
|
||||||
{
|
{
|
||||||
std::cerr << "Failed to open book file " << fileName << std::endl;
|
cerr << "Failed to open book file " << fileName << endl;
|
||||||
bookFile.close();
|
close();
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Book::close() closes the currently open book file
|
/// Book::close() closes the file only if it is open, otherwise
|
||||||
|
/// we can end up in a little mess due to how std::ifstream works.
|
||||||
|
|
||||||
void Book::close() {
|
void Book::close() {
|
||||||
|
|
||||||
if (bookFile.is_open())
|
if (is_open())
|
||||||
bookFile.close();
|
ifstream::close();
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// Book::is_open() tests whether a book file has been opened.
|
|
||||||
|
|
||||||
bool Book::is_open() const {
|
|
||||||
|
|
||||||
return bookFile.is_open() && bookSize != 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Book::file_name() returns the file name of the currently active book,
|
/// Book::file_name() returns the file name of the currently active book,
|
||||||
/// or the empty string if no book is open.
|
/// or the empty string if no book is open.
|
||||||
|
|
||||||
const std::string Book::file_name() const {
|
const string Book::file_name() const {
|
||||||
|
|
||||||
return is_open() ? fileName : "";
|
return is_open() ? fileName : "";
|
||||||
}
|
}
|
||||||
|
@ -404,9 +389,9 @@ const std::string Book::file_name() const {
|
||||||
/// Book::get_move() gets a book move for a given position. Returns
|
/// Book::get_move() gets a book move for a given position. Returns
|
||||||
/// 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) {
|
||||||
|
|
||||||
if (!is_open())
|
if (!is_open() || bookSize == 0)
|
||||||
return MOVE_NONE;
|
return MOVE_NONE;
|
||||||
|
|
||||||
int bookMove = 0, scoresSum = 0;
|
int bookMove = 0, scoresSum = 0;
|
||||||
|
@ -414,9 +399,9 @@ Move Book::get_move(const Position& pos) const {
|
||||||
BookEntry entry;
|
BookEntry entry;
|
||||||
|
|
||||||
// Choose a book move among the possible moves for the given position
|
// Choose a book move among the possible moves for the given position
|
||||||
for (int i = find_key(key); i < bookSize; i++)
|
for (int idx = find_key(key); idx < bookSize; idx++)
|
||||||
{
|
{
|
||||||
read_entry(entry, i);
|
read_entry(entry, idx);
|
||||||
if (entry.key != key)
|
if (entry.key != key)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -449,7 +434,7 @@ Move Book::get_move(const Position& pos) const {
|
||||||
/// entry with the same key as the input is returned. When the key is not
|
/// entry with the same key as the input is returned. When the key is not
|
||||||
/// 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) {
|
||||||
|
|
||||||
int left, right, mid;
|
int left, right, mid;
|
||||||
BookEntry entry;
|
BookEntry entry;
|
||||||
|
@ -460,7 +445,7 @@ 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;
|
||||||
|
|
||||||
|
@ -472,6 +457,7 @@ int Book::find_key(uint64_t key) const {
|
||||||
else
|
else
|
||||||
left = mid + 1;
|
left = mid + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(left == right);
|
assert(left == right);
|
||||||
|
|
||||||
read_entry(entry, left);
|
read_entry(entry, left);
|
||||||
|
@ -483,23 +469,36 @@ int Book::find_key(uint64_t key) const {
|
||||||
/// input, and looks up the opening book entry at the given index in the book
|
/// input, and looks up the opening book entry at the given index in the book
|
||||||
/// file. The book entry is copied to the first input parameter.
|
/// file. The book entry is copied to the first input parameter.
|
||||||
|
|
||||||
void Book::read_entry(BookEntry& entry, int n) const {
|
void Book::read_entry(BookEntry& entry, int idx) {
|
||||||
|
|
||||||
assert(n >= 0 && n < bookSize);
|
assert(idx >= 0 && idx < bookSize);
|
||||||
assert(is_open());
|
assert(is_open());
|
||||||
|
|
||||||
bookFile.seekg(n * EntrySize, std::ios_base::beg);
|
seekg(idx * EntrySize, ios_base::beg);
|
||||||
if (!bookFile.good())
|
*this >> entry;
|
||||||
|
if (!good())
|
||||||
{
|
{
|
||||||
std::cerr << "Failed to read book entry at index " << n << std::endl;
|
cerr << "Failed to read book entry at index " << idx << endl;
|
||||||
bookFile.close();
|
close();
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
entry.key = read_integer64(bookFile);
|
}
|
||||||
entry.move = read_integer16(bookFile);
|
|
||||||
entry.count = read_integer16(bookFile);
|
|
||||||
entry.n = read_integer16(bookFile);
|
/// Book::read_integer() reads size chars from the file stream
|
||||||
entry.sum = read_integer16(bookFile);
|
/// and converts them in an integer number.
|
||||||
|
|
||||||
|
uint64_t Book::read_integer(int size) {
|
||||||
|
|
||||||
|
char buf[8];
|
||||||
|
read(buf, size);
|
||||||
|
|
||||||
|
// Numbers are stored on disk as a binary byte stream
|
||||||
|
uint64_t n = 0ULL;
|
||||||
|
for (int i = 0; i < size; i++)
|
||||||
|
n = (n << 8) + (unsigned char)buf[i];
|
||||||
|
|
||||||
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -517,7 +516,7 @@ namespace {
|
||||||
{
|
{
|
||||||
Bitboard b = pos.pieces_of_color(c);
|
Bitboard b = pos.pieces_of_color(c);
|
||||||
|
|
||||||
while (b != EmptyBoardBB)
|
while (b)
|
||||||
{
|
{
|
||||||
Square s = pop_1st_bit(&b);
|
Square s = pop_1st_bit(&b);
|
||||||
Piece p = pos.piece_on(s);
|
Piece p = pos.piece_on(s);
|
||||||
|
@ -528,7 +527,6 @@ namespace {
|
||||||
result ^= book_piece_key(p, s);
|
result ^= book_piece_key(p, s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
@ -573,39 +571,4 @@ namespace {
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint16_t read_integer16(std::ifstream& file) {
|
|
||||||
|
|
||||||
uint64_t n = read_integer(file, 2);
|
|
||||||
assert(n == (uint16_t)n);
|
|
||||||
return (uint16_t)n;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint64_t read_integer64(std::ifstream& file) {
|
|
||||||
|
|
||||||
return read_integer(file, 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint64_t read_integer(std::ifstream& file, int size) {
|
|
||||||
|
|
||||||
char buf[8];
|
|
||||||
file.read(buf, size);
|
|
||||||
|
|
||||||
if (!file.good())
|
|
||||||
{
|
|
||||||
std::cerr << "Failed to read " << size << " bytes from book file" << std::endl;
|
|
||||||
file.close();
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Numbers are stored on disk in big endian format
|
|
||||||
uint64_t n = 0ULL;
|
|
||||||
for (int i = 0; i < size; i++)
|
|
||||||
n = (n << 8) + (unsigned char)buf[i];
|
|
||||||
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
25
src/book.h
25
src/book.h
|
@ -52,31 +52,24 @@ struct BookEntry {
|
||||||
uint16_t sum;
|
uint16_t sum;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Book {
|
class Book : private std::ifstream {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Constructors
|
|
||||||
Book();
|
|
||||||
|
|
||||||
// Open and close book files
|
|
||||||
void open(const std::string& fName);
|
void open(const std::string& fName);
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
// Testing if a book is opened
|
|
||||||
bool is_open() const;
|
|
||||||
|
|
||||||
// The file name of the currently active book
|
|
||||||
const std::string file_name() const;
|
const std::string file_name() const;
|
||||||
|
Move get_move(const Position& pos);
|
||||||
// Get a book move for a given position
|
|
||||||
Move get_move(const Position& pos) const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int find_key(uint64_t key) const;
|
Book& operator>>(uint64_t& n) { n = read_integer(8); return *this; }
|
||||||
void read_entry(BookEntry& entry, int n) const;
|
Book& operator>>(uint16_t& n) { n = (uint16_t)read_integer(2); return *this; }
|
||||||
|
void operator>>(BookEntry& e) { *this >> e.key >> e.move >> e.count >> e.n >> e.sum; }
|
||||||
|
|
||||||
|
uint64_t read_integer(int size);
|
||||||
|
void read_entry(BookEntry& e, int n);
|
||||||
|
int find_key(uint64_t key);
|
||||||
|
|
||||||
std::string fileName;
|
std::string fileName;
|
||||||
mutable std::ifstream bookFile;
|
|
||||||
int bookSize;
|
int bookSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue