summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engine/src/search.rs13
-rw-r--r--engine/src/transposition_table.rs36
2 files changed, 36 insertions, 13 deletions
diff --git a/engine/src/search.rs b/engine/src/search.rs
index 9c8ea26..4326ac6 100644
--- a/engine/src/search.rs
+++ b/engine/src/search.rs
@@ -42,8 +42,8 @@ pub fn negamax(
}
} else {
let table = task.transposition_table;
- if let Some(entry) = table.get(board, depth) {
- return (entry, None);
+ if let Some((entry, best_move)) = table.get(board, depth) {
+ return (entry, Some(best_move));
}
let turn = board.turn();
@@ -93,9 +93,14 @@ pub fn negamax(
}
}
- table.insert(board, best_eval, unsafe { NonZeroU8::new_unchecked(depth) });
+ // safety: we already checked that the list isn't empty, so there must
+ // be at least one move here
+ let best_move = unsafe { best_move.unwrap_unchecked() };
+ // safety: in the case of a zero depth, a different branch is taken
+ let depth = unsafe { NonZeroU8::new_unchecked(depth) };
+ table.insert(board, best_eval, best_move, depth);
- (best_eval, best_move)
+ (best_eval, Some(best_move))
}
}
diff --git a/engine/src/transposition_table.rs b/engine/src/transposition_table.rs
index 9fc16d0..290ba68 100644
--- a/engine/src/transposition_table.rs
+++ b/engine/src/transposition_table.rs
@@ -1,4 +1,5 @@
use crate::{eval::Evaluation, CheckersBitBoard};
+use model::Move;
use parking_lot::RwLock;
use std::num::NonZeroU8;
@@ -6,12 +7,23 @@ use std::num::NonZeroU8;
struct TranspositionTableEntry {
board: CheckersBitBoard,
eval: Evaluation,
+ best_move: Move,
depth: NonZeroU8,
}
impl TranspositionTableEntry {
- const fn new(board: CheckersBitBoard, eval: Evaluation, depth: NonZeroU8) -> Self {
- Self { board, eval, depth }
+ const fn new(
+ board: CheckersBitBoard,
+ eval: Evaluation,
+ best_move: Move,
+ depth: NonZeroU8,
+ ) -> Self {
+ Self {
+ board,
+ eval,
+ best_move,
+ depth,
+ }
}
}
@@ -27,7 +39,7 @@ pub struct TranspositionTableRef<'a> {
}
impl<'a> TranspositionTableRef<'a> {
- pub fn get(self, board: CheckersBitBoard, depth: u8) -> Option<Evaluation> {
+ pub fn get(self, board: CheckersBitBoard, depth: u8) -> Option<(Evaluation, Move)> {
let table_len = self.replace_table.as_ref().len();
// try the replace table
@@ -39,7 +51,7 @@ impl<'a> TranspositionTableRef<'a> {
};
if let Some(entry) = *entry {
if entry.board == board && entry.depth.get() >= depth {
- return Some(entry.eval);
+ return Some((entry.eval, entry.best_move));
}
}
@@ -54,7 +66,7 @@ impl<'a> TranspositionTableRef<'a> {
Some(entry) => {
if entry.board == board {
if entry.depth.get() >= depth {
- Some(entry.eval)
+ Some((entry.eval, entry.best_move))
} else {
None
}
@@ -101,7 +113,13 @@ impl<'a> TranspositionTableRef<'a> {
}
}
- pub fn insert(&self, board: CheckersBitBoard, eval: Evaluation, depth: NonZeroU8) {
+ 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
@@ -110,7 +128,7 @@ impl<'a> TranspositionTableRef<'a> {
.get_unchecked(board.hash_code() as usize % table_len)
.write()
};
- *entry = Some(TranspositionTableEntry::new(board, eval, depth));
+ *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 {
@@ -121,10 +139,10 @@ impl<'a> TranspositionTableRef<'a> {
match *entry {
Some(entry_val) => {
if depth >= entry_val.depth {
- *entry = Some(TranspositionTableEntry::new(board, eval, depth));
+ *entry = Some(TranspositionTableEntry::new(board, eval, best_move, depth));
}
}
- None => *entry = Some(TranspositionTableEntry::new(board, eval, depth)),
+ None => *entry = Some(TranspositionTableEntry::new(board, eval, best_move, depth)),
}
}
}