|  | @@ -8,26 +8,10 @@ use std::collections::HashMap;
 | 
											
												
													
														|  |  use zobrist::ZobristTable;
 |  |  use zobrist::ZobristTable;
 | 
											
												
													
														|  |  use hash::*;
 |  |  use hash::*;
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -enum MoveUndo {
 |  | 
 | 
											
												
													
														|  | -    Default {
 |  | 
 | 
											
												
													
														|  | -        piece_type: PieceType,
 |  | 
 | 
											
												
													
														|  | -        before: Bitboard,
 |  | 
 | 
											
												
													
														|  | -        captured_type: PieceType,
 |  | 
 | 
											
												
													
														|  | -        captured_before: Bitboard,
 |  | 
 | 
											
												
													
														|  | -    },
 |  | 
 | 
											
												
													
														|  | -    Castling { rooks_before: Bitboard, king_before: Bitboard },
 |  | 
 | 
											
												
													
														|  | -    Promotion {
 |  | 
 | 
											
												
													
														|  | -        promoted_to: PieceType,
 |  | 
 | 
											
												
													
														|  | -        promoted_to_before: Bitboard,
 |  | 
 | 
											
												
													
														|  | -        pawns_before: Bitboard
 |  | 
 | 
											
												
													
														|  | -    }
 |  | 
 | 
											
												
													
														|  | -}
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  pub struct SearchControl<'a> {
 |  |  pub struct SearchControl<'a> {
 | 
											
												
													
														|  |      pub nodes: usize,
 |  |      pub nodes: usize,
 | 
											
												
													
														|  | -    pub check: &'a mut dyn FnMut() -> bool,
 |  | 
 | 
											
												
													
														|  | -    pub zt: &'a ZobristTable
 |  | 
 | 
											
												
													
														|  | 
 |  | +    pub check: &'a mut dyn FnMut() -> bool
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  pub enum SearchResult {
 |  |  pub enum SearchResult {
 | 
											
										
											
												
													
														|  | @@ -73,7 +57,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 valued_moves: Vec<(Move, PosValue)> = Vec::with_capacity(moves.len());
 | 
											
												
													
														|  |      let mut cancelled = false;
 |  |      let mut cancelled = false;
 | 
											
												
													
														|  |      for mov in moves {
 |  |      for mov in moves {
 | 
											
												
													
														|  | -        let new_game = apply_move(game, sc.zt, mov);
 |  | 
 | 
											
												
													
														|  | 
 |  | +        let new_game = apply_move(game, mov);
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |          let hash_entry = hash.lookup(&new_game);
 |  |          let hash_entry = hash.lookup(&new_game);
 | 
											
												
													
														|  |          if let Some(he) = hash_entry {
 |  |          if let Some(he) = hash_entry {
 | 
											
										
											
												
													
														|  | @@ -181,7 +165,7 @@ fn negamax(game: &Game, sc: &mut SearchControl, hash: &mut Cache, mut alpha: Pos
 | 
											
												
													
														|  |          }
 |  |          }
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |      for mov in moves {
 |  |      for mov in moves {
 | 
											
												
													
														|  | -        let new_game = apply_move(game, sc.zt, mov);
 |  | 
 | 
											
												
													
														|  | 
 |  | +        let new_game = apply_move(game, mov);
 | 
											
												
													
														|  |          let (mut val, ret) = negamax(&new_game, sc, hash, -beta, -alpha, depth - 1);
 |  |          let (mut val, ret) = negamax(&new_game, sc, hash, -beta, -alpha, depth - 1);
 | 
											
												
													
														|  |          val = -val;
 |  |          val = -val;
 | 
											
												
													
														|  |  
 |  |  
 | 
											
										
											
												
													
														|  | @@ -225,7 +209,7 @@ fn quiescence_search(game: &Game, sc: &mut SearchControl, mut alpha: PosValue, b
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      let moves = generate_attacking_moves(game, game.turn);
 |  |      let moves = generate_attacking_moves(game, game.turn);
 | 
											
												
													
														|  |      for mov in moves {
 |  |      for mov in moves {
 | 
											
												
													
														|  | -        let new_game = apply_move(game, sc.zt, mov);
 |  | 
 | 
											
												
													
														|  | 
 |  | +        let new_game = apply_move(game, mov);
 | 
											
												
													
														|  |          let val = -quiescence_search(&new_game, sc, -beta, -alpha, depth - 1);
 |  |          let val = -quiescence_search(&new_game, sc, -beta, -alpha, depth - 1);
 | 
											
												
													
														|  |          if val >= beta {
 |  |          if val >= beta {
 | 
											
												
													
														|  |              return beta;
 |  |              return beta;
 | 
											
										
											
												
													
														|  | @@ -247,7 +231,7 @@ pub fn undo(game: &mut Game, mov: Move) {
 | 
											
												
													
														|  |      
 |  |      
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -pub fn apply_move(game: &Game, zt: &ZobristTable, mov: Move) -> Game {
 |  | 
 | 
											
												
													
														|  | 
 |  | +pub fn apply_move(game: &Game, mov: Move) -> Game {
 | 
											
												
													
														|  |      let mut new_game = game.clone();
 |  |      let mut new_game = game.clone();
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      let side = game.turn;
 |  |      let side = game.turn;
 | 
											
										
											
												
													
														|  | @@ -277,17 +261,22 @@ pub fn apply_move(game: &Game, zt: &ZobristTable, mov: Move) -> Game {
 | 
											
												
													
														|  |              }
 |  |              }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |              // if it is a capture
 |  |              // if it is a capture
 | 
											
												
													
														|  | -            if from_square(mov.to) | others != 0 {
 |  | 
 | 
											
												
													
														|  | 
 |  | +            if from_square(mov.to) & others != 0 {
 | 
											
												
													
														|  |                  let (other_piece, other_side) = game.get_square(mov.to);
 |  |                  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);
 |  | 
 | 
											
												
													
														|  | 
 |  | +                if let Some((ref zt, ref _zv)) = game.zobrist {
 | 
											
												
													
														|  | 
 |  | +                    let hup = zt.piece_hash(other_piece, other_side, mov.to);
 | 
											
												
													
														|  | 
 |  | +                    new_game.update_zobrist(hup);
 | 
											
												
													
														|  | 
 |  | +                }
 | 
											
												
													
														|  |                  new_game.apply_mask(!from_square(mov.to));
 |  |                  new_game.apply_mask(!from_square(mov.to));
 | 
											
												
													
														|  |              }
 |  |              }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |              let moved_piece = mov.apply_to(new_game.get_piece(pt, side));
 |  |              let moved_piece = mov.apply_to(new_game.get_piece(pt, side));
 | 
											
												
													
														|  |              new_game.set_piece(pt, side, moved_piece);
 |  |              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);
 |  | 
 | 
											
												
													
														|  | 
 |  | +            if let Some((ref zt, ref _zv)) = game.zobrist {
 | 
											
												
													
														|  | 
 |  | +                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 } => {
 |  |          Move::Castling { side, left } => {
 | 
											
												
													
														|  |              // invalidate future castling rights
 |  |              // invalidate future castling rights
 | 
											
										
											
												
													
														|  | @@ -337,6 +326,8 @@ pub fn apply_move(game: &Game, zt: &ZobristTable, mov: Move) -> Game {
 | 
											
												
													
														|  |      new_game.turn = !new_game.turn;
 |  |      new_game.turn = !new_game.turn;
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -    info!("applied {}, zobrist now {}", mov.to_string(), new_game.zobrist.unwrap_or(u64::MAX));
 |  | 
 | 
											
												
													
														|  | 
 |  | +    if let Some((ref zt, ref zv)) = new_game.zobrist {
 | 
											
												
													
														|  | 
 |  | +        info!("applied {}, zobrist now {}", mov.to_string(), *zv);
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  |      return new_game;
 |  |      return new_game;
 | 
											
												
													
														|  |  }
 |  |  }
 |