Nicolas Winkler 3 years ago
parent
commit
5b4cc38def
6 changed files with 37 additions and 17 deletions
  1. 2 2
      src/engine.rs
  2. 14 4
      src/game.rs
  3. 1 1
      src/main.rs
  4. 1 0
      src/movegen.rs
  5. 17 8
      src/search.rs
  6. 2 2
      src/zobrist.rs

+ 2 - 2
src/engine.rs

@@ -105,7 +105,7 @@ impl Engine {
                     }
                     return false;
                 };
-                let mut sc = SearchControl{ nodes: 0, check: &mut check_fn };
+                let mut sc = SearchControl{ nodes: 0, check: &mut check_fn, zt: &self.zobrist_table };
                 let before = Instant::now();
                 let search_result = search(&self.game, &mut sc, &mut self.hash, *depth as i32);
 
@@ -139,7 +139,7 @@ impl Engine {
                     return false;
                 };
 
-                let mut sc = SearchControl{ nodes: 0, check: &mut check_fn };
+                let mut sc = SearchControl{ nodes: 0, check: &mut check_fn, zt: &self.zobrist_table };
                 let mut best_move = Move::default();
                 let mut best_val: PosValue = i32::max_value() as _;
                 loop {

+ 14 - 4
src/game.rs

@@ -422,12 +422,22 @@ impl Game {
         return board;
     }
 
+    pub fn update_zobrist(&mut self, h: zobrist::Hash) {
+        if let Some(mut zh) = self.zobrist {
+            zh ^= h;
+        }
+    }
+
     pub fn calculate_zobrist(&self, zt: &ZobristTable) -> zobrist::Hash {
         let mut hash: zobrist::Hash = 0;
-        for pt in 0..12 {
-            let bb_it = BitboardIterator(self.pieces[pt]);
-            for bb_square in bb_it {
-                hash ^= zt.piece_hash(pt as _, square(bb_square));
+        for pt in 0..6 {
+            let bb_it_w = BitboardIterator(self.get_piece(pt, WHITE));
+            let bb_it_b = BitboardIterator(self.get_piece(pt, BLACK));
+            for bb_square in bb_it_w {
+                hash ^= zt.piece_hash(pt as _, WHITE, square(bb_square));
+            }
+            for bb_square in bb_it_b {
+                hash ^= zt.piece_hash(pt as _, BLACK, square(bb_square));
             }
         }
 

+ 1 - 1
src/main.rs

@@ -28,7 +28,7 @@ fn main() {
         .init();
         */
     
-    let logfile = File::create("C:\\Users\\Nicolas\\debug.log").unwrap();
+    let logfile = File::create("/home/nicolas/debug.log").unwrap();
     simplelog::WriteLogger::init(LevelFilter::Info, Config::default(), logfile).unwrap();
 
     let (esend, erecv) = mpsc::channel();

+ 1 - 0
src/movegen.rs

@@ -2,6 +2,7 @@ use bitboard::Bitboard;
 use bitboard::Square;
 use bitboard::*;
 use game::Game;
+use zobrist::ZobristTable;
 use log::info;
 
 pub type Side = bool;

+ 17 - 8
src/search.rs

@@ -5,6 +5,7 @@ use evaluate::*;
 use log::info;
 use rand::prelude::*;
 use std::collections::HashMap;
+use zobrist::ZobristTable;
 use hash::*;
 
 enum MoveUndo {
@@ -26,6 +27,7 @@ enum MoveUndo {
 pub struct SearchControl<'a> {
     pub nodes: usize,
     pub check: &'a mut dyn FnMut() -> bool,
+    pub zt: &'a ZobristTable
 }
 
 pub enum SearchResult {
@@ -71,7 +73,7 @@ pub fn search(game: &Game, sc: &mut SearchControl, hash: &mut Cache, depth: i32)
     let mut valued_moves: Vec<(Move, PosValue)> = Vec::with_capacity(moves.len());
     let mut cancelled = false;
     for mov in moves {
-        let new_game = apply_move(game, mov);
+        let new_game = apply_move(game, sc.zt, mov);
 
         let hash_entry = hash.lookup(&new_game);
         if let Some(he) = hash_entry {
@@ -179,7 +181,7 @@ fn negamax(game: &Game, sc: &mut SearchControl, hash: &mut Cache, mut alpha: Pos
         }
     }
     for mov in moves {
-        let new_game = apply_move(game, mov);
+        let new_game = apply_move(game, sc.zt, mov);
         let (mut val, ret) = negamax(&new_game, sc, hash, -beta, -alpha, depth - 1);
         val = -val;
 
@@ -204,9 +206,9 @@ fn negamax(game: &Game, sc: &mut SearchControl, hash: &mut Cache, mut alpha: Pos
     return ((alpha as f64 * 0.99) as _, false);
 }
 
-fn quiescence_search(game: &Game, si: &mut SearchControl, mut alpha: PosValue, beta: PosValue, depth: i32) -> PosValue {
+fn quiescence_search(game: &Game, sc: &mut SearchControl, mut alpha: PosValue, beta: PosValue, depth: i32) -> PosValue {
     let val = evaluate(game);
-    si.nodes += 1;
+    sc.nodes += 1;
 
     if val >= beta {
         return beta;
@@ -223,8 +225,8 @@ fn quiescence_search(game: &Game, si: &mut SearchControl, mut alpha: PosValue, b
 
     let moves = generate_attacking_moves(game, game.turn);
     for mov in moves {
-        let new_game = apply_move(game, mov);
-        let val = -quiescence_search(&new_game, si, -beta, -alpha, depth - 1);
+        let new_game = apply_move(game, sc.zt, mov);
+        let val = -quiescence_search(&new_game, sc, -beta, -alpha, depth - 1);
         if val >= beta {
             return beta;
         }
@@ -245,7 +247,7 @@ pub fn undo(game: &mut Game, mov: Move) {
     
 }
 
-pub fn apply_move(game: &Game, mov: Move) -> Game {
+pub fn apply_move(game: &Game, zt: &ZobristTable, mov: Move) -> Game {
     let mut new_game = game.clone();
 
     let side = game.turn;
@@ -274,11 +276,18 @@ pub fn apply_move(game: &Game, mov: Move) -> Game {
                 new_game.castling_rights[3] = false;
             }
 
+            // if it is a capture
             if from_square(mov.to) | others != 0 {
+                let (other_piece, other_side) = game.get_square(mov.to);
+                let hup = zt.piece_hash(other_piece, other_side, mov.to);
+                new_game.update_zobrist(hup);
                 new_game.apply_mask(!from_square(mov.to));
             }
             let moved_piece = mov.apply_to(new_game.get_piece(pt, side));
             new_game.set_piece(pt, side, moved_piece);
+
+            let hup = zt.piece_hash(pt, side, mov.from) ^ zt.piece_hash(pt, side, mov.to);
+            new_game.update_zobrist(hup);
         },
         Move::Castling { side, left } => {
             // invalidate future castling rights
@@ -328,6 +337,6 @@ pub fn apply_move(game: &Game, mov: Move) -> Game {
     new_game.turn = !new_game.turn;
 
 
-
+    info!("applied {}, zobrist now {}", mov.to_string(), new_game.zobrist.unwrap_or(u64::MAX));
     return new_game;
 }

+ 2 - 2
src/zobrist.rs

@@ -48,8 +48,8 @@ impl ZobristTable {
         return zt;
     }
 
-    pub fn piece_hash(&self, piece_type: PieceType, sq: Square) -> Hash {
-        self.board[sq as usize][piece_type as usize]
+    pub fn piece_hash(&self, piece_type: PieceType, side: bool, sq: Square) -> Hash {
+        self.board[sq as usize][piece_type as usize + if side { 6 } else { 0 }]
     }
 
     pub fn en_passant_hash(&self, file: u8) -> Hash {