aboutsummaryrefslogtreecommitdiff
path: root/src/grossmeister/ttable.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/grossmeister/ttable.rs')
-rw-r--r--src/grossmeister/ttable.rs89
1 files changed, 38 insertions, 51 deletions
diff --git a/src/grossmeister/ttable.rs b/src/grossmeister/ttable.rs
index 0c6724f..2f673c9 100644
--- a/src/grossmeister/ttable.rs
+++ b/src/grossmeister/ttable.rs
@@ -1,7 +1,5 @@
-use std::cmp::Ordering;
-
+use std::collections::HashMap;
use crate::moves::Move;
-
use super::Grossmeister;
/// https://www.chessprogramming.org/Node_Types
@@ -15,21 +13,6 @@ pub enum NodeType {
All,
}
-impl NodeType {
- fn cmp_order(&self) -> u8 {
- match self {
- NodeType::PV => 2,
- NodeType::Cut => 1,
- NodeType::All => 0,
- }
- }
-}
-impl PartialOrd for NodeType {
- fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
- Some(self.cmp_order().cmp(&other.cmp_order()))
- }
-}
-
#[derive(Debug, PartialEq, Clone, Copy)]
pub struct TranspositionTableItem {
/// Zobrist hash of this position
@@ -40,52 +23,56 @@ pub struct TranspositionTableItem {
pub node_type: NodeType,
}
-impl PartialOrd for TranspositionTableItem {
- fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
- // Order by depth first, then node type
- let depth_ordering = self.depth.partial_cmp(&other.depth);
- if depth_ordering != Some(Ordering::Equal) {
- return depth_ordering
- }
+pub const TTABLE_SIZE: u64 = 2u64.pow(23);
- self.node_type.partial_cmp(&other.node_type)
- }
+#[derive(Debug, Clone)]
+pub struct TranspositionTable {
+ pub always_replace: HashMap<u64, TranspositionTableItem>,
+ pub depth_preferred: HashMap<u64, TranspositionTableItem>,
}
-
-pub const TTABLE_SIZE: u64 = 2u64.pow(24);
-pub type TranspositionTable = Vec<Option<TranspositionTableItem>>;
-
-impl Grossmeister {
- fn transposition_ref(&mut self) -> &mut Option<TranspositionTableItem> {
- &mut self.transposition_table[(self.board.hash % TTABLE_SIZE) as usize]
+impl Default for TranspositionTable {
+ fn default() -> Self {
+ TranspositionTable {
+ always_replace: HashMap::with_capacity(TTABLE_SIZE as usize),
+ depth_preferred: HashMap::with_capacity(TTABLE_SIZE as usize),
+ }
}
+}
+impl Grossmeister {
/// Find current position in Transposition Table
/// This operation is safe from collisions since it compares the *full* hash
- pub fn transposition(&mut self) -> Option<TranspositionTableItem> {
- let hash = self.board.hash;
- match self.transposition_ref() {
- Some(item) => {
- if item.hash == hash {
- return Some(*item)
- }
+ pub fn transposition(&self) -> Option<&TranspositionTableItem> {
+ self.transposition_table.depth_preferred.get(&self.board.hash).and_then(|item| {
+ if item.hash == self.board.hash {
+ Some(item)
+ } else {
None
}
- None => None
- }
+ }).or(self.transposition_table.always_replace.get(&self.board.hash).and_then(|item| {
+ if item.hash == self.board.hash {
+ Some(item)
+ } else {
+ None
+ }
+ }))
}
pub fn store_transposition(&mut self, transposition: TranspositionTableItem) {
- let transposition_ref = self.transposition_ref();
- match transposition_ref {
- Some(existing_transposition) => {
- if transposition >= *existing_transposition {
- *transposition_ref = Some(transposition)
- }
- }
- None => *transposition_ref = Some(transposition)
+ self.transposition_table.always_replace.insert(self.board.hash, transposition);
+ if match self.transposition_table.depth_preferred.get(&self.board.hash) {
+ Some(existing_transposition) => transposition.depth >= existing_transposition.depth,
+ None => true,
+ } {
+ self.transposition_table.depth_preferred.insert(self.board.hash, transposition);
}
}
+ pub fn table_full(&self) -> u64 {
+ let total_entries = self.transposition_table.always_replace.len() + self.transposition_table.depth_preferred.len();
+ let total_size = TTABLE_SIZE * 2;
+ (1000.0 * (total_entries as f64 / total_size as f64)) as u64
+ }
+
}