aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoreug-vs <eugene@eug-vs.xyz>2023-02-26 19:17:58 +0300
committereug-vs <eugene@eug-vs.xyz>2023-02-26 19:22:44 +0300
commit3ae684ec1f697f2e34eec755bfeffb20a3a1d856 (patch)
tree96f26c9cb33807b75e6459d933dce6a9b7ea97fd
parent40dffd88a018bb3757d7b0e3c97ba0ae4b4e8945 (diff)
downloadchessnost-3ae684ec1f697f2e34eec755bfeffb20a3a1d856.tar.gz
feat: add GUI->engine UCI commands
-rw-r--r--src/grossmeister/UCI.rs149
-rw-r--r--src/grossmeister/mod.rs4
2 files changed, 102 insertions, 51 deletions
diff --git a/src/grossmeister/UCI.rs b/src/grossmeister/UCI.rs
index 3531a1e..1e85b71 100644
--- a/src/grossmeister/UCI.rs
+++ b/src/grossmeister/UCI.rs
@@ -9,68 +9,117 @@ const AUTHOR: &str = "Eugene Sokolov";
impl Grossmeister {
pub fn start(&mut self) {
- let mut board = Board::new();
let mut search_handle = None;
loop {
let mut cmd = String::new();
stdin().read_line(&mut cmd).unwrap();
- let tokens: Vec<&str> = cmd.trim().split(' ').collect();
- println!("Command: {:?}, tokens: {:?}", cmd, tokens);
+ let mut tokens = cmd.trim().split(' ');
- match tokens[0] {
- "uci" => {
- println!("id name {}", NAME);
- println!("id author {}", AUTHOR);
- println!("uciok");
- }
- "isready" => {
- println!("readyok");
- }
- "position" => {
- match tokens[1] {
- "startpos" => {
- board = Board::new();
- }
- _ => {
- todo!("Parse FEN")
- }
+ if let Some(token) = tokens.next() {
+ match token {
+ "uci" => {
+ println!("id name {}", NAME);
+ println!("id author {}", AUTHOR);
+ println!("uciok");
}
- assert!(tokens[2] == "moves");
- for move_token in tokens.iter().skip(3) {
- let mov = Move::from_notation(move_token.chars());
- board.make_move(mov);
- println!("{:?}", mov);
- board.print();
+ "debug" => {
+ if let Some(token) = tokens.next() {
+ match token {
+ "on" => self.debug = true,
+ "off" => self.debug = false,
+ _ => {
+ panic!("Wrong option to debug: {}. CMD: {}", token, cmd);
+ },
+ }
+ };
}
- }
- "go" => {
- match tokens[1] {
- "infinite" => {
- // Clone current self and move it
- // into thread to analyze a position
- let mut gm = self.clone();
- let builder = Builder::new();
+ "isready" => {
+ println!("readyok");
+ }
+ "setoption" => {
+ todo!()
+ }
+ "ucinewgame" => {
+ todo!("What should we even do here?")
+ }
+ "position" => {
+ if let Some(token) = tokens.next() {
+ match token {
+ "startpos" => {
+ self.board = Board::new();
- search_handle = Some(builder.spawn(move || {
- gm.analyze(board);
- gm
- }).unwrap());
- },
- _ => todo!()
+ if let Some(token) = tokens.next() {
+ if token == "moves" {
+ for token in tokens.by_ref() {
+ let mov = Move::from_notation(token.chars());
+ self.board.make_move(mov);
+ println!("{:?}", mov);
+ self.board.print();
+ }
+ } else {
+ panic!("Unexpected token: {}. CMD: {}", token, cmd);
+ }
+ }
+ }
+ "fen" => {
+ // TODO: handle "moves" command after "fen"?
+ let index = "position fen".len() + 1;
+ if let Some(fen) = cmd.get(index..) {
+ self.board = Board::from_FEN(fen.to_string());
+ };
+ }
+ _ => {
+ todo!("Parse FEN")
+ }
+ }
+ } else {
+ todo!("Decide what to do when position is now provided")
+ }
}
- },
- "stop" => {
- self.should_halt.store(true, std::sync::atomic::Ordering::Relaxed);
- if let Some(hand) = search_handle.take() {
- // Search returns new SELF that is more powerful
- // because he evaluated many new positions and
- // his transposition table is more saturated
- *self = hand.join().unwrap();
+ "go" => {
+ if let Some(token) = tokens.next() {
+ match token {
+ "searchmoves" => todo!(),
+ "ponder" => todo!(),
+ "wtime" => todo!(),
+ "btime" => todo!(),
+ "winc" => todo!(),
+ "binc" => todo!(),
+ "movestogo" => todo!(),
+ "depth" => todo!(),
+ "nodes" => todo!(),
+ "mate" => todo!(),
+ "movetime" => todo!(),
+ "infinite" => {
+ // Clone current self and move it
+ // into thread to analyze a position
+ let mut gm = self.clone();
+ let builder = Builder::new();
+
+ search_handle = Some(builder.spawn(move || {
+ gm.analyze(gm.board);
+ gm
+ }).unwrap());
+ },
+ _ => todo!()
+ }
+ }
+ },
+ "stop" => {
+ self.should_halt.store(true, std::sync::atomic::Ordering::Relaxed);
+ if let Some(hand) = search_handle.take() {
+ // Search returns new SELF that is more powerful
+ // because he evaluated many new positions and
+ // his transposition table is more saturated
+ *self = hand.join().unwrap();
+ }
+ self.should_halt.store(false, std::sync::atomic::Ordering::Relaxed);
}
- self.should_halt.store(false, std::sync::atomic::Ordering::Relaxed);
+ "ponderhit" => todo!(),
+ "quit" => break,
+ _ => {},
}
- _ => {},
}
}
}
diff --git a/src/grossmeister/mod.rs b/src/grossmeister/mod.rs
index 10788d5..bd123d4 100644
--- a/src/grossmeister/mod.rs
+++ b/src/grossmeister/mod.rs
@@ -22,7 +22,8 @@ pub struct Grossmeister {
/// It's indexex by Zobrist hash of a position mod size
transposition_table: TranspositionTable,
- should_halt: Arc<AtomicBool>
+ should_halt: Arc<AtomicBool>,
+ debug: bool,
}
impl Default for Grossmeister {
@@ -37,6 +38,7 @@ impl Grossmeister {
board,
transposition_table: vec![None; TTABLE_SIZE as usize],
should_halt: Arc::new(AtomicBool::new(false)),
+ debug: false,
}
}
}