/*
- Glaurung, a UCI chess playing engine.
- Copyright (C) 2004-2008 Tord Romstad
+ Stockfish, a UCI chess playing engine derived from Glaurung 2.1
+ Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
+ Copyright (C) 2008 Marco Costalba
- Glaurung is free software: you can redistribute it and/or modify
+ Stockfish is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
-
- Glaurung is distributed in the hope that it will be useful,
+
+ Stockfish is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
////
#include <cassert>
-#include <cstdio>
#include "book.h"
#include "mersenne.h"
/// Indices to the Random64[] array
-
+
const int RandomPiece = 0;
const int RandomCastle = 768;
const int RandomEnPassant = 772;
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
-
+
uint64_t book_key(const Position &pos);
uint64_t book_piece_key(Piece p, Square s);
uint64_t book_castle_key(const Position &pos);
uint64_t book_ep_key(const Position &pos);
uint64_t book_color_key(const Position &pos);
- uint64_t read_integer(FILE *file, int size);
-
+ uint16_t read_integer16(std::ifstream& file);
+ uint64_t read_integer64(std::ifstream& file);
+ uint64_t read_integer(std::ifstream& file, int size);
}
/// Constructor
-Book::Book() {
- bookFile = NULL;
- bookSize = 0;
-}
+Book::Book() : bookSize(0) {}
/// Book::open() opens a book file with a given file name.
void Book::open(const std::string &fName) {
+
fileName = fName;
- bookFile = fopen(fileName.c_str(), "rb");
- if(bookFile != NULL) {
- if(fseek(bookFile, 0, SEEK_END) == -1) {
- std::cerr << "Failed to open book file " << fileName << std::endl;
- exit(EXIT_FAILURE);
- }
- bookSize = ftell(bookFile) / 16;
- if(bookSize == -1) {
+ bookFile.open(fileName.c_str(), std::ifstream::in | std::ifstream::binary);
+ if (!bookFile.is_open())
+ return;
+
+ bookFile.seekg(0, std::ios::end);
+ bookSize = bookFile.tellg() / 16;
+ bookFile.seekg(0, std::ios::beg);
+
+ if (!bookFile.good())
+ {
std::cerr << "Failed to open book file " << fileName << std::endl;
exit(EXIT_FAILURE);
- }
}
}
/// Book::close() closes the currently open book file.
void Book::close() {
- if(bookFile != NULL && fclose(bookFile) == EOF) {
- std::cerr << "Failed to close book file" << std::endl;
- exit(EXIT_FAILURE);
- }
+
+ if (bookFile.is_open())
+ bookFile.close();
}
/// Book::is_open() tests whether a book file has been opened.
bool Book::is_open() const {
- return bookFile != NULL && bookSize != 0;
+
+ return bookFile.is_open() && bookSize != 0;
}
/// or the empty string if no book is open.
const std::string Book::file_name() const {
- return this->is_open()? fileName : "";
+
+ return bookFile.is_open() ? fileName : "";
}
-
+
/// Book::get_move() gets a book move for a given position. Returns
/// MOVE_NONE if no book move is found.
/// file. The book entry is copied to the first input parameter.
void Book::read_entry(BookEntry& entry, int n) const {
+
assert(n >= 0 && n < bookSize);
- assert(bookFile != NULL);
+ assert(bookFile.is_open());
- if(fseek(bookFile, n*16, SEEK_SET) == -1) {
+ bookFile.seekg(n*16, std::ios_base::beg);
+ if (!bookFile.good())
+ {
std::cerr << "Failed to read book entry at index " << n << std::endl;
exit(EXIT_FAILURE);
}
-
- entry.key = read_integer(bookFile, 8);
- entry.move = read_integer(bookFile, 2);
- entry.count = read_integer(bookFile, 2);
- entry.n = read_integer(bookFile, 2);
- entry.sum = read_integer(bookFile, 2);
+ entry.key = read_integer64(bookFile);
+ entry.move = read_integer16(bookFile);
+ entry.count = read_integer16(bookFile);
+ entry.n = read_integer16(bookFile);
+ entry.sum = read_integer16(bookFile);
}
return result;
}
-
+
uint64_t book_piece_key(Piece p, Square s) {
return Random64[RandomPiece + (PieceTo12[int(p)]^1)*64 + int(s)];
return result;
}
-
+
uint64_t book_ep_key(const Position &pos) {
return (pos.ep_square() == SQ_NONE)?
0ULL : Random64[RandomEnPassant + square_file(pos.ep_square())];
}
-
+
uint64_t book_color_key(const Position &pos) {
return (pos.side_to_move() == WHITE)? Random64[RandomTurn] : 0ULL;
}
-
- uint64_t read_integer(FILE *file, int size) {
- uint64_t n = 0ULL;;
- int i;
- int b;
- assert(file != NULL);
- assert(size > 0 && size <= 8);
+ uint16_t read_integer16(std::ifstream& file) {
+
+ uint64_t n = read_integer(file, 2);
+ assert(n == (uint16_t)n);
+ return (uint16_t)n;
+ }
+
- for(i = 0; i < size; i++) {
- b = fgetc(file);
- if(b == EOF) {
+ 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;
exit(EXIT_FAILURE);
- }
- assert(b >= 0 && b < 256);
- n = (n << 8) | b;
}
+ // Numbers are stored in little endian format
+ uint64_t n = 0ULL;
+ for (int i = 0; i < size; i++)
+ n = (n << 8) + (unsigned char)buf[i];
+
return n;
}
-
}