Nicolas Winkler 3 年之前
父節點
當前提交
5e06421d64
共有 5 個文件被更改,包括 39 次插入19 次删除
  1. 11 2
      src/bitboard.rs
  2. 3 6
      src/engine.rs
  3. 4 4
      src/game.rs
  4. 13 0
      src/hash.rs
  5. 8 7
      src/search.rs

+ 11 - 2
src/bitboard.rs

@@ -85,16 +85,25 @@ pub fn square(b: Bitboard) -> Square {
     b.trailing_zeros() as Square
 }
 
+///
+/// \brief calculates the square index of a square
+/// 
+/// \param file the file of the square with 0 being the a file and 7 being the h file
+/// \param row the row of the square with 0 being row 1 and 7 being row 8
+/// 
 pub fn square_from_indices(file: u8, row: u8) -> Square {
-    (7 - row) * 8 + 7 - file
+    (row) * 8 + 7 - file
 }
 
 pub fn from_indices(file: u8, row: u8) -> Bitboard {
     1_u64 << square_from_indices(file, row)
 }
 
+///
+/// reverse of indices_from_square
+/// 
 pub fn indices_from_square(sq: Square) -> (u8, u8) {
-    (7 - sq % 8, 7 - sq / 8)
+    (7 - sq % 8, sq / 8)
 }
 
 pub fn print_board(b: Bitboard) -> String {

+ 3 - 6
src/engine.rs

@@ -8,6 +8,7 @@ use log::{info};
 use std::time::{Duration, Instant};
 use std::collections::{VecDeque, HashMap};
 use zobrist::ZobristTable;
+use hash::Cache;
 
 use std::thread::sleep_ms;
 use std::sync::mpsc::{Receiver, Sender};
@@ -40,16 +41,12 @@ pub enum SearchInfo {
 pub enum InterfaceMsg {
 }
 
-pub struct HashEntry {
-
-}
-
 pub struct Engine {
     game: Game,
     messages: VecDeque<EngineMsg>,
     r: Receiver<EngineMsg>,
     s: Sender<InterfaceMsg>,
-    hash: HashMap<Game, HashEntry>,
+    hash: Cache,
     zobrist_table: ZobristTable
 }
 
@@ -59,7 +56,7 @@ impl Engine {
             game: Game::default(),
             messages: VecDeque::new(),
             r, s,
-            hash: HashMap::new(),
+            hash: Cache::new(),
             zobrist_table: ZobristTable::new()
         };
         eng.game.zobrist = Some(eng.game.calculate_zobrist(&eng.zobrist_table));

+ 4 - 4
src/game.rs

@@ -77,9 +77,9 @@ impl Game {
 
         {
             let rows = position.split('/');
-            let mut row_index = 0;
+            let mut row_index: i32 = 7;
             for row in rows {
-                if row_index >= 8 {
+                if row_index < 0 {
                     return None;
                 }
                 let mut col_index = 0;
@@ -89,7 +89,7 @@ impl Game {
                         return None;
                     }
 
-                    let bit_to_set = from_indices(col_index, row_index);
+                    let bit_to_set = from_indices(col_index, row_index as _);
                     match c {
                         'p' => { *game.pawns_mut(BLACK) |= bit_to_set },
                         'n' => { *game.knights_mut(BLACK) |= bit_to_set },
@@ -112,7 +112,7 @@ impl Game {
                     }
                     col_index += 1;
                 }
-                row_index += 1;
+                row_index -= 1;
             }
         }
 

+ 13 - 0
src/hash.rs

@@ -18,6 +18,16 @@ pub struct CacheEntry {
     value: PosValue
 }
 
+impl CacheEntry {
+    pub fn new_value(depth: i32, value: PosValue) -> Self {
+        CacheEntry {
+            entry_type: EntryType::Value,
+            depth,
+            value
+        }
+    }
+}
+
 pub struct Cache {
     hashmap: HashMap<Game, CacheEntry>,
 }
@@ -39,5 +49,8 @@ impl Cache {
             self.hashmap.remove(&first_key);
         }
         self.hashmap.insert(game_pos.clone(), ce);
+        if self.hashmap.len() % 1024 == 0 {
+            info!("hash contains {} items", self.hashmap.len());
+        }
     }
 }

+ 8 - 7
src/search.rs

@@ -5,7 +5,7 @@ use evaluate::*;
 use log::info;
 use rand::prelude::*;
 use std::collections::HashMap;
-use engine::HashEntry;
+use hash::{CacheEntry, Cache};
 
 enum MoveUndo {
     Default {
@@ -39,7 +39,7 @@ pub enum SearchResult {
 /**
  * searches for moves and returns the best move found plus its value
  */
-pub fn search(game: &Game, sc: &mut SearchControl, hash: &mut HashMap<Game, HashEntry>, depth: i32) -> SearchResult {
+pub fn search(game: &Game, sc: &mut SearchControl, hash: &mut Cache, depth: i32) -> SearchResult {
 
     if depth == 0 {
         return SearchResult::Invalid;
@@ -73,7 +73,7 @@ pub fn search(game: &Game, sc: &mut SearchControl, hash: &mut HashMap<Game, Hash
     for mov in moves {
         let new_game = apply_move(game, mov);
         //info!("searching {}", mov.to_string());
-        let (mut val, ret) = negamax(&new_game, sc, -beta, -alpha, depth - 1);
+        let (mut val, ret) = negamax(&new_game, sc, hash, -beta, -alpha, depth - 1);
         val = -val;
 
         if ret {
@@ -114,6 +114,7 @@ pub fn search(game: &Game, sc: &mut SearchControl, hash: &mut HashMap<Game, Hash
             return SearchResult::Cancelled(Some((chosen_mov.0, chosen_mov.1)));
         }
         else {
+            hash.cache(game, CacheEntry::new_value(depth, chosen_mov.1));
             return SearchResult::Finished(chosen_mov.0, chosen_mov.1);
         }
     }
@@ -122,7 +123,7 @@ pub fn search(game: &Game, sc: &mut SearchControl, hash: &mut HashMap<Game, Hash
     }
 }
 
-fn negamax(game: &Game, sc: &mut SearchControl, mut alpha: PosValue, beta: PosValue, depth: i32) -> (PosValue, bool) {
+fn negamax(game: &Game, sc: &mut SearchControl, hash: &mut Cache, mut alpha: PosValue, beta: PosValue, depth: i32) -> (PosValue, bool) {
     if depth == 0 {
         return (quiescence_search(game, sc, alpha, beta, 7), false);
         let eval = evaluate(game);
@@ -159,7 +160,7 @@ fn negamax(game: &Game, sc: &mut SearchControl, mut alpha: PosValue, beta: PosVa
     }
     for mov in moves {
         let new_game = apply_move(game, mov);
-        let (mut val, ret) = negamax(&new_game, sc, -beta, -alpha, depth - 1);
+        let (mut val, ret) = negamax(&new_game, sc, hash, -beta, -alpha, depth - 1);
         val = -val;
 
         if ret {
@@ -170,7 +171,7 @@ fn negamax(game: &Game, sc: &mut SearchControl, mut alpha: PosValue, beta: PosVa
             return (beta, false);
         }
         if val > alpha {
-            alpha = (val as f64 * 0.95) as _;
+            alpha = val;//(val as f64 * 0.95) as _;
         }
         //info!(" -> negamaxed {} -> {}", mov.to_string(), depth - 1);
         if val > best {
@@ -180,7 +181,7 @@ fn negamax(game: &Game, sc: &mut SearchControl, mut alpha: PosValue, beta: PosVa
         }
     }
     //info!("best alpha {}", best);
-    return ((best as f64 * 0.99) as _, false);
+    return ((alpha as f64 * 0.99) as _, false);
 }
 
 fn quiescence_search(game: &Game, si: &mut SearchControl, mut alpha: PosValue, beta: PosValue, depth: i32) -> PosValue {