diff options
author | eug-vs <eugene@eug-vs.xyz> | 2023-02-26 23:26:51 +0300 |
---|---|---|
committer | eug-vs <eugene@eug-vs.xyz> | 2023-02-26 23:27:20 +0300 |
commit | 8e7ac2814c4a92eba79f9c626ad14ac0b7bfef3f (patch) | |
tree | da30e36423d5b1aa4aaaa2666b985e9674680850 | |
parent | 54e72754d0fae2b2768b66c39c72e9afaba0cba8 (diff) | |
download | chessnost-8e7ac2814c4a92eba79f9c626ad14ac0b7bfef3f.tar.gz |
feat: add clock and time management to UCI
-rw-r--r-- | src/board/io.rs | 3 | ||||
-rw-r--r-- | src/board/mod.rs | 4 | ||||
-rw-r--r-- | src/clock.rs | 22 | ||||
-rw-r--r-- | src/grossmeister/UCI.rs | 66 | ||||
-rw-r--r-- | src/grossmeister/search.rs | 1 | ||||
-rw-r--r-- | src/lib.rs | 1 |
6 files changed, 81 insertions, 16 deletions
diff --git a/src/board/io.rs b/src/board/io.rs index 67aa096..d27b856 100644 --- a/src/board/io.rs +++ b/src/board/io.rs @@ -1,4 +1,4 @@ -use crate::{bitboard::Bitboard, attacks::Attacks, moves::Move}; +use crate::{bitboard::Bitboard, attacks::Attacks, moves::Move, clock::Clock}; use super::{Board, Piece, zobrist::Zobrist}; const PIECE_CHARS: [&str; 12] = [ @@ -96,6 +96,7 @@ impl IO for Board { attacks: Attacks::new(), castling_rights: [[true; 2]; 2], // TODO: actualy parse from FEN ep_target: None, // TODO: parse from FEN + clock: Clock::default(), hash: 0, zobrist_seed: Board::seed(), }; diff --git a/src/board/mod.rs b/src/board/mod.rs index 6fb8b93..95d470a 100644 --- a/src/board/mod.rs +++ b/src/board/mod.rs @@ -1,4 +1,4 @@ -use crate::{bitboard::{Bitboard, BitboardFns}, moves::{Move, MoveKind}, attacks::Attacks, square::Square, board::io::IO}; +use crate::{bitboard::{Bitboard, BitboardFns}, moves::{Move, MoveKind}, attacks::Attacks, square::Square, board::io::IO, clock::Clock}; use self::{zobrist::{ZobristSeed, Zobrist}, piece::Piece, color::Color}; pub mod io; @@ -24,6 +24,8 @@ pub struct Board { /// En passsant target square pub ep_target: Option<Square>, + pub clock: Clock, + // Computed values pub occupancy: Bitboard, /// Zobrist hash of the current position diff --git a/src/clock.rs b/src/clock.rs new file mode 100644 index 0000000..896307a --- /dev/null +++ b/src/clock.rs @@ -0,0 +1,22 @@ +use std::time::Duration; + +#[derive(Debug, Clone, Copy, PartialEq)] +pub struct Clock { + pub time: [Duration; 2], // White, Black + pub increment: [Duration; 2], +} + +impl Default for Clock { + fn default() -> Self { + Self::new(Duration::from_secs(60 * 5), Duration::from_secs(3)) + } +} + +impl Clock { + pub fn new(time: Duration, increment: Duration) -> Self { + Self { + time: [time, time], + increment: [increment, increment], + } + } +} diff --git a/src/grossmeister/UCI.rs b/src/grossmeister/UCI.rs index d5e67a1..2c466a1 100644 --- a/src/grossmeister/UCI.rs +++ b/src/grossmeister/UCI.rs @@ -1,6 +1,6 @@ -use std::{io::stdin, thread::{Builder, JoinHandle}, str::Split}; +use std::{io::stdin, thread::{Builder, JoinHandle, spawn, sleep}, str::Split, time::Duration}; -use crate::{board::{Board, io::IO}, moves::Move}; +use crate::{board::{Board, io::IO, color::Color}, moves::Move}; use super::Grossmeister; @@ -91,7 +91,6 @@ impl Grossmeister { // his transposition table is more saturated *self = hand.join().unwrap(); } - self.should_halt.store(false, std::sync::atomic::Ordering::Relaxed); } "ponderhit" => todo!(), "quit" => break, @@ -106,10 +105,30 @@ impl Grossmeister { match token { "searchmoves" => todo!(), "ponder" => todo!(), - "wtime" => {} - "btime" => {} - "winc" => {} - "binc" => {} + "wtime" => { + if let Some(time) = tokens.next() { + let time: u64 = time.parse().unwrap(); + self.board.clock.time[Color::White as usize] = Duration::from_millis(time); + } + } + "btime" => { + if let Some(time) = tokens.next() { + let time: u64 = time.parse().unwrap(); + self.board.clock.time[Color::Black as usize] = Duration::from_millis(time); + } + } + "winc" => { + if let Some(time) = tokens.next() { + let time: u64 = time.parse().unwrap(); + self.board.clock.increment[Color::White as usize] = Duration::from_millis(time); + } + } + "binc" => { + if let Some(time) = tokens.next() { + let time: u64 = time.parse().unwrap(); + self.board.clock.increment[Color::White as usize] = Duration::from_millis(time); + } + } "movestogo" => {} "depth" => { if let Some(depth) = tokens.next() { @@ -119,7 +138,15 @@ impl Grossmeister { }, "nodes" => todo!(), "mate" => todo!(), - "movetime" => todo!(), + "movetime" => { + if let Some(time) = tokens.next() { + let time: u64 = time.parse().unwrap(); + let duration = Duration::from_millis(time); + + self.create_terminator_thread(duration); + return self.create_search_thread(u8::MAX) + } + }, "infinite" => { return self.create_search_thread(u8::MAX); }, @@ -127,19 +154,30 @@ impl Grossmeister { } return self.parse_go(tokens) } - self.create_search_thread(6) + + let color = self.board.color(); + let duration = self.board.clock.time[color as usize] / 20 + self.board.clock.increment[color as usize]; + + self.create_terminator_thread(duration); + self.create_search_thread(u8::MAX) + } + + fn create_terminator_thread(&self, duration: Duration) -> JoinHandle<()> { + let should_halt = self.should_halt.clone(); + spawn(move || { + println!("info string terminating search in {:?}", duration); + sleep(duration); + should_halt.store(true, std::sync::atomic::Ordering::Relaxed); + }) } fn create_search_thread(&self, depth: u8) -> JoinHandle<Self> { // Clone current self and move it // into thread to analyze a position let mut gm = self.clone(); - let builder = Builder::new(); - - - builder.spawn(move || { + spawn(move || { gm.iterative_deepening(depth); gm - }).unwrap() + }) } } diff --git a/src/grossmeister/search.rs b/src/grossmeister/search.rs index def4305..f0805cb 100644 --- a/src/grossmeister/search.rs +++ b/src/grossmeister/search.rs @@ -215,6 +215,7 @@ impl Grossmeister { if self.debug { println!("info string aborting"); } + self.should_halt.store(false, std::sync::atomic::Ordering::Relaxed); break; } @@ -1,6 +1,7 @@ pub mod square; pub mod bitboard; pub mod board; +pub mod clock; pub mod attacks; pub mod moves; pub mod grossmeister; |