|  | @@ -14,6 +14,7 @@ pub struct SearchControl<'a> {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /// function to check if the search should be exited
 | 
	
		
			
				|  |  |      pub check: &'a mut dyn FnMut() -> bool,
 | 
	
		
			
				|  |  | +    pub stopping: bool,
 | 
	
		
			
				|  |  |      pub move_history: &'a mut RepetitionTable,
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /// depth the search was started at
 | 
	
	
		
			
				|  | @@ -33,6 +34,7 @@ impl<'a> SearchControl<'a> {
 | 
	
		
			
				|  |  |              nodes: 0,
 | 
	
		
			
				|  |  |              pv: Vec::with_capacity(depth as usize),
 | 
	
		
			
				|  |  |              check,
 | 
	
		
			
				|  |  | +            stopping: false,
 | 
	
		
			
				|  |  |              move_history,
 | 
	
		
			
				|  |  |              initial_depth: depth
 | 
	
		
			
				|  |  |          }
 | 
	
	
		
			
				|  | @@ -69,13 +71,12 @@ pub fn search(game: &mut Game, sc: &mut SearchControl, hash: &mut Cache, mut alp
 | 
	
		
			
				|  |  |          //assert_eq!(new_game, *game, );
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          //info!("searching {}", mov.to_string());
 | 
	
		
			
				|  |  | -        let (mut val, ret) = negamax(game, sc, hash, decrease_mate_in(-beta), decrease_mate_in(-alpha), depth - 1);
 | 
	
		
			
				|  |  | +        let mut val = -negamax(game, sc, hash, decrease_mate_in(-beta), decrease_mate_in(-alpha), depth - 1);
 | 
	
		
			
				|  |  |          game.undo_move(undo);
 | 
	
		
			
				|  |  | -        val = -val;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          val = increase_mate_in(val);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        if ret {
 | 
	
		
			
				|  |  | +        if sc.stopping {
 | 
	
		
			
				|  |  |              //return (Move::default(), 0);
 | 
	
		
			
				|  |  |              cancelled = true;
 | 
	
		
			
				|  |  |              break;
 | 
	
	
		
			
				|  | @@ -124,22 +125,22 @@ pub fn search(game: &mut Game, sc: &mut SearchControl, hash: &mut Cache, mut alp
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -fn negamax(game: &mut Game, sc: &mut SearchControl, hash: &mut Cache, mut alpha: PosValue, beta: PosValue, depth: i32) -> (PosValue, bool) {
 | 
	
		
			
				|  |  | +fn negamax(game: &mut Game, sc: &mut SearchControl, hash: &mut Cache, mut alpha: PosValue, beta: PosValue, depth: i32) -> PosValue {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      if let Some(e) = hash.lookup(game) {
 | 
	
		
			
				|  |  |          if e.depth >= depth {
 | 
	
		
			
				|  |  |              //println!("TABLE HIT!");
 | 
	
		
			
				|  |  |              match e.entry_type {
 | 
	
		
			
				|  |  | -                EntryType::Value => { return (e.value, false); },
 | 
	
		
			
				|  |  | +                EntryType::Value => { /*return e.value;*/ },
 | 
	
		
			
				|  |  |                  //EntryType::Value => { if e.value >= alpha { return (e.value, false); } else { return (alpha, false); } },
 | 
	
		
			
				|  |  |                  //EntryType::LowerBound => { if e.value > alpha { return (e.value, false) } },
 | 
	
		
			
				|  |  |                  EntryType::LowerBound => {
 | 
	
		
			
				|  |  | -                    if e.value < alpha { return (alpha, false); }
 | 
	
		
			
				|  |  | +                    if e.value < alpha { return alpha; }
 | 
	
		
			
				|  |  |                      //if e.value >= beta { return (beta, false); }
 | 
	
		
			
				|  |  |                  },
 | 
	
		
			
				|  |  |                  //EntryType::UpperBound => { if e.value >= beta { return (beta, false); } },
 | 
	
		
			
				|  |  |                  EntryType::UpperBound => {
 | 
	
		
			
				|  |  | -                    if e.value >= beta { return (beta, false); }
 | 
	
		
			
				|  |  | +                    if e.value >= beta { return beta; }
 | 
	
		
			
				|  |  |                  },
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          }
 | 
	
	
		
			
				|  | @@ -152,7 +153,8 @@ fn negamax(game: &mut Game, sc: &mut SearchControl, hash: &mut Cache, mut alpha:
 | 
	
		
			
				|  |  |      sc.nodes += 1;
 | 
	
		
			
				|  |  |      if sc.nodes % 1024 == 0 {
 | 
	
		
			
				|  |  |          if (sc.check)() {
 | 
	
		
			
				|  |  | -            return (0 as _, true);
 | 
	
		
			
				|  |  | +            sc.stopping = true;
 | 
	
		
			
				|  |  | +            return 0;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -164,31 +166,32 @@ fn negamax(game: &mut Game, sc: &mut SearchControl, hash: &mut Cache, mut alpha:
 | 
	
		
			
				|  |  |      if moves.len() == 0 {
 | 
	
		
			
				|  |  |          if check {
 | 
	
		
			
				|  |  |              // mate
 | 
	
		
			
				|  |  | -            return (-mate(), false);
 | 
	
		
			
				|  |  | +            return -mate();
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          else {
 | 
	
		
			
				|  |  |              // stalemate
 | 
	
		
			
				|  |  | -            return (0 as _, false);
 | 
	
		
			
				|  |  | +            return 0;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      // Nullmove
 | 
	
		
			
				|  |  | -    /*if !check && depth >= 4 && game_lateness(game) < 80 {
 | 
	
		
			
				|  |  | +    if !check && depth >= 4 && game_lateness(game) < 80 {
 | 
	
		
			
				|  |  |          let nmov = Move::Nullmove;
 | 
	
		
			
				|  |  |          let undo = game.apply(nmov);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        let (mut val, ret) = negamax(game, sc, hash, -beta, -alpha, depth / 2 - 1);
 | 
	
		
			
				|  |  | +        let val = -negamax(game, sc, hash, -beta, -alpha, depth / 2 - 1);
 | 
	
		
			
				|  |  |          game.undo_move(undo);
 | 
	
		
			
				|  |  | -        val = -val;
 | 
	
		
			
				|  |  | -        
 | 
	
		
			
				|  |  | -        if ret {
 | 
	
		
			
				|  |  | -            return (alpha, ret);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        if sc.stopping {
 | 
	
		
			
				|  |  | +            return alpha;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        if val >= beta {
 | 
	
		
			
				|  |  | -            return (beta, false);
 | 
	
		
			
				|  |  | +        if is_mate_in_p1(val).is_none() {
 | 
	
		
			
				|  |  | +            if val >= beta {
 | 
	
		
			
				|  |  | +                return beta;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | -    }*/
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      sort_moves(game, hash, &mut moves);
 | 
	
	
		
			
				|  | @@ -199,26 +202,23 @@ fn negamax(game: &mut Game, sc: &mut SearchControl, hash: &mut Cache, mut alpha:
 | 
	
		
			
				|  |  |      for mov in moves {
 | 
	
		
			
				|  |  |          let undo = game.apply(mov);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        let (mut val, ret) = negamax(game, sc, hash, decrease_mate_in(-beta), decrease_mate_in(-alpha), depth - 1);
 | 
	
		
			
				|  |  | +        let mut val = -negamax(game, sc, hash, -beta, -alpha, depth - 1);
 | 
	
		
			
				|  |  |          game.undo_move(undo);
 | 
	
		
			
				|  |  | -        val = -val;
 | 
	
		
			
				|  |  | -        val = increase_mate_in(val);
 | 
	
		
			
				|  |  | +        //val = increase_mate_in(val);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        if ret {
 | 
	
		
			
				|  |  | -            return (alpha, ret)
 | 
	
		
			
				|  |  | +        // return if the search has been cancelled
 | 
	
		
			
				|  |  | +        if sc.stopping {
 | 
	
		
			
				|  |  | +            return alpha;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          if val >= beta {
 | 
	
		
			
				|  |  |              //hash.cache(game, CacheEntry::new_upper(depth, val));
 | 
	
		
			
				|  |  |              //println!("but ret {}: {}", depth, beta);
 | 
	
		
			
				|  |  |              //info!("{} causes beta cutoff at {} ", mov.to_string(), val);
 | 
	
		
			
				|  |  | -            return (beta, false);
 | 
	
		
			
				|  |  | +            return beta;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | -        if val > alpha {
 | 
	
		
			
				|  |  | -            alpha = val;//(val as f64 * 0.95) as _;
 | 
	
		
			
				|  |  | -            if let Some(p) = is_mate_in_p1(val) {
 | 
	
		
			
				|  |  | -                //info!("{} is mate in {} plies: {}", mov.to_string(), p, val);
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | +        if increase_mate_in(val) > alpha {
 | 
	
		
			
				|  |  | +            alpha = increase_mate_in(val);
 | 
	
		
			
				|  |  |              alpha_is_exact = true;
 | 
	
		
			
				|  |  |              best_move = mov;
 | 
	
		
			
				|  |  |          }
 | 
	
	
		
			
				|  | @@ -234,31 +234,32 @@ fn negamax(game: &mut Game, sc: &mut SearchControl, hash: &mut Cache, mut alpha:
 | 
	
		
			
				|  |  |          hash.cache(game, CacheEntry::new_lower(depth, alpha));
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      //info!("best alpha {}", alpha);
 | 
	
		
			
				|  |  | -    return (alpha, false);
 | 
	
		
			
				|  |  | +    return alpha;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -fn quiescence_search(game: &mut Game, sc: &mut SearchControl, hash: &mut Cache, mut alpha: PosValue, beta: PosValue, depth: i32) -> (PosValue, bool) {
 | 
	
		
			
				|  |  | +fn quiescence_search(game: &mut Game, sc: &mut SearchControl, hash: &mut Cache, mut alpha: PosValue, beta: PosValue, depth: i32) -> PosValue {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      sc.nodes += 1;
 | 
	
		
			
				|  |  |      if sc.nodes % 1024 == 0 {
 | 
	
		
			
				|  |  |          if (sc.check)() {
 | 
	
		
			
				|  |  | -            return (0 as _, true);
 | 
	
		
			
				|  |  | +            sc.stopping = true;
 | 
	
		
			
				|  |  | +            return 0;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      let val = evaluate(game);
 | 
	
		
			
				|  |  |      if val >= beta {
 | 
	
		
			
				|  |  | -        return (beta, false);
 | 
	
		
			
				|  |  | +        return beta;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      if val > alpha {
 | 
	
		
			
				|  |  |          alpha = val;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      if depth <= 0 {
 | 
	
		
			
				|  |  | -        return (alpha, false);
 | 
	
		
			
				|  |  | +        return alpha;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    if game.get_piece(KING, game.turn) == 0 { return (-mate(), false); }
 | 
	
		
			
				|  |  | +    if game.get_piece(KING, game.turn) == 0 { return -mate(); }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      let mut moves = generate_attacking_moves(game, game.turn);
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -266,23 +267,21 @@ fn quiescence_search(game: &mut Game, sc: &mut SearchControl, hash: &mut Cache,
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      for mov in moves {
 | 
	
		
			
				|  |  |          let undo = game.apply(mov);
 | 
	
		
			
				|  |  | -        let (mut val, ret) = quiescence_search(game, sc, hash, decrease_mate_in(-beta), decrease_mate_in(-alpha), depth - 1);
 | 
	
		
			
				|  |  | +        let mut val = -quiescence_search(game, sc, hash, decrease_mate_in(-beta), decrease_mate_in(-alpha), depth - 1);
 | 
	
		
			
				|  |  |          game.undo_move(undo);
 | 
	
		
			
				|  |  | -        val = -val;
 | 
	
		
			
				|  |  | -        val = increase_mate_in(val);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        if ret {
 | 
	
		
			
				|  |  | -            return (alpha, ret)
 | 
	
		
			
				|  |  | +        if sc.stopping {
 | 
	
		
			
				|  |  | +            return alpha
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          if val >= beta {
 | 
	
		
			
				|  |  | -            return (beta, false);
 | 
	
		
			
				|  |  | +            return beta;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | -        if val > alpha {
 | 
	
		
			
				|  |  | -            alpha = val;
 | 
	
		
			
				|  |  | +        if increase_mate_in(val) > alpha {
 | 
	
		
			
				|  |  | +            alpha = increase_mate_in(val);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | -    return (alpha, false);
 | 
	
		
			
				|  |  | +    return alpha;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 |