#include <iostream>
#include "book.h"
+#include "misc.h"
#include "movegen.h"
using namespace std;
result ^= ZobCastle[3];
if (pos.ep_square() != SQ_NONE)
- result ^= ZobEnPassant[square_file(pos.ep_square())];
+ result ^= ZobEnPassant[file_of(pos.ep_square())];
if (pos.side_to_move() == WHITE)
result ^= ZobTurn[0];
}
-/// 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.
+/// Book::close() closes the file only if it is open, otherwise the call fails
+/// and the failbit internal state flag is set.
void Book::close() {
}
-/// Book::open() opens a book file with a given file name
+/// Book::open() opens a book file with a given name
void Book::open(const string& fileName) {
// Close old file before opening the new
close();
- bookFile.open(fileName.c_str(), ifstream::in | ifstream::binary);
+ bookFile.open(fileName.c_str(), ifstream::in | ifstream::binary |ios::ate);
// Silently return when asked to open a non-exsistent file
if (!bookFile.is_open())
return;
- // Get the book size in number of entries
- bookFile.seekg(0, ios::end);
+ // Get the book size in number of entries, we are already at the file end
bookSize = long(bookFile.tellg()) / sizeof(BookEntry);
if (!bookFile.good())
}
-/// Book::get_move() gets a book move for a given position. Returns
-/// MOVE_NONE if no book move is found. If findBestMove is true then
-/// return always the highest rated book move.
+/// Book::probe() gets a book move for a given position. Returns MOVE_NONE
+/// if no book move is found. If findBest is true then returns always the
+/// highest rated move otherwise chooses randomly based on the move score.
-Move Book::get_move(const Position& pos, bool findBestMove) {
+Move Book::probe(const Position& pos, bool findBest) {
if (!bookSize || !bookFile.is_open())
return MOVE_NONE;
BookEntry entry;
- int bookMove = MOVE_NONE;
- unsigned score, scoresSum = 0, bestScore = 0;
+ unsigned scoresSum = 0, bestScore = 0, bookMove = 0;
uint64_t key = book_key(pos);
+ int idx = first_entry(key) - 1;
// Choose a book move among the possible moves for the given position
- for (int idx = first_entry(key); idx < bookSize; idx++)
+ while (++idx < bookSize && (entry = read_entry(idx), entry.key == key))
{
- entry = read_entry(idx);
-
- if (entry.key != key)
- break;
-
- score = entry.count;
-
- if (!findBestMove)
- {
- // 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
- // with lower score. Note that first entry is always chosen.
- scoresSum += score;
- if (RKiss.rand<unsigned>() % scoresSum < score)
- bookMove = entry.move;
- }
- else if (score > bestScore)
- {
- bestScore = score;
+ scoresSum += entry.count;
+
+ // 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
+ // with lower score. Note that first entry is always chosen.
+ if ( RKiss.rand<unsigned>() % scoresSum < entry.count
+ || (findBest && entry.count > bestScore))
bookMove = entry.move;
- }
+
+ if (entry.count > bestScore)
+ bestScore = entry.count;
}
if (!bookMove)
int promotion = (bookMove >> 12) & 7;
if (promotion)
- bookMove = int(make_promotion_move(move_from(Move(bookMove)),
- move_to(Move(bookMove)),
- PieceType(promotion + 1)));
+ bookMove = make_promotion_move(move_from(Move(bookMove)),
+ move_to(Move(bookMove)),
+ PieceType(promotion + 1));
// Verify the book move is legal
for (MoveList<MV_LEGAL> ml(pos); !ml.end(); ++ml)
- if ((ml.move() & ~(3 << 14)) == bookMove) // Mask out special flags
+ if (unsigned(ml.move() & ~(3 << 14)) == bookMove) // Mask out special flags
return ml.move();
return MOVE_NONE;
n = 0;
for (size_t i = 0; i < sizeof(T); i++)
- n = (n << 8) + (T)bookFile.get();
+ n = T((n << 8) + bookFile.get());
return *this;
}