Преглед изворни кода

improved move ordering for quiescent moves

Nicolas Winkler пре 2 година
родитељ
комит
5366c73f96
4 измењених фајлова са 44 додато и 7 уклоњено
  1. 1 1
      src/evaluate.rs
  2. 9 0
      src/game.rs
  3. 32 1
      src/movegen.rs
  4. 2 5
      src/search.rs

+ 1 - 1
src/evaluate.rs

@@ -111,7 +111,7 @@ fn knight_value(game: &Game, side: Side) -> PosValue {
     center_knights * 6 + k_attacks as PosValue + ((num_knights * 75 * num_opp_pawns) / 8) as PosValue
 }
 
-fn material_value(game: &Game, side: Side) -> PosValue {
+pub fn material_value(game: &Game, side: Side) -> PosValue {
     (game.get_piece(PAWN, side).count_ones() * 100
         + game.get_piece(KNIGHT, side).count_ones() * 220
         + game.get_piece(BISHOP, side).count_ones() * 320

+ 9 - 0
src/game.rs

@@ -5,6 +5,8 @@ use std::sync::Arc;
 use zobrist::{ZobristTable};
 use zobrist;
 
+use crate::movegen;
+
 #[derive(Clone)]
 pub struct Game
 {
@@ -568,6 +570,13 @@ impl Game {
         }
     }
 
+    ///
+    /// TODO: improve
+    /// 
+    pub fn is_legal(&self, mov: Move) -> bool {
+        movegen::generate_legal_moves(&mut self.clone(), self.turn).contains(&mov)
+    }
+
     pub fn apply(&mut self, mov: Move) -> MoveUndo {
 
         /*if !self.is_zobrist_correct() {

+ 32 - 1
src/movegen.rs

@@ -271,10 +271,41 @@ pub fn sort_moves(game: &mut Game, hash: &mut Cache, killers: &[Move], move_list
     });
 }
 
+pub fn sort_moves_least_valuable_attacker(game: &mut Game, move_list: &mut Vec<Move>) {
+    const piece_values: [i32; 6] = [
+        100, // Pawn
+        220, // Knight
+        320, // Bishop
+        400, // Rook
+        800, // Queen
+        100000 // King
+    ];
+
+    let lva_mvv_score= |mov: &Move| {
+        let v = match mov {
+            Move::Default { mov: _, piece_type, captured } => {
+                let attack = piece_values[*piece_type as usize];
+                let victim = captured.map(|ct| piece_values[ct as usize]).unwrap_or(0);
+                attack - victim * 5
+            },
+            Move::Promotion { mov: _, promote_to: _, captured } => {
+                let victim = captured.map(|ct| piece_values[ct as usize]).unwrap_or(0);
+                piece_values[PAWN as usize] - victim * 5
+            },
+            _ => 0
+        };
+        v
+    };
+
+    move_list.sort_by_cached_key(lva_mvv_score)
+}
+
 pub fn sort_moves_no_hash(game: &mut Game, move_list: &mut Vec<Move>) {
     move_list.sort_by_cached_key(|mov| {
         let undo = game.apply(*mov);
-        let eval = crate::evaluate::evaluate(game);
+        let our_material = crate::evaluate::material_value(game, game.turn);
+        let their_material = crate::evaluate::material_value(game, !game.turn);
+        let eval = our_material - their_material;
         game.undo_move(undo);
         return eval;
     });

+ 2 - 5
src/search.rs

@@ -207,10 +207,6 @@ pub fn negamax(game: &mut Game, sc: &mut SearchControl, hash: &mut Cache, mut al
         }
     }
 
-
-    //sort_moves(game, hash, &sc.killer_moves, &mut moves);
-    //moves.sort_by_cached_key(|m| if sc.is_killer(*m) { -1 } else { 0 });
-
     let mut alpha_is_exact = false;
     let mut best_move = Move::Nullmove;
 
@@ -283,7 +279,8 @@ fn quiescence_search(game: &mut Game, sc: &mut SearchControl, hash: &mut Cache,
 
     let mut moves = generate_attacking_moves(game, game.turn);
 
-    sort_moves_no_hash(game, &mut moves);
+    //sort_moves_no_hash(game, &mut moves);
+    sort_moves_least_valuable_attacker(game, &mut moves);
 
     for mov in moves {
         let undo = game.apply(mov);