diff options
author | eug-vs <eugene@eug-vs.xyz> | 2024-01-22 01:30:47 +0100 |
---|---|---|
committer | eug-vs <eugene@eug-vs.xyz> | 2024-01-22 02:01:34 +0100 |
commit | 299c6d6dee96a50f9366955192f922d449d11f20 (patch) | |
tree | db03f75fc611fcc409af9981c25c8373ed6d7b95 /src/grossmeister | |
parent | f266b20fd559b624fc265905af4e7d971491915a (diff) | |
download | chessnost-299c6d6dee96a50f9366955192f922d449d11f20.tar.gz |
feat: store PV in a separate table
Diffstat (limited to 'src/grossmeister')
-rw-r--r-- | src/grossmeister/search.rs | 40 | ||||
-rw-r--r-- | src/grossmeister/ttable.rs | 24 |
2 files changed, 44 insertions, 20 deletions
diff --git a/src/grossmeister/search.rs b/src/grossmeister/search.rs index c81c586..372fecc 100644 --- a/src/grossmeister/search.rs +++ b/src/grossmeister/search.rs @@ -47,6 +47,12 @@ impl Grossmeister { return 0.0 } + // Mate distance pruning + let mating_score = Grossmeister::MDP(&mut alpha, &mut beta, root_distance); + if mating_score != 0.0 { + return mating_score + } + if let Some(transposition) = self.transposition() { if transposition.depth >= depth_left { match transposition.node_type { @@ -77,12 +83,6 @@ impl Grossmeister { node_type: NodeType::All, }; - // Mate distance pruning - let mating_score = Grossmeister::MDP(&mut alpha, &mut beta, root_distance); - if mating_score != 0.0 { - return mating_score - } - if depth_left == 0 { return self.quiscence(alpha, beta, root_distance) } @@ -167,6 +167,12 @@ impl Grossmeister { return 0.0 } + // Mate distance pruning + let mating_score = Grossmeister::MDP(&mut alpha, &mut beta, root_distance); + if mating_score != 0.0 { + return mating_score + } + if let Some(transposition) = self.transposition() { match transposition.node_type { NodeType::PV => { @@ -195,14 +201,6 @@ impl Grossmeister { node_type: NodeType::All, }; - // Mate distance pruning - let mating_score = Grossmeister::MDP(&mut alpha, &mut beta, root_distance); - if mating_score != 0.0 { - transposition.score = mating_score; - return mating_score - } - - let mut tactical_only = false; if !self.board.is_king_in_check(color) { // If we are not in check, we can evaluate stand pat @@ -263,17 +261,17 @@ impl Grossmeister { alpha } - fn reconstruct_pv(&mut self, depth: u8) -> Vec<Move> { + fn collect_pv(&mut self, depth: u8) -> Vec<Move> { let mut pv = Vec::with_capacity(depth as usize); if depth > 0 { - if let Some(transposition) = self.transposition().cloned() { + if let Some(transposition) = self.pv().cloned() { if let Some(mov) = transposition.mov { if transposition.depth < depth { - println!("info string found lower-depth {:?}-node ({}) than expected ({}). Probably bad", transposition.node_type, transposition.depth, depth); + println!("info string found lower-depth {:?} node ({}) than expected ({}). Probably bad", transposition.node_type, transposition.depth, depth); } if transposition.depth > depth { - println!("info string found higher-depth {:?}-node ({}) than expected ({}). Good for us?", transposition.node_type, transposition.depth, depth); + println!("info string found higher-depth {:?} node ({}) than expected ({}). Good for us?", transposition.node_type, transposition.depth, depth); } let ep_target_before = self.board.ep_target; let castling_rights_before = self.board.castling_rights; @@ -281,12 +279,14 @@ impl Grossmeister { let captured = self.board.make_move(mov); pv.push(mov); - let mut subtree_pv = self.reconstruct_pv(transposition.depth - 1); + let mut subtree_pv = self.collect_pv(depth - 1); pv.append(&mut subtree_pv); self.board.unmake_move(mov, captured, ep_target_before, castling_rights_before, hash_before); } + } else { + println!("No PV node found for hash {}", self.board.hash); } } @@ -336,7 +336,7 @@ impl Grossmeister { } best_score = score; - pv = self.reconstruct_pv(depth); + pv = self.collect_pv(depth); // Print UCI info print!("info depth {} score ", depth); diff --git a/src/grossmeister/ttable.rs b/src/grossmeister/ttable.rs index b1eeec3..b40bac1 100644 --- a/src/grossmeister/ttable.rs +++ b/src/grossmeister/ttable.rs @@ -62,8 +62,12 @@ impl TranspositionTable { #[derive(Debug, Default, Clone)] pub struct MasterTable { + /// Always contains the most recent transposition always_replace: TranspositionTable, + /// Stores highest-depth entries depth_preferred: TranspositionTable, + /// Used to collect Principal Variation. Not used in search + pv: TranspositionTable, } impl Grossmeister { @@ -81,6 +85,26 @@ impl Grossmeister { } { self.transposition_table.depth_preferred.set(self.board.hash, transposition) } + + // Store PV/Cut nodes in PV table + // Note: Cut nodes are probably only relevant in close-to-mate situations + if match transposition.node_type { + NodeType::PV => true, // Always replace PV nodes + NodeType::Cut => { + match self.transposition_table.pv.get(self.board.hash) { + Some(existing_transposition) => existing_transposition.node_type != NodeType::PV, + None => true, + } + } + _ => false, + } { + self.transposition_table.pv.set(self.board.hash, transposition) + } + } + + /// Extract current node information from PV table + pub fn pv(&self) -> Option<&TranspositionTableItem> { + self.transposition_table.pv.get(self.board.hash) } pub fn table_full(&self) -> u64 { |