Bläddra i källkod

Merge branch 'master' of http://git.winfor.ch/nicolas/bishop

Nicolas Winkler 3 år sedan
förälder
incheckning
da51d59445
6 ändrade filer med 37 tillägg och 131 borttagningar
  1. 4 0
      src/engine.rs
  2. 4 8
      src/game.rs
  3. 1 1
      src/interface.rs
  4. 0 5
      src/main.rs
  5. 22 11
      src/movegen.rs
  6. 6 106
      src/search.rs

+ 4 - 0
src/engine.rs

@@ -44,7 +44,10 @@ pub struct Engine {
     move_history: RepetitionTable,
     messages: VecDeque<EngineMsg>,
     r: Receiver<EngineMsg>,
+
+    #[allow(unused)]
     s: Sender<InterfaceMsg>,
+    
     hash: Cache,
     zobrist_table: Arc<ZobristTable>
 }
@@ -123,6 +126,7 @@ impl Engine {
         }
     }
 
+    #[allow(unused)]
     fn try_dequeue_message(&mut self) -> Option<EngineMsg> {
         if self.messages.is_empty() {
             self.r.try_recv().ok()

+ 4 - 8
src/game.rs

@@ -167,8 +167,7 @@ impl Game {
     }
 
     pub fn from_fen_str(fen: &str) -> Option<Game> {
-        let mut fen_parts = fen.split_whitespace();
-
+        let fen_parts = fen.split_whitespace();
         Self::from_fen(fen_parts.collect::<Vec<&str>>().as_slice())
     }
 
@@ -228,11 +227,11 @@ impl Game {
 
                     // pawn capture
                     let (from_file, from_row) = indices_from_square(from);
-                    let (to_file, to_row) = indices_from_square(to);
-                    if piece_type == PAWN && from_file != to_file {
+                    let (target_file, _target_row) = indices_from_square(to);
+                    if piece_type == PAWN && from_file != target_file {
                         let others = self.get_all_side(!side);
                         if others & from_square(to) == 0 {
-                            let beaten = square_from_indices(to_file, from_row);
+                            let beaten = square_from_indices(target_file, from_row);
                             return Ok(Move::EnPassant{ mov: SimpleMove{ from, to }, beaten });
                         }
                     }
@@ -591,11 +590,8 @@ impl Game {
         let en_passant_before = self.en_passant;
 
         let side = self.turn;
-        let friends = self.get_all_side(side);
         let others = self.get_all_side(!side);
 
-        let with_zobrist = self.zobrist.is_some();
-
         match mov {
             Move::Default{ mov, piece_type: pt, captured: _ } => {
 

+ 1 - 1
src/interface.rs

@@ -52,7 +52,7 @@ fn cmd_isready(_args: Vec<&str>) {
     println!("readyok");
 }
 
-fn cmd_position(mut args: Vec<&str>, r: &Receiver<InterfaceMsg>, s: &Sender<EngineMsg>) {
+fn cmd_position(mut args: Vec<&str>, _r: &Receiver<InterfaceMsg>, s: &Sender<EngineMsg>) {
     let position = args[0];
     args.drain(0..1);
 

+ 0 - 5
src/main.rs

@@ -12,15 +12,10 @@ extern crate log;
 extern crate simplelog;
 extern crate rand;
 
-use simplelog::*;
-
 use std::sync::mpsc;
 use std::{thread, fs::File};
-use log::*;
 use engine::Engine;
 
-use evaluate::*;
-
 fn main() {
     /*let mut builder = Builder::from_default_env();
     builder

+ 22 - 11
src/movegen.rs

@@ -2,7 +2,7 @@ use bitboard::Bitboard;
 use bitboard::Square;
 use bitboard::*;
 use game::Game;
-use hash::Cache;
+use hash::{Cache, EntryType};
 
 pub type Side = bool;
 
@@ -25,8 +25,6 @@ pub struct SimpleMove {
     pub to: Square,
 }
 
-struct MovePieceTypes(u8);
-
 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
 pub enum Move {
     Default { mov: SimpleMove, piece_type: PieceType, captured: Option<PieceType> },
@@ -176,13 +174,17 @@ pub fn generate_possattacking_moves(game: &Game, side: Side) -> Vec<Move> {
 }
 
 
-pub fn generate_legal_moves(game: &Game, side: Side) -> Vec<Move> {
+pub fn generate_legal_moves(game: &mut Game, side: Side) -> Vec<Move> {
     let moves = generate_moves(game, side);
 
-    moves.into_iter().filter(|mov| {
-        let tryout = crate::search::apply_move(game, *mov);
-        !is_check(&tryout, side)
-    }).collect::<Vec<Move>>()
+    let check_legality = |mov: &Move| {
+        let undo = game.apply(*mov);
+        let legal = !is_check(game, side);
+        game.undo_move(undo);
+        return legal;
+    };
+
+    moves.into_iter().filter(check_legality).collect::<Vec<Move>>()
 }
 
 
@@ -201,11 +203,21 @@ pub fn generate_attacking_moves(game: &Game, side: Side) -> Vec<Move> {
 pub fn sort_moves(game: &mut Game, hash: &mut Cache, move_list: &mut Vec<Move>) {
 
     move_list.sort_by_cached_key(|mov| {
-
         let undo = game.apply(*mov);
         if let Some(e) = hash.lookup(game) {
             game.undo_move(undo);
-            return e.value;
+            if let EntryType::Value = e.entry_type {
+                return e.value;
+            }
+            else if let EntryType::LowerBound = e.entry_type {
+                return e.value - 1000;
+            }
+            else if let EntryType::UpperBound = e.entry_type {
+                return e.value + 1000;
+            }
+            else {
+                return 0;
+            }
         }
         else {
             let eval = crate::evaluate::evaluate(game);
@@ -366,7 +378,6 @@ fn generate_knight_moves(game: &Game, side: Side, move_list: &mut Vec<Move>, cap
         let nocap_targets = BitboardIterator(get_knight_targets(square(k)) & (!friends & !others));
 
         for target in cap_targets {
-            let target_square = square(target);
             let simple_move = SimpleMove { from: square(k), to: square(target) };
             let captured = game.find_piece(target);
             move_list.push(Move::Default{ mov: simple_move, piece_type: KNIGHT, captured });

+ 6 - 106
src/search.rs

@@ -1,4 +1,3 @@
-use bitboard::*;
 use movegen::*;
 use game::Game;
 use evaluate::*;
@@ -264,6 +263,12 @@ fn quiescence_search(game: &mut Game, sc: &mut SearchControl, hash: &mut Cache,
 
         let (mut val, ret) = quiescence_search(game, sc, hash, -beta, -alpha, depth - 1);
         val = -val;
+
+        if ret {
+            game.undo_move(undo);
+            return (alpha, ret)
+        }
+
         if val >= beta {
             game.undo_move(undo);
             return (beta, false);
@@ -277,111 +282,6 @@ fn quiescence_search(game: &mut Game, sc: &mut SearchControl, hash: &mut Cache,
 }
 
 
-pub fn apply_move(game: &Game, mov: Move) -> Game {
-    let mut new_game = game.clone();
-
-    let side = game.turn;
-    let friends = game.get_all_side(side);
-    let others = game.get_all_side(!side);
-    match mov {
-        Move::Default{ mov, piece_type: pt, captured: _ } => {
-
-            if pt == KING {
-                // invalidate castling rights
-                new_game.castling_rights[if game.turn == BLACK { 2 } else { 0 }] = false;
-                new_game.castling_rights[if game.turn == BLACK { 3 } else { 1 }] = false;
-            }
-
-            // invalidate castling rights
-            if mov.from == square_from_indices(7, 0) || mov.to == square_from_indices(7, 0) {
-                new_game.castling_rights[0] = false;
-            }
-            if mov.from == square_from_indices(0, 0) || mov.to == square_from_indices(0, 0) {
-                new_game.castling_rights[1] = false;
-            }
-            if mov.from == square_from_indices(7, 7) || mov.to == square_from_indices(7, 7) {
-                new_game.castling_rights[2] = false;
-            }
-            if mov.from == square_from_indices(0, 7) || mov.to == square_from_indices(0, 7) {
-                new_game.castling_rights[3] = false;
-            }
-
-            // if it is a capture
-            if from_square(mov.to) & others != 0 {
-                let (other_piece, other_side) = game.get_square(mov.to);
-                if let Some((ref zt, ref _zv)) = game.zobrist {
-                    let hup = zt.piece_hash(other_piece, other_side, mov.to);
-                    new_game.update_zobrist(hup);
-                }
-                new_game.apply_mask(!from_square(mov.to));
-            }
-
-            let moved_piece = mov.apply_to(new_game.get_piece(pt, side));
-            new_game.set_piece(pt, side, moved_piece);
-
-            if let Some((ref zt, ref _zv)) = game.zobrist {
-                let hup = zt.piece_hash(pt, side, mov.from) ^ zt.piece_hash(pt, side, mov.to);
-                new_game.update_zobrist(hup);
-            }
-        },
-        Move::Castling { side, left } => {
-            // invalidate future castling rights
-            new_game.castling_rights[if game.turn == BLACK { 2 } else { 0 }] = false;
-            new_game.castling_rights[if game.turn == BLACK { 3 } else { 1 }] = false;
-
-            let king = game.get_piece(KING, side);
-            let rook = if left {
-                game.get_piece(ROOK, side) & (king << 4)
-            }
-            else {
-                game.get_piece(ROOK, side) & (king >> 3)
-            };
-
-            let new_king = if left { king << 2 } else { king >> 2 };
-            let new_rook = if left { rook >> 3 } else { rook << 2 };
-
-            new_game.set_piece(KING, side, new_king);
-            *new_game.get_piece_mut(ROOK, side) |= new_rook;
-            *new_game.get_piece_mut(ROOK, side) &= !rook;
-        },
-        Move::EnPassant { mov, beaten } => {
-            let pawns = game.pawns(side);
-            if let Some(ep) = game.en_passant {
-                *new_game.get_piece_mut(PAWN, side) &= !from_square(mov.from);
-                *new_game.get_piece_mut(PAWN, side) |= from_square(mov.to);
-                *new_game.get_piece_mut(PAWN, !side) &= !from_square(beaten);
-            }
-        },
-        Move::Promotion { mov, promote_to, captured } => {
-            //if from_square(mov.to) & others != 0 {
-            if let Some(pt) = captured {
-                *new_game.get_piece_mut(pt, !side) &= !from_square(mov.to);
-            }
-            new_game.apply_mask(!from_square(mov.from));
-
-            match promote_to {
-                QUEEN => { *new_game.queens_mut(side) |= from_square(mov.to); }
-                ROOK => { *new_game.rooks_mut(side) |= from_square(mov.to); }
-                BISHOP => { *new_game.bishops_mut(side) |= from_square(mov.to); }
-                KNIGHT => { *new_game.knights_mut(side) |= from_square(mov.to); }
-                _ => {
-                    info!("internal error");
-                }
-            }
-        },
-        Move::Nullmove => {}
-    }
-
-    new_game.turn = !new_game.turn;
-
-
-    if let Some((ref zt, ref zv)) = new_game.zobrist {
-        //info!("applied {}, zobrist now {}", mov.to_string(), *zv);
-    }
-    return new_game;
-}
-
-
 pub fn perft(game: &mut Game, sc: &mut SearchControl, depth: i32) -> bool {
     let moves = generate_legal_moves(game, game.turn);