Nicolas Winkler 3 years ago
parent
commit
3ec3557db4
2 changed files with 28 additions and 18 deletions
  1. 14 3
      src/engine.rs
  2. 14 15
      src/search.rs

+ 14 - 3
src/engine.rs

@@ -37,11 +37,13 @@ pub enum InterfaceMsg {
 
 pub fn run_engine(r: Receiver<EngineMsg>, s: Sender<InterfaceMsg>) {
     let mut game = Game::default();
-    for msg in r {
+    loop {
         //game.pieces[0] = 0x00ff_0000_0000_0100;
         //game.pieces[QUEEN as usize] = 0x0000_0000_0000_0080;
         //game.pieces[10] = 0x4000_0000_0000_0000;
 
+        let msg = r.recv().unwrap();
+
         match msg {
             EngineMsg::SetBoard(g) => {
                 //println!("SetBoard");
@@ -52,12 +54,21 @@ pub fn run_engine(r: Receiver<EngineMsg>, s: Sender<InterfaceMsg>) {
                 //info!("searching in pos\n {}", game.beautiful_print());
                 //println!("Search {}", depth);
 
+                let check_fn = || -> bool {
+                    if let Ok(msg) = r.try_recv() {
+                        return true;
+                    }
+                    return false;
+                };
+
+                let mut sc = SearchControl{ nodes: 0, check: &check_fn };
+
                 let before = Instant::now();
-                let (best_move, search_info) = search(&game, depth);
+                let best_move = search(&game, &mut sc, depth);
                 let time = before.elapsed();
                 println!("bestmove {}", best_move.to_string());
                 info!("bestmove {}", best_move.to_string());
-                info!("searched {} nodes in {} ms ({} nodes/s)", search_info.nodes, time.as_millis(), (search_info.nodes as f64 / time.as_millis() as f64 * 1000.0) as i64);
+                info!("searched {} nodes in {} ms ({} nodes/s)", sc.nodes, time.as_millis(), (sc.nodes as f64 / time.as_millis() as f64 * 1000.0) as i64);
             },
             EngineMsg::Ping => { println!("Ping") },
             EngineMsg::Stop => { println!("Stop") },

+ 14 - 15
src/search.rs

@@ -21,17 +21,16 @@ enum MoveUndo {
 }
 
 
-pub struct SearchInfo {
-    pub nodes: usize
+pub struct SearchControl<'a> {
+    pub nodes: usize,
+    pub check: &'a dyn Fn() -> bool,
 }
 
 
-pub fn search(game: &Game, depth: i32) -> (Move, SearchInfo) {
-
-    let mut si = SearchInfo { nodes: 0 };
+pub fn search(game: &Game, sc: &mut SearchControl, depth: i32) -> Move {
 
     if depth == 0 {
-        return (Move::default(), si);
+        return Move::default();
     }
 
     let mut moves = generate_legal_moves(game, game.turn);
@@ -60,7 +59,7 @@ pub fn search(game: &Game, depth: i32) -> (Move, SearchInfo) {
     let mut valued_moves = moves.iter().map(|mov| {
         let new_game = apply_move(game, *mov);
         //info!("searching {}", mov.to_string());
-        let val = -negamax(&new_game, &mut si, -beta, -alpha, depth - 1);
+        let val = -negamax(&new_game, sc, -beta, -alpha, depth - 1);
         info!("searched {} -> {}", mov.to_string(), val);
 
         if val > alpha {
@@ -81,16 +80,16 @@ pub fn search(game: &Game, depth: i32) -> (Move, SearchInfo) {
         let best_moves = valued_moves.iter().filter(|mv| mv.1 == min_val).map(|(mov, _)| *mov).collect::<Vec<Move>>();
 
         //info!("bestmove value {}", -min_val);
-        return (best_moves[(rng.next_u64() % best_moves.len() as u64) as usize], si);
+        return best_moves[(rng.next_u64() % best_moves.len() as u64) as usize];
     }
     else {
-        return (Move::Default{ mov: SimpleMove{ from: 0, to: 0 }, piece_type: PAWN }, si);
+        return Move::Default{ mov: SimpleMove{ from: 0, to: 0 }, piece_type: PAWN };
     }
 }
 
-fn negamax(game: &Game, si: &mut SearchInfo, mut alpha: i32, beta: i32, depth: i32) -> i32 {
+fn negamax(game: &Game, sc: &mut SearchControl, mut alpha: i32, beta: i32, depth: i32) -> i32 {
     if depth == 0 {
-        return quiescence_search(game, si, alpha, beta, 7);
+        return quiescence_search(game, sc, alpha, beta, 7);
         let eval = evaluate(game);
         if eval != 0 {
             //info!("eval: {}", eval);
@@ -100,7 +99,7 @@ fn negamax(game: &Game, si: &mut SearchInfo, mut alpha: i32, beta: i32, depth: i
 
     const MIN_VALUE: i32 = i32::min_value() + 1;
 
-    si.nodes += 1;
+    sc.nodes += 1;
 
     let mut best = MIN_VALUE;
     //let mut best_move = Move::default();
@@ -122,12 +121,12 @@ fn negamax(game: &Game, si: &mut SearchInfo, mut alpha: i32, beta: i32, depth: i
     }
     for mov in moves {
         let new_game = apply_move(game, mov);
-        let val = -negamax(&new_game, si, -beta, -alpha, depth - 1);
+        let val = -negamax(&new_game, sc, -beta, -alpha, depth - 1);
         if val >= beta {
             return beta;
         }
         if val > alpha {
-            alpha = val;
+            alpha = (val as f64 * 0.95) as i32;
         }
         //info!(" -> negamaxed {} -> {}", mov.to_string(), depth - 1);
         if val > best {
@@ -140,7 +139,7 @@ fn negamax(game: &Game, si: &mut SearchInfo, mut alpha: i32, beta: i32, depth: i
     return (best as f64 * 0.99) as i32;
 }
 
-fn quiescence_search(game: &Game, si: &mut SearchInfo, mut alpha: i32, beta: i32, depth: i32) -> i32 {
+fn quiescence_search(game: &Game, si: &mut SearchControl, mut alpha: i32, beta: i32, depth: i32) -> i32 {
     const MIN_VALUE: i32 = i32::min_value() + 1;
 
     let val = evaluate(game);