Skip to content

Commit

Permalink
Add tablebase probing in search
Browse files Browse the repository at this point in the history
  • Loading branch information
jgilchrist committed Nov 12, 2024
1 parent 5f30c48 commit 1d51735
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 9 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## [Unreleased]

* Add tablebase probing in search based on 'fathom' (18.97 +- 8.35 (5-man))
* Use arrayvec for PrincipalVariation (15.52 +- 8.72)
* Fix an accidental fail hard in quiescence - fail soft when eval >= beta (12.54 +- 7.15)
* Add futility pruning (10.82 +- 6.41)
Expand Down
1 change: 0 additions & 1 deletion src/engine/eval/player_eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ impl Eval {
Self(eval)
}

#[expect(unused, reason = "Unused")]
pub fn mate_in(ply: u8) -> Self {
Self(Self::MATE - i16::from(ply))
}
Expand Down
1 change: 1 addition & 0 deletions src/engine/search/iterative_deepening.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ pub fn search(
state.nodes_visited,
time_control.elapsed(),
),
tbhits: state.tbhits,
},
},
);
Expand Down
3 changes: 3 additions & 0 deletions src/engine/search/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ pub struct SearchState {

nodes_visited: u64,
max_depth_reached: u8,
tbhits: u64,
}

impl SearchState {
Expand All @@ -90,6 +91,7 @@ impl SearchState {

max_depth_reached: 0,
nodes_visited: 0,
tbhits: 0,
}
}
}
Expand Down Expand Up @@ -134,6 +136,7 @@ pub struct SearchStats {
pub time: Duration,
pub nodes: u64,
pub nodes_per_second: u64,
pub tbhits: u64,
}

pub trait Reporter {
Expand Down
45 changes: 45 additions & 0 deletions src/engine/search/negamax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::engine::search::quiescence::quiescence;
use crate::engine::search::tables::lmr_table::lmr_reduction;
use crate::engine::search::time_control::TimeStrategy;
use crate::engine::search::transposition::{NodeBound, SearchTranspositionTableData};
use crate::engine::tablebases::Wdl;

pub fn negamax(
game: &mut Game,
Expand Down Expand Up @@ -80,6 +81,50 @@ pub fn negamax(
previous_best_move = tt_entry.best_move;
}

let tb_cardinality = persistent_state.tablebase.n_men();
if !is_root && tb_cardinality > 0 {
let piece_count = game.board.occupancy().count();

if piece_count < tb_cardinality || (piece_count <= tb_cardinality && depth >= 1) {
if let Some(wdl) = persistent_state.tablebase.wdl(game) {
state.tbhits += 1;

let score = match wdl {
Wdl::Win => Eval::mate_in(plies),
Wdl::Draw => Eval::DRAW,
Wdl::Loss => Eval::mated_in(plies),
};

let tb_bound = match wdl {
Wdl::Win => NodeBound::Lower,
Wdl::Loss => NodeBound::Upper,
Wdl::Draw => NodeBound::Exact,
};

if tb_bound == NodeBound::Exact
|| (tb_bound == NodeBound::Lower && score >= beta)
|| (tb_bound == NodeBound::Upper && score <= alpha)
{
let tt_data = SearchTranspositionTableData {
bound: tb_bound,
eval: score,
best_move: None,
age: persistent_state.tt.generation,
depth,
};

persistent_state.tt.insert(&game.zobrist, tt_data);

return Ok(score);
}

if is_pv && tb_bound == NodeBound::Lower {
alpha = alpha.max(score);
}
}
}
}

let eval = eval::eval(game);

if !is_root && !is_pv && !in_check {
Expand Down
12 changes: 4 additions & 8 deletions src/engine/tablebases/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@ impl Tablebase {
}

#[expect(
unused,
reason = "Won't be used until proper tablebase support is implemented"
clippy::cast_possible_truncation,
reason = "n_men will be at most 7 as these are the largest syzygy tablebases"
)]
pub fn n_men(&self) -> usize {
pub fn n_men(&self) -> u8 {
if !self.is_enabled {
return 0;
}

unsafe { bindings::TB_LARGEST as usize }
unsafe { bindings::TB_LARGEST as u8 }
}

pub fn set_paths(&mut self, path: &str) {
Expand All @@ -58,10 +58,6 @@ impl Tablebase {
self.is_enabled = true;
}

#[expect(
unused,
reason = "Won't be used until proper tablebase support is implemented"
)]
pub fn wdl(&self, game: &Game) -> Option<Wdl> {
if !self.is_enabled {
return None;
Expand Down
1 change: 1 addition & 0 deletions src/engine/uci/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ impl UciReporter {
time: Some(progress.stats.time),
nodes: Some(progress.stats.nodes),
nps: Some(progress.stats.nodes_per_second),
tbhits: Some(progress.stats.tbhits),
hashfull: Some(progress.hashfull),
..Default::default()
}));
Expand Down

0 comments on commit 1d51735

Please sign in to comment.