namespace engine {
struct Hashe {
enum class Flag : uint8_t {
Exact,
Alpha,
Beta
};
U64 key;
Move best;
uint8_t depth;
int16_t score;
Flag flag;
};
class TTable {
public:
static inline constexpr const uint16_t unknown = 32500;
TTable() {}
TTable(U64 size) : table(size, {0}) {}
void clear() { table.clear(); };
int16_t read(const Board &board, int ply, Move *best, int16_t alpha, int16_t beta, uint8_t depth) const {
U64 hash = board.get_hash();
const Hashe &phashe = table[hash % table.size()];
if (phashe.key == hash) {
if (phashe.depth >= depth) {
int16_t score = phashe.score;
if (score < -MATE_SCORE) score += ply;
if (score > MATE_SCORE) score -= ply;
if (phashe.flag == Hashe::Flag::Exact) return score;
if ((phashe.flag == Hashe::Flag::Alpha) && (score <= alpha)) return alpha;
if ((phashe.flag == Hashe::Flag::Beta) && (score >= beta)) return beta;
}
*best = phashe.best;
}
return unknown;
}
void write(const Board &board, int ply, Move best, int16_t score, uint8_t depth, Hashe::Flag flag) {
U64 hash = board.get_hash();
Hashe &phashe = table[hash % table.size()];
if (score < -MATE_SCORE) score += ply;
if (score > MATE_SCORE) score -= ply;
phashe = {hash, best, depth, score, flag};
}
private:
std::vector<Hashe> table;
};
Board board;
TTable ttable(C64(0x400000));
TTable ttable;
Move pv_table[MAX_PLY][MAX_PLY];
Move killer[2][MAX_PLY];
U32 history[12][64];