From fdb2804883deb31e3aeb15bbe588dcc9b7b76bd0 Mon Sep 17 00:00:00 2001 From: Mica White Date: Mon, 8 Dec 2025 19:56:48 -0500 Subject: Stuff --- engine/src/transposition_table.rs | 354 +++++++++++++++++++------------------- 1 file changed, 177 insertions(+), 177 deletions(-) mode change 100644 => 100755 engine/src/transposition_table.rs (limited to 'engine/src/transposition_table.rs') diff --git a/engine/src/transposition_table.rs b/engine/src/transposition_table.rs old mode 100644 new mode 100755 index 290ba68..e3cd59a --- a/engine/src/transposition_table.rs +++ b/engine/src/transposition_table.rs @@ -1,177 +1,177 @@ -use crate::{eval::Evaluation, CheckersBitBoard}; -use model::Move; -use parking_lot::RwLock; -use std::num::NonZeroU8; - -#[derive(Copy, Clone, Debug)] -struct TranspositionTableEntry { - board: CheckersBitBoard, - eval: Evaluation, - best_move: Move, - depth: NonZeroU8, -} - -impl TranspositionTableEntry { - const fn new( - board: CheckersBitBoard, - eval: Evaluation, - best_move: Move, - depth: NonZeroU8, - ) -> Self { - Self { - board, - eval, - best_move, - depth, - } - } -} - -pub struct TranspositionTable { - replace_table: Box<[RwLock>]>, - depth_table: Box<[RwLock>]>, -} - -#[derive(Copy, Clone, Debug)] -pub struct TranspositionTableRef<'a> { - replace_table: &'a [RwLock>], - depth_table: &'a [RwLock>], -} - -impl<'a> TranspositionTableRef<'a> { - pub fn get(self, board: CheckersBitBoard, depth: u8) -> Option<(Evaluation, Move)> { - let table_len = self.replace_table.as_ref().len(); - - // try the replace table - let entry = unsafe { - self.replace_table - .as_ref() - .get_unchecked(board.hash_code() as usize % table_len) - .read() - }; - if let Some(entry) = *entry { - if entry.board == board && entry.depth.get() >= depth { - return Some((entry.eval, entry.best_move)); - } - } - - // try the depth table - let entry = unsafe { - self.depth_table - .as_ref() - .get_unchecked(board.hash_code() as usize % table_len) - .read() - }; - match *entry { - Some(entry) => { - if entry.board == board { - if entry.depth.get() >= depth { - Some((entry.eval, entry.best_move)) - } else { - None - } - } else { - None - } - } - None => None, - } - } - - pub fn get_any_depth(self, board: CheckersBitBoard) -> Option { - let table_len = self.replace_table.as_ref().len(); - - // try the depth table - let entry = unsafe { - self.depth_table - .as_ref() - .get_unchecked(board.hash_code() as usize % table_len) - .read() - }; - if let Some(entry) = *entry { - if entry.board == board { - return Some(entry.eval); - } - } - - // try the replace table - let entry = unsafe { - self.replace_table - .as_ref() - .get_unchecked(board.hash_code() as usize % table_len) - .read() - }; - match *entry { - Some(entry) => { - if entry.board == board { - Some(entry.eval) - } else { - None - } - } - None => None, - } - } - - pub fn insert( - &self, - board: CheckersBitBoard, - eval: Evaluation, - best_move: Move, - depth: NonZeroU8, - ) { - let table_len = self.replace_table.as_ref().len(); - - // insert to the replace table - let mut entry = unsafe { - self.replace_table - .get_unchecked(board.hash_code() as usize % table_len) - .write() - }; - *entry = Some(TranspositionTableEntry::new(board, eval, best_move, depth)); - - // insert to the depth table, only if the new depth is higher - let mut entry = unsafe { - self.depth_table - .get_unchecked(board.hash_code() as usize % table_len) - .write() - }; - match *entry { - Some(entry_val) => { - if depth >= entry_val.depth { - *entry = Some(TranspositionTableEntry::new(board, eval, best_move, depth)); - } - } - None => *entry = Some(TranspositionTableEntry::new(board, eval, best_move, depth)), - } - } -} - -impl TranspositionTable { - pub fn new(table_size: usize) -> Self { - let table_size = - table_size / 2 / std::mem::size_of::>>(); - let mut replace_table = Box::new_uninit_slice(table_size); - let mut depth_table = Box::new_uninit_slice(table_size); - - for entry in replace_table.iter_mut() { - entry.write(RwLock::new(None)); - } - - for entry in depth_table.iter_mut() { - entry.write(RwLock::new(None)); - } - - Self { - replace_table: unsafe { replace_table.assume_init() }, - depth_table: unsafe { depth_table.assume_init() }, - } - } - - pub fn get_ref(&self) -> TranspositionTableRef { - TranspositionTableRef { - replace_table: &self.replace_table, - depth_table: &self.depth_table, - } - } -} +use crate::{eval::Evaluation, CheckersBitBoard}; +use model::Move; +use parking_lot::RwLock; +use std::num::NonZeroU8; + +#[derive(Copy, Clone, Debug)] +struct TranspositionTableEntry { + board: CheckersBitBoard, + eval: Evaluation, + best_move: Move, + depth: NonZeroU8, +} + +impl TranspositionTableEntry { + const fn new( + board: CheckersBitBoard, + eval: Evaluation, + best_move: Move, + depth: NonZeroU8, + ) -> Self { + Self { + board, + eval, + best_move, + depth, + } + } +} + +pub struct TranspositionTable { + replace_table: Box<[RwLock>]>, + depth_table: Box<[RwLock>]>, +} + +#[derive(Copy, Clone, Debug)] +pub struct TranspositionTableRef<'a> { + replace_table: &'a [RwLock>], + depth_table: &'a [RwLock>], +} + +impl<'a> TranspositionTableRef<'a> { + pub fn get(self, board: CheckersBitBoard, depth: u8) -> Option<(Evaluation, Move)> { + let table_len = self.replace_table.as_ref().len(); + + // try the replace table + let entry = unsafe { + self.replace_table + .as_ref() + .get_unchecked(board.hash_code() as usize % table_len) + .read() + }; + if let Some(entry) = *entry { + if entry.board == board && entry.depth.get() >= depth { + return Some((entry.eval, entry.best_move)); + } + } + + // try the depth table + let entry = unsafe { + self.depth_table + .as_ref() + .get_unchecked(board.hash_code() as usize % table_len) + .read() + }; + match *entry { + Some(entry) => { + if entry.board == board { + if entry.depth.get() >= depth { + Some((entry.eval, entry.best_move)) + } else { + None + } + } else { + None + } + } + None => None, + } + } + + pub fn get_any_depth(self, board: CheckersBitBoard) -> Option { + let table_len = self.replace_table.as_ref().len(); + + // try the depth table + let entry = unsafe { + self.depth_table + .as_ref() + .get_unchecked(board.hash_code() as usize % table_len) + .read() + }; + if let Some(entry) = *entry { + if entry.board == board { + return Some(entry.eval); + } + } + + // try the replace table + let entry = unsafe { + self.replace_table + .as_ref() + .get_unchecked(board.hash_code() as usize % table_len) + .read() + }; + match *entry { + Some(entry) => { + if entry.board == board { + Some(entry.eval) + } else { + None + } + } + None => None, + } + } + + pub fn insert( + &self, + board: CheckersBitBoard, + eval: Evaluation, + best_move: Move, + depth: NonZeroU8, + ) { + let table_len = self.replace_table.as_ref().len(); + + // insert to the replace table + let mut entry = unsafe { + self.replace_table + .get_unchecked(board.hash_code() as usize % table_len) + .write() + }; + *entry = Some(TranspositionTableEntry::new(board, eval, best_move, depth)); + + // insert to the depth table, only if the new depth is higher + let mut entry = unsafe { + self.depth_table + .get_unchecked(board.hash_code() as usize % table_len) + .write() + }; + match *entry { + Some(entry_val) => { + if depth >= entry_val.depth { + *entry = Some(TranspositionTableEntry::new(board, eval, best_move, depth)); + } + } + None => *entry = Some(TranspositionTableEntry::new(board, eval, best_move, depth)), + } + } +} + +impl TranspositionTable { + pub fn new(table_size: usize) -> Self { + let table_size = + table_size / 2 / std::mem::size_of::>>(); + let mut replace_table = Box::new_uninit_slice(table_size); + let mut depth_table = Box::new_uninit_slice(table_size); + + for entry in replace_table.iter_mut() { + entry.write(RwLock::new(None)); + } + + for entry in depth_table.iter_mut() { + entry.write(RwLock::new(None)); + } + + Self { + replace_table: unsafe { replace_table.assume_init() }, + depth_table: unsafe { depth_table.assume_init() }, + } + } + + pub fn get_ref(&self) -> TranspositionTableRef { + TranspositionTableRef { + replace_table: &self.replace_table, + depth_table: &self.depth_table, + } + } +} -- cgit v1.2.3