#include <random>
class Board;
class Zobrist {
public:
Zobrist() = delete;
static inline U64 hash(const Board &board);
static inline constexpr U64 key_side() { return keys_side; }
static inline constexpr U64 key_castle(int exp) { return keys_castle[exp]; }
static inline constexpr U64 key_enpassant(square::Square square) {
return keys_enpassant[to_underlying(square)];
}
static inline constexpr U64 key_piece(piece::Type type, color::Color color, square::Square square) {
return keys_piece[piece::get_index(type, color)][to_underlying(square)];
namespace zobrist {
extern std::array<std::array<U64, 64>, 12> keys_piece;
extern std::array<U64, 64> keys_enpassant;
extern std::array<U64, 16> keys_castle;
const U64 keys_side = Random(C32(1699391443))();
inline void init() {
Random gen1(C64(1804289383));
for (piece::Type type : piece::TypeIter()) {
int piece_index_white = piece::get(type, color::Color::WHITE).index;
int piece_index_black = piece::get(type, color::Color::BLACK).index;
for (int square = 0; square < 64; square++) {
keys_piece[piece_index_white][square] = gen1();
keys_piece[piece_index_black][square] = gen1();
}
}
private:
using key_piece_array = std::array<std::array<U64, 64>, 12>;
static inline constexpr const key_piece_array keys_piece = []() constexpr -> key_piece_array {
key_piece_array key_piece;
Random gen(C64(1804289383));
for (piece::Type type : piece::TypeIter()) {
int piece_index_white = piece::get(type, color::Color::WHITE).index;
int piece_index_black = piece::get(type, color::Color::BLACK).index;
for (int square = 0; square < 64; square++) {
key_piece[piece_index_white][square] = gen();
key_piece[piece_index_black][square] = gen();
}
}
return key_piece;
}();
Random gen2(C32(337245213));
for (int castle = 0; castle < 64; castle++) {
keys_enpassant[castle] = gen2();
}
using key_enpassant_array = std::array<U64, 64>;
static inline constexpr const key_enpassant_array keys_enpassant = []() constexpr -> key_enpassant_array {
key_enpassant_array key_enpassant;
Random gen(C32(337245213));
for (int castle = 0; castle < 64; castle++) {
key_enpassant[castle] = gen();
}
return key_enpassant;
}();
Random gen3(C32(3642040919));
for (int castle = 0; castle < 16; castle++) {
keys_castle[castle] = gen3();
}
};
using key_castle_array = std::array<U64, 16>;
static inline constexpr const key_castle_array keys_castle = []() constexpr -> key_castle_array {
key_castle_array key_castle;
Random gen(C32(3642040919));
for (int castle = 0; castle < 16; castle++) {
key_castle[castle] = gen();
}
return key_castle;
}();
inline U64 hash(const Board &board);
inline constexpr U64 key_side() { return keys_side; }
inline constexpr U64 key_castle(int exp) { return keys_castle[exp]; }
inline constexpr U64 key_enpassant(square::Square square) { return keys_enpassant[to_underlying(square)]; }
inline constexpr U64 key_piece(piece::Type type, color::Color color, square::Square square) {
return keys_piece[piece::get_index(type, color)][to_underlying(square)];
}
static inline constexpr const U64 keys_side = Random(C32(1699391443))();
};
}; // namespace zobrist
#endif