#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)]
#[repr(u8)]
pub enum TTFlag {
#[default]
Exact,
LowerBound,
UpperBound,
}
#[derive(Debug, Default, Copy, Clone)]
pub struct TTEntry {
pub key: u32,
pub value: i8,
pub flag: TTFlag,
pub depth: u8,
pub age: u8,
}
#[derive(Debug)]
pub struct TranspositionTable {
entries: Vec<TTEntry>,
age: u8,
}
impl TranspositionTable {
pub const MAX_SIZE: usize = (1 << 23) + 9;
pub fn new() -> TranspositionTable {
Self::default()
}
#[inline(always)]
pub fn index(&self, key: u64) -> usize {
(key % Self::MAX_SIZE as u64) as usize
}
pub fn reset(&mut self) {
self.age = self.age.wrapping_add(1);
}
pub fn put(&mut self, key: u64, value: i8, flag: TTFlag, depth: u8) {
let pos = self.index(key);
self.entries[pos].key = key as u32;
self.entries[pos].value = value;
self.entries[pos].flag = flag;
self.entries[pos].depth = depth;
self.entries[pos].age = self.age;
}
pub fn get(&self, key: u64) -> Option<&TTEntry> {
let pos = self.index(key);
let entry = &self.entries[pos];
if entry.key == key as u32 && entry.age == self.age {
Some(entry)
} else {
None
}
}
}
impl Default for TranspositionTable {
fn default() -> TranspositionTable {
TranspositionTable {
entries: vec![TTEntry::default(); Self::MAX_SIZE],
age: 0,
}
}
}