hash.rs 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. use game::Game;
  2. use evaluate::PosValue;
  3. use std::collections::{HashMap};
  4. use log::info;
  5. use zobrist;
  6. #[derive(Clone)]
  7. pub enum EntryType {
  8. Value,
  9. LowerBound,
  10. UpperBound,
  11. }
  12. #[derive(Clone)]
  13. pub struct CacheEntry {
  14. pub entry_type: EntryType,
  15. pub depth: i32,
  16. pub value: PosValue,
  17. }
  18. impl CacheEntry {
  19. pub fn new_value(depth: i32, value: PosValue) -> Self {
  20. CacheEntry {
  21. entry_type: EntryType::Value,
  22. depth,
  23. value,
  24. }
  25. }
  26. pub fn new_upper(depth: i32, beta: PosValue) -> Self {
  27. CacheEntry {
  28. entry_type: EntryType::UpperBound,
  29. depth,
  30. value: beta,
  31. }
  32. }
  33. pub fn new_lower(depth: i32, alpha: PosValue) -> Self {
  34. CacheEntry {
  35. entry_type: EntryType::LowerBound,
  36. depth,
  37. value: alpha,
  38. }
  39. }
  40. }
  41. pub struct Cache {
  42. hashmap: HashMap<zobrist::Hash, CacheEntry>,
  43. max_capacity: usize
  44. }
  45. #[derive(Clone)]
  46. pub struct RepetitionTable {
  47. hashmap: HashMap<zobrist::Hash, i32>,
  48. }
  49. impl Cache {
  50. pub fn new() -> Self {
  51. Cache {
  52. hashmap: HashMap::new(),
  53. max_capacity: 40000000
  54. }
  55. }
  56. pub fn lookup(&self, game_pos: &Game) -> Option<CacheEntry> {
  57. self.hashmap.get(&game_pos.zobrist.as_ref().unwrap().1).map(|x| x.clone())
  58. }
  59. pub fn cache(&mut self, game_pos: &Game, ce: CacheEntry) {
  60. if let Some(c) = self.lookup(game_pos) {
  61. if c.depth > ce.depth {
  62. return;
  63. }
  64. }
  65. if self.hashmap.len() > self.max_capacity {
  66. //let first_key = self.hashmap.keys().next().unwrap().clone();
  67. //self.hashmap.remove(&first_key);
  68. self.hashmap.clear();
  69. }
  70. let key = game_pos.zobrist.as_ref().unwrap().1;
  71. self.hashmap.insert(key, ce);
  72. if self.hashmap.len() % (1024 * 32) == 0 {
  73. info!("hash contains {} items", self.hashmap.len());
  74. }
  75. }
  76. }
  77. impl RepetitionTable {
  78. pub fn new() -> Self {
  79. RepetitionTable {
  80. hashmap: HashMap::with_capacity(256)
  81. }
  82. }
  83. pub fn clear(&mut self) {
  84. self.hashmap.clear();
  85. }
  86. pub fn increment(&mut self, hash: zobrist::Hash) -> i32 {
  87. if let Some(entry) = self.hashmap.get_mut(&hash) {
  88. *entry += 1;
  89. *entry
  90. }
  91. else {
  92. self.hashmap.insert(hash, 1);
  93. 1
  94. }
  95. }
  96. pub fn decrement(&mut self, hash: zobrist::Hash) {
  97. if let Some(entry) = self.hashmap.get_mut(&hash) {
  98. *entry -= 1;
  99. if *entry == 0 {
  100. self.hashmap.remove(&hash);
  101. }
  102. }
  103. }
  104. }