use crate::CheckersBitBoard; #[cfg(debug_assertions)] const TABLE_SIZE: usize = 1_000_000 / std::mem::size_of::(); #[cfg(not(debug_assertions))] const TABLE_SIZE: usize = 10_000_000 / std::mem::size_of::(); const EMPTY_ENTRY: Option = None; static mut REPLACE_TABLE: [Option; TABLE_SIZE] = [EMPTY_ENTRY; TABLE_SIZE]; static mut DEPTH_TABLE: [Option; TABLE_SIZE] = [EMPTY_ENTRY; TABLE_SIZE]; #[derive(Copy, Clone, Debug)] struct TranspositionTableEntry { board: CheckersBitBoard, eval: f32, depth: u8, } pub struct TranspositionTableReference { replace_table: &'static mut [Option; TABLE_SIZE], depth_table: &'static mut [Option; TABLE_SIZE], } impl TranspositionTableEntry { const fn new(board: CheckersBitBoard, eval: f32, depth: u8) -> Self { Self { board, eval, depth } } } impl TranspositionTableReference { pub fn new() -> Self { Self { replace_table: unsafe { &mut REPLACE_TABLE }, depth_table: unsafe { &mut DEPTH_TABLE }, } } pub fn get(self, board: CheckersBitBoard, depth: u8) -> Option { // try the replace table let entry = unsafe { self.replace_table .get_unchecked(board.hash_code() as usize % TABLE_SIZE) }; if let Some(entry) = *entry { if entry.board == board && entry.depth >= depth { return Some(entry.eval); } } // try the depth table let entry = unsafe { self.depth_table .get_unchecked(board.hash_code() as usize % TABLE_SIZE) }; match *entry { Some(entry) => { if entry.board == board { if entry.depth >= depth { Some(entry.eval) } else { None } } else { None } } None => None, } } pub fn insert(self, board: CheckersBitBoard, eval: f32, depth: u8) { // insert to the replace table let entry = unsafe { self.replace_table .get_unchecked_mut(board.hash_code() as usize % TABLE_SIZE) }; *entry = Some(TranspositionTableEntry::new(board, eval, depth)); // insert to the depth table, only if the new depth is higher let entry = unsafe { self.depth_table .get_unchecked_mut(board.hash_code() as usize % TABLE_SIZE) }; match *entry { Some(entry_val) => { if depth >= entry_val.depth { *entry = Some(TranspositionTableEntry::new(board, eval, depth)); } } None => *entry = Some(TranspositionTableEntry::new(board, eval, depth)), } } }