Sfoglia il codice sorgente

small changes to search and movegen

Nicolas Winkler 2 anni fa
parent
commit
71174d9116
4 ha cambiato i file con 48 aggiunte e 36 eliminazioni
  1. 30 24
      src/engine.rs
  2. 4 0
      src/hash.rs
  3. 6 5
      src/movegen.rs
  4. 8 7
      src/search.rs

+ 30 - 24
src/engine.rs

@@ -155,13 +155,11 @@ impl Engine {
         }
     }
 
-    #[allow(dead_code)]
-    fn reconstruct_pv(&self) -> Vec<Move> {
+    fn reconstruct_pv(game: &Game, hash: &Cache) -> Vec<Move> {
         let mut pv: Vec<Move> = Vec::new();
-
-        let mut g = self.game.clone();
+        let mut g = game.clone();
         loop {
-            let mce = self.hash.lookup(&g);
+            let mce = hash.lookup(&g);
             if let Some(ce) = mce {
                 pv.push(ce.mov);
                 g.apply(ce.mov);
@@ -245,27 +243,39 @@ impl Engine {
 
         let mut alpha = crate::evaluate::MIN_VALUE;
         let mut beta = crate::evaluate::MAX_VALUE;
-        //let window_size = 100;
+        let window_size = 10;
+        let mut is_windowed = false;
+
         loop {
 
             sc.set_depth(depth);
 
             let search_result = search(&mut self.game, &mut sc, &mut self.hash, alpha, beta, depth as i32);
 
+            if let SearchResult::Invalid = search_result {
+                if is_windowed {
+                    alpha = crate::evaluate::MIN_VALUE;
+                    beta = crate::evaluate::MAX_VALUE;
+                    is_windowed = false;
+                    continue;
+                }
+            }
+
             if let SearchResult::Finished(bm, bv) = search_result {
                 info!("depth: {} bm: {}, bv: {}", depth, bm.to_string(), bv);
 
                 if bv >= beta || bv <= alpha {
                     alpha = crate::evaluate::MIN_VALUE;
                     beta = crate::evaluate::MAX_VALUE;
-                    //println!("repeat");
+                    is_windowed = false;
                     continue;
                 }
                 else {
-                    alpha = crate::evaluate::MIN_VALUE;
-                    beta = crate::evaluate::MAX_VALUE;
-                    //alpha = bv - window_size;
-                    //beta = bv + window_size;
+                    //alpha = crate::evaluate::MIN_VALUE;
+                    //beta = crate::evaluate::MAX_VALUE;
+                    is_windowed = true;
+                    alpha = bv - window_size;
+                    beta = bv + window_size;
                 }
 
                 best_move = bm;
@@ -275,25 +285,21 @@ impl Engine {
                 let nodes = sc.nodes;
                 let nps = (nodes as f64 / elapsed.as_nanos() as f64 * 1000000000.0) as i64;
                 let cp = best_val as i64;
+                let hashfull = self.hash.fullness_permill();
                 
-                //let pv_array = self.reconstruct_pv();
-                let pv = &sc.pv.iter().filter(|&m| !m.is_null()).map(|m| m.to_string()).fold(String::new(), |a, b| a + " " + &b)[0..];
+                let pv_array = Self::reconstruct_pv(&self.game, &self.hash);
+                let pv = &pv_array.iter().filter(|&m| !m.is_null()).map(|m| m.to_string()).fold(String::new(), |a, b| a + " " + &b)[0..];
 
                 if let Some(plies) = crate::evaluate::is_mate_in_p1(bv) {
                     let turns = plies / 2;
-                    println!("info depth {} score mate {} time {} nodes {} nps {} pv{}", depth, turns, elapsed.as_millis(), nodes, nps, pv);
-                    info!("info depth {} score mate {} time {} nodes {} nps {} pv{}", depth, turns, elapsed.as_millis(), nodes, nps, pv);
-                    
-                    /*if depth > 3 {
-                        break;
-                    }*/
-                    /*if plies.abs() * 3 < depth {
-                        break;
-                    }*/
+                    let infostring = format!("info depth {} score mate {} time {} nodes {} nps {} hashfull {} pv{}", depth, turns, elapsed.as_millis(), nodes, nps, hashfull, pv);
+                    println!("{}", infostring);
+                    info!("{}", infostring);
                 }
                 else {
-                    println!("info depth {} score cp {} time {} nodes {} nps {} pv{}", depth, cp, elapsed.as_millis(), nodes, nps, pv);
-                    info!("info depth {} score cp {} time {} nodes {} nps {} pv{}", depth, cp, elapsed.as_millis(), nodes, nps, pv);
+                    let infostring = format!("info depth {} score cp {} time {} nodes {} nps {} hashfull {} pv{}", depth, cp, elapsed.as_millis(), nodes, nps, hashfull, pv);
+                    println!("{}", infostring);
+                    info!("{}", infostring);
                 }
                 depth += 1;
             }

+ 4 - 0
src/hash.rs

@@ -89,6 +89,10 @@ impl Cache {
             info!("hash contains {} items", self.hashmap.len());
         }
     }
+
+    pub fn fullness_permill(&self) -> usize{
+        return (1000 * self.hashmap.len()) / self.max_capacity;
+    }
 }
 
 

+ 6 - 5
src/movegen.rs

@@ -204,7 +204,7 @@ pub fn generate_legal_moves(game: &mut Game, side: Side) -> Vec<Move> {
 }
 
 
-pub fn generate_legal_sorted_moves(game: &mut Game, _hash: &mut Cache, killers: &[Move], ce: Option<CacheEntry>, side: Side) -> Vec<Move> {
+pub fn generate_legal_sorted_moves(game: &mut Game, hash: &mut Cache, killers: &[Move], ce: Option<CacheEntry>, side: Side) -> Vec<Move> {
     let moves = generate_moves(game, side);
 
     let illegal_value = crate::evaluate::MAX_VALUE;
@@ -219,9 +219,10 @@ pub fn generate_legal_sorted_moves(game: &mut Game, _hash: &mut Cache, killers:
         }
 
         let pv_bonus = if let Some(c) = &ce { if &c.mov == mov { 1000 } else { 0 } } else { 0 };
-        let killer_bonus = if killers.contains(mov) { 200 } else { 0 };
+        let killer_bonus = if killers.contains(mov) { 300 } else { 0 };
+        let capture_bonus: i32 = -mvv_lva_score(mov) / 16;
 
-        let eval = crate::evaluate::evaluate(game) - killer_bonus - pv_bonus;
+        let eval = crate::evaluate::evaluate(game) - killer_bonus - capture_bonus - pv_bonus;
         game.undo_move(undo);
         return eval;
     };
@@ -276,7 +277,7 @@ pub fn sort_moves(game: &mut Game, hash: &mut Cache, killers: &[Move], move_list
 /// assigns a score to capture moves lower the more valuable the captured piece. Secondly
 /// also higher the more the attacking piece is worth.
 /// 
-fn lva_mvv_score(mov: &Move) -> i32 {
+fn mvv_lva_score(mov: &Move) -> i32 {
     const PIECE_VALUES: [i32; 6] = [
         100, // Pawn
         220, // Knight
@@ -301,7 +302,7 @@ fn lva_mvv_score(mov: &Move) -> i32 {
 }
 
 pub fn sort_moves_least_valuable_attacker(_game: &mut Game, move_list: &mut Vec<Move>) {
-    move_list.sort_by_cached_key(lva_mvv_score)
+    move_list.sort_by_cached_key(mvv_lva_score)
 }
 
 pub fn sort_moves_no_hash(game: &mut Game, move_list: &mut Vec<Move>) {

+ 8 - 7
src/search.rs

@@ -65,6 +65,7 @@ impl<'a> SearchControl<'a> {
 }
 
 
+
 /**
  * searches for moves and returns the best move found plus its value
  */
@@ -73,15 +74,15 @@ pub fn search(game: &mut Game, sc: &mut SearchControl, hash: &mut Cache, mut alp
         return SearchResult::Invalid;
     }
 
-    let mut moves = generate_legal_moves(game, game.turn);
+    let cache_entry = hash.lookup(game);
+
     let ply_depth = (sc.initial_depth - depth) as usize;
-    sort_moves(game, hash, &sc.killer_moves[ply_depth], &mut moves);
+    let moves = generate_legal_sorted_moves(game, hash, &sc.killer_moves[ply_depth], cache_entry, game.turn);
+    //let mut moves = generate_legal_moves(game, game.turn);
+    //sort_moves(game, hash, &sc.killer_moves[ply_depth], &mut moves);
     
     info!("moves: {:?}", moves.iter().map(|mv| mv.to_string()).collect::<Vec<String>>());
 
-    //let mut alpha: PosValue = MIN_VALUE;
-    //let mut beta: PosValue = MAX_VALUE;
-
     // use a slight offset for the alpha value in the root node in order to
     // determine possibly multiple good moves
     const ALPHA_OFFSET: PosValue = 0 as PosValue;
@@ -231,7 +232,7 @@ pub fn negamax(game: &mut Game, sc: &mut SearchControl, hash: &mut Cache, mut al
             if !mov.is_capture() {
                 sc.insert_killer(ply_depth, mov);
             }
-            return beta;
+            return val;
         }
         if increase_mate_in(val) > alpha {
             alpha = increase_mate_in(val);
@@ -247,7 +248,7 @@ pub fn negamax(game: &mut Game, sc: &mut SearchControl, hash: &mut Cache, mut al
         sc.pv[cur_depth] = best_move;
     }
     else {
-        //hash.cache(game, CacheEntry::new_lower(depth, alpha));
+        hash.cache(game, CacheEntry::new_lower(depth, Move::Nullmove, alpha));
     }
     //info!("best alpha {}", alpha);
     return alpha;