However, I think I may have found a bug in the code where the actual opening book is written. To make things short, Faile writes a 64-bit hash for each position along with an unsigned short int, called .freq, that counts the frequency, or the number of times a position occurs.
When it is time to write the actual data to the opening book file, it uses this code:
Code: Select all
void write_book (void) {
/* write our book to the binary file faile.obk */
...
/* write our book: */
for (i = 0; i <= b_hash_mask; i++) {
b_hash = b_hash_table[i];
if (b_hash.freq > 1) {
counter++;
fwrite (&b_hash, sizeof (b_hash_s), 1, book_out);
}
}
...
Code: Select all
if (b_hash.freq > 1) {
1. e4 e5 2. Nf3 Nf6 3. d4
0-1
1. e4 e5 2. Nf3 Nf6 3. Nxe5
0-1
... and Faile will only write the positions that correspond to the first 4 ply of each game -- the last move of each of these games, 3. d4 and 3. Nxe5, will not be written to the book. (I've tested this so I know that it is true.)
If this is not a bug, then why would it be considered desirable to eliminate all moves that only occur once from the book? (Yes, I can certainly see that this would reduce the physical size of the book file, but that seems like a poor excuse for cutting short so many lines.)
Is there some other reason to do this? Or does this indeed look like a bug?
The reason why I ask is that, if I were to implement my own opening book, I'd want to use the '?' as a signal to my program not to play a move so marked. But, you'd still want to be able to indicate a refutation line after the move, so that it is available to your program. Something like this:
1. f4 e6 2. g4? Qh4#
0-1
But if you eliminate all positions that only occur once from your opening book, then you wouldn't be able to store the refutation line. (Faile has no mechanism for marking such moves anyway, but still....)