|  | @@ -11,7 +11,7 @@ pub struct SearchControl<'a> {
 | 
	
		
			
				|  |  |      pub nodes: usize,
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      pub pv: Vec<Move>,
 | 
	
		
			
				|  |  | -    pub killer_moves: [Move; 3],
 | 
	
		
			
				|  |  | +    pub killer_moves: Vec<[Move; 2]>,
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /// function to check if the search should be exited
 | 
	
		
			
				|  |  |      pub check: &'a mut dyn FnMut() -> bool,
 | 
	
	
		
			
				|  | @@ -34,7 +34,7 @@ impl<'a> SearchControl<'a> {
 | 
	
		
			
				|  |  |          SearchControl {
 | 
	
		
			
				|  |  |              nodes: 0,
 | 
	
		
			
				|  |  |              pv: Vec::with_capacity(depth as usize),
 | 
	
		
			
				|  |  | -            killer_moves: [Move::Nullmove; 3],
 | 
	
		
			
				|  |  | +            killer_moves: vec![[Move::Nullmove; 2]; depth as usize],
 | 
	
		
			
				|  |  |              check,
 | 
	
		
			
				|  |  |              stopping: false,
 | 
	
		
			
				|  |  |              move_history,
 | 
	
	
		
			
				|  | @@ -42,15 +42,25 @@ impl<'a> SearchControl<'a> {
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    pub fn insert_killer(&mut self, killer: Move) {
 | 
	
		
			
				|  |  | -        for i in 1..self.killer_moves.len() {
 | 
	
		
			
				|  |  | -            self.killer_moves[i - 1] = self.killer_moves[i];
 | 
	
		
			
				|  |  | +    pub fn set_depth(&mut self, depth: i32) {
 | 
	
		
			
				|  |  | +        self.initial_depth = depth;
 | 
	
		
			
				|  |  | +        self.killer_moves = vec![[Move::Nullmove; 2]; depth as usize];
 | 
	
		
			
				|  |  | +        self.pv = vec![Move::Nullmove; depth as _];
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    pub fn insert_killer(&mut self, ply_depth: usize, killer: Move) {
 | 
	
		
			
				|  |  | +        if self.is_killer(ply_depth, &killer) {
 | 
	
		
			
				|  |  | +            return;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        let nkm = self.killer_moves[ply_depth].len();
 | 
	
		
			
				|  |  | +        for i in 1..nkm {
 | 
	
		
			
				|  |  | +            self.killer_moves[ply_depth][i - 1] = self.killer_moves[ply_depth][i];
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | -        self.killer_moves[self.killer_moves.len() - 1] = killer;
 | 
	
		
			
				|  |  | +        self.killer_moves[ply_depth][nkm - 1] = killer;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    pub fn is_killer(&self, killer: &Move) -> bool {
 | 
	
		
			
				|  |  | -        self.killer_moves.contains(killer)
 | 
	
		
			
				|  |  | +    pub fn is_killer(&self, ply_depth: usize, killer: &Move) -> bool {
 | 
	
		
			
				|  |  | +        self.killer_moves[ply_depth].contains(killer)
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -65,7 +75,8 @@ pub fn search(game: &mut Game, sc: &mut SearchControl, hash: &mut Cache, mut alp
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      let mut moves = generate_legal_moves(game, game.turn);
 | 
	
		
			
				|  |  |      let mut rng = rand::thread_rng();
 | 
	
		
			
				|  |  | -    sort_moves(game, hash, &sc.killer_moves, &mut moves);
 | 
	
		
			
				|  |  | +    let ply_depth = (sc.initial_depth - depth) as usize;
 | 
	
		
			
				|  |  | +    sort_moves(game, hash, &sc.killer_moves[ply_depth], &mut moves);
 | 
	
		
			
				|  |  |      
 | 
	
		
			
				|  |  |      info!("moves: {:?}", moves.iter().map(|mv| mv.to_string()).collect::<Vec<String>>());
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -203,8 +214,8 @@ pub fn negamax(game: &mut Game, sc: &mut SearchControl, hash: &mut Cache, mut al
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    sort_moves(game, hash, &sc.killer_moves, &mut moves);
 | 
	
		
			
				|  |  | +    let ply_depth = (sc.initial_depth - depth) as usize;
 | 
	
		
			
				|  |  | +    sort_moves(game, hash, &sc.killer_moves[ply_depth], &mut moves);
 | 
	
		
			
				|  |  |      //moves.sort_by_cached_key(|m| if sc.is_killer(*m) { -1 } else { 0 });
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      let mut alpha_is_exact = false;
 | 
	
	
		
			
				|  | @@ -231,7 +242,9 @@ pub fn negamax(game: &mut Game, sc: &mut SearchControl, hash: &mut Cache, mut al
 | 
	
		
			
				|  |  |              hash.cache(game, CacheEntry::new_upper(depth, val));
 | 
	
		
			
				|  |  |              //println!("but ret {}: {}", depth, beta);
 | 
	
		
			
				|  |  |              //info!("{} causes beta cutoff at {} ", mov.to_string(), val);
 | 
	
		
			
				|  |  | -            sc.insert_killer(mov);
 | 
	
		
			
				|  |  | +            if !mov.is_capture() {
 | 
	
		
			
				|  |  | +                sc.insert_killer(ply_depth, mov);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  |              return beta;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          if increase_mate_in(val) > alpha {
 |