aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoreug-vs <eugene@eug-vs.xyz>2023-02-26 23:26:51 +0300
committereug-vs <eugene@eug-vs.xyz>2023-02-26 23:27:20 +0300
commit8e7ac2814c4a92eba79f9c626ad14ac0b7bfef3f (patch)
treeda30e36423d5b1aa4aaaa2666b985e9674680850
parent54e72754d0fae2b2768b66c39c72e9afaba0cba8 (diff)
downloadchessnost-8e7ac2814c4a92eba79f9c626ad14ac0b7bfef3f.tar.gz
feat: add clock and time management to UCI
-rw-r--r--src/board/io.rs3
-rw-r--r--src/board/mod.rs4
-rw-r--r--src/clock.rs22
-rw-r--r--src/grossmeister/UCI.rs66
-rw-r--r--src/grossmeister/search.rs1
-rw-r--r--src/lib.rs1
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;
}
diff --git a/src/lib.rs b/src/lib.rs
index beebe77..7f94687 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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;