|  | @@ -4,7 +4,6 @@ use game::Game;
 | 
											
												
													
														|  |  use evaluate::*;
 |  |  use evaluate::*;
 | 
											
												
													
														|  |  use log::info;
 |  |  use log::info;
 | 
											
												
													
														|  |  use rand::prelude::*;
 |  |  use rand::prelude::*;
 | 
											
												
													
														|  | -use zobrist;
 |  | 
 | 
											
												
													
														|  |  use hash::*;
 |  |  use hash::*;
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  
 |  |  
 | 
											
										
											
												
													
														|  | @@ -381,3 +380,59 @@ pub fn apply_move(game: &Game, mov: Move) -> Game {
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |      return new_game;
 |  |      return new_game;
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +pub fn perft(game: &mut Game, sc: &mut SearchControl, depth: i32) -> bool {
 | 
											
												
													
														|  | 
 |  | +    let moves = generate_legal_moves(game, game.turn);
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    if depth <= 1 {
 | 
											
												
													
														|  | 
 |  | +        sc.nodes += moves.len();
 | 
											
												
													
														|  | 
 |  | +        if sc.nodes % 1024 < moves.len() {
 | 
											
												
													
														|  | 
 |  | +            if (sc.check)() {
 | 
											
												
													
														|  | 
 |  | +                return true;
 | 
											
												
													
														|  | 
 |  | +            }
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +        return false;
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    
 | 
											
												
													
														|  | 
 |  | +    for mov in moves {
 | 
											
												
													
														|  | 
 |  | +        let undo = game.apply(mov);
 | 
											
												
													
														|  | 
 |  | +        let do_return = perft(game, sc, depth - 1);
 | 
											
												
													
														|  | 
 |  | +        if do_return {
 | 
											
												
													
														|  | 
 |  | +            game.undo_move(undo);
 | 
											
												
													
														|  | 
 |  | +            return true;
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +        game.undo_move(undo);
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    return false;
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +#[cfg(test)]
 | 
											
												
													
														|  | 
 |  | +mod tests {
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    use super::*;
 | 
											
												
													
														|  | 
 |  | +    #[test]
 | 
											
												
													
														|  | 
 |  | +    fn test_move_generation() {
 | 
											
												
													
														|  | 
 |  | +        let positions = [
 | 
											
												
													
														|  | 
 |  | +            "rnbq1k1r/pp1Pbppp/2p5/8/2B5/8/PPP1NnPP/RNBQK2R w KQ - 1 8",
 | 
											
												
													
														|  | 
 |  | +            "r4rk1/1pp1qppp/p1np1n2/2b1p1B1/2B1P1b1/P1NP1N2/1PP1QPPP/R4RK1 w - - 0 10"
 | 
											
												
													
														|  | 
 |  | +        ];
 | 
											
												
													
														|  | 
 |  | +        let perft_results: [Vec<usize>; 2] = [
 | 
											
												
													
														|  | 
 |  | +            vec![44, 1486, 62379, 2103487],
 | 
											
												
													
														|  | 
 |  | +            vec![46, 2079, 89890, 3894594]
 | 
											
												
													
														|  | 
 |  | +        ];
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +        for (i, &position) in positions.iter().enumerate() {
 | 
											
												
													
														|  | 
 |  | +            let mut game = Game::from_fen_str(position).unwrap();
 | 
											
												
													
														|  | 
 |  | +            for (j, &p_res) in perft_results[i].iter().enumerate() {
 | 
											
												
													
														|  | 
 |  | +                let depth = j + 1;
 | 
											
												
													
														|  | 
 |  | +                let mut sc = SearchControl{ nodes: 0, check: &mut (|| false), move_history: &mut RepetitionTable::new(), initial_depth: depth as _ };
 | 
											
												
													
														|  | 
 |  | +                perft(&mut game, &mut sc, depth as _);
 | 
											
												
													
														|  | 
 |  | +                assert_eq!(sc.nodes, p_res);
 | 
											
												
													
														|  | 
 |  | +            }
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +}
 |