aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/board/mod.rs2
-rw-r--r--src/grossmeister/evaluation.rs16
-rw-r--r--src/grossmeister/mod.rs26
-rw-r--r--src/grossmeister/perft.rs0
-rw-r--r--src/main.rs50
-rw-r--r--src/player.rs3
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>);
}