diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/board/mod.rs | 2 | ||||
-rw-r--r-- | src/grossmeister/evaluation.rs | 16 | ||||
-rw-r--r-- | src/grossmeister/mod.rs | 26 | ||||
-rw-r--r-- | src/grossmeister/perft.rs | 0 | ||||
-rw-r--r-- | src/main.rs | 50 | ||||
-rw-r--r-- | src/player.rs | 3 |
6 files changed, 55 insertions, 42 deletions
diff --git a/src/board/mod.rs b/src/board/mod.rs index ff01ddc..6fb8b93 100644 --- a/src/board/mod.rs +++ b/src/board/mod.rs @@ -30,7 +30,7 @@ pub struct Board { pub hash: u64, zobrist_seed: ZobristSeed, - attacks: Attacks, + pub attacks: Attacks, } impl Default for Board { diff --git a/src/grossmeister/evaluation.rs b/src/grossmeister/evaluation.rs index 61d375c..308f320 100644 --- a/src/grossmeister/evaluation.rs +++ b/src/grossmeister/evaluation.rs @@ -198,7 +198,7 @@ impl Grossmeister { }; let pawn_attacked_squares = opponent_pawns.serialize().iter().fold(0u64, |acc, square| { - acc | self.attacks.pawn[color.flip() as usize][*square as usize] + acc | self.board.attacks.pawn[color.flip() as usize][*square as usize] }); // Exclude squares controlled by enemy pawns from mobility @@ -219,20 +219,20 @@ impl Grossmeister { } None => 0, }; - mobility += (self.attacks.pawn[color as usize][source as usize] & (opponent_occupancy | ep_bitboard)).pop_count() as f32; - mobility += (self.attacks.pawn_pushes[color as usize][source as usize] & empty).pop_count() as f32; + mobility += (self.board.attacks.pawn[color as usize][source as usize] & (opponent_occupancy | ep_bitboard)).pop_count() as f32; + mobility += (self.board.attacks.pawn_pushes[color as usize][source as usize] & empty).pop_count() as f32; } let able_to_double_push_mask = match color { Color::White => empty >> 8, Color::Black => empty << 8, }; for source in (*piece & able_to_double_push_mask).serialize() { - mobility += (self.attacks.pawn_double_pushes[color as usize][source as usize] & empty).pop_count() as f32; + mobility += (self.board.attacks.pawn_double_pushes[color as usize][source as usize] & empty).pop_count() as f32; } } Piece::King => { for source in piece.serialize() { - mobility += (self.attacks.king[source as usize] & (empty | opponent_occupancy)).pop_count() as f32; + mobility += (self.board.attacks.king[source as usize] & (empty | opponent_occupancy)).pop_count() as f32; // Castling let king_home_position = match color { @@ -280,17 +280,17 @@ impl Grossmeister { } Piece::Knight => { for source in piece.serialize() { - mobility += (self.attacks.knight[source as usize] & (empty | opponent_occupancy)).pop_count() as f32; + mobility += (self.board.attacks.knight[source as usize] & (empty | opponent_occupancy)).pop_count() as f32; } } Piece::Bishop => { for source in piece.serialize() { - mobility += (self.attacks.bishop(self.board.occupancy, source) & (empty | opponent_occupancy)).pop_count() as f32; + mobility += (self.board.attacks.bishop(self.board.occupancy, source) & (empty | opponent_occupancy)).pop_count() as f32; } } Piece::Rook => { for source in piece.serialize() { - mobility += (self.attacks.rook(self.board.occupancy, source) & (empty | opponent_occupancy)).pop_count() as f32; + mobility += (self.board.attacks.rook(self.board.occupancy, source) & (empty | opponent_occupancy)).pop_count() as f32; } } Piece::Queen => { diff --git a/src/grossmeister/mod.rs b/src/grossmeister/mod.rs index d9e5d1d..d07aeee 100644 --- a/src/grossmeister/mod.rs +++ b/src/grossmeister/mod.rs @@ -1,4 +1,6 @@ -use crate::{board::Board, attacks::Attacks}; +use std::time::Duration; + +use crate::{board::Board, player::Player, moves::Move}; use self::ttable::{TranspositionTable, TTABLE_SIZE}; mod ttable; @@ -9,12 +11,9 @@ mod search; /// This structure represents a player, it stores his knowledge /// and experience about the game. pub struct Grossmeister { - pub board: Board, - - /// Array of pre-computed attack tables. - /// This structure allows Grossmeister to calculate attacks of the pieces - /// as fast as possible using his big brain. - attacks: Attacks, + /// GM's internal board representation + /// This is usually a copy of a real board + board: Board, /// Transposition table is a cache of all positions that Grossmeister /// has seen and evaluated. @@ -22,13 +21,24 @@ pub struct Grossmeister { transposition_table: TranspositionTable, } +impl Default for Grossmeister { + fn default() -> Self { + Self::new(Board::default()) + } +} impl Grossmeister { pub fn new(board: Board) -> Self { Self { board, - attacks: Attacks::new(), transposition_table: vec![None; TTABLE_SIZE as usize], } } } + +impl Player for Grossmeister { + fn analyze(&mut self, board: Board, duration: Duration) -> (f32, Vec<Move>) { + self.board = board; // Copy the board into GM's head + self.iterative_deepening(8, duration, true) + } +} diff --git a/src/grossmeister/perft.rs b/src/grossmeister/perft.rs deleted file mode 100644 index e69de29..0000000 --- a/src/grossmeister/perft.rs +++ /dev/null diff --git a/src/main.rs b/src/main.rs index e7633bc..049dc68 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,27 +5,28 @@ use chessnost::board::color::Color; use chessnost::board::io::IO; use chessnost::board::Board; use chessnost::grossmeister::Grossmeister; +use chessnost::player::Player; -fn opponent_move(gm: &mut Grossmeister) { - let mov = match gm.board.read_move() { +fn opponent_move(board: &mut Board) { + let mov = match board.read_move() { Ok(m) => m, Err(e) => { println!("Error: {}", e); - return opponent_move(gm); + return opponent_move(board); } }; print!("{:?}", mov); - gm.board.make_move(mov); - gm.board.print(); + board.make_move(mov); + board.print(); } -fn computer_move(gm: &mut Grossmeister, time_left: &mut Duration) { +fn computer_move(board: &mut Board, gm: &mut Grossmeister, time_left: &mut Duration) { let allowed_move_duration = *time_left / 20; - let max_depth = 7 + (gm.board.ply as i32 / 15) as u8; + // let max_depth = 7 + (board.ply as i32 / 15) as u8; println!("~{:?} left, allocating {:?} for a move", time_left, allowed_move_duration); let move_start = Instant::now(); - let (score, pv) = gm.iterative_deepening(max_depth, allowed_move_duration, true); + let (score, pv) = gm.analyze(*board, allowed_move_duration); let elapsed = move_start.elapsed(); if *time_left >= elapsed { @@ -38,17 +39,17 @@ fn computer_move(gm: &mut Grossmeister, time_left: &mut Duration) { let mov = pv[0]; println!("{:?}", mov); - gm.board.make_move(mov); - gm.board.print(); + board.make_move(mov); + board.print(); // Ponder for some time - println!("Pondering, assume opponent move from PV: {:?}", pv[1]); - let ep_target_before = gm.board.ep_target; - let castling_rights_before = gm.board.castling_rights; - let hash_before = gm.board.hash; - let captured_piece = gm.board.make_move(pv[1]); - gm.iterative_deepening(max_depth, Duration::from_secs(3), false); - gm.board.unmake_move(pv[1], captured_piece, ep_target_before, castling_rights_before, hash_before); + // println!("Pondering, assume opponent move from PV: {:?}", pv[1]); + // let ep_target_before = gm.board.ep_target; + // let castling_rights_before = gm.board.castling_rights; + // let hash_before = gm.board.hash; + // let captured_piece = gm.board.make_move(pv[1]); + // gm.iterative_deepening(max_depth, Duration::from_secs(3), false); + // gm.board.unmake_move(pv[1], captured_piece, ep_target_before, castling_rights_before, hash_before); } fn main() { @@ -72,26 +73,27 @@ fn main() { }); let manual_decrement = Duration::from_secs(7); // Time to sync moves with the game - let board = if args.len() == 5 { + let mut board = if args.len() == 5 { Board::from_FEN(args[4].to_string()) } else { Board::new() }; + board.print(); + + let mut gm = Grossmeister::default(); - let mut gm = Grossmeister::new(board); - gm.board.print(); loop { time_left += increment; time_left -= manual_decrement; match color { Color::White => { - computer_move(&mut gm, &mut time_left); - opponent_move(&mut gm); + computer_move(&mut board, &mut gm, &mut time_left); + opponent_move(&mut board); } Color::Black => { - opponent_move(&mut gm); - computer_move(&mut gm, &mut time_left); + opponent_move(&mut board); + computer_move(&mut board, &mut gm, &mut time_left); } } } diff --git a/src/player.rs b/src/player.rs index 26cf0cc..15f4a86 100644 --- a/src/player.rs +++ b/src/player.rs @@ -1,7 +1,8 @@ +use std::time::Duration; use crate::{board::Board, moves::Move}; pub trait Player { /// Analyze a position on a given board, giving /// the score for the side to move and Principal Variation. - fn analyze(&self, board: Board) -> (f32, Vec<Move>); + fn analyze(&mut self, board: Board, duration: Duration) -> (f32, Vec<Move>); } |