Add basic UCI support

This commit is contained in:
2024-07-31 23:59:09 +03:00
parent 1c80db695f
commit 48cf03fd9d
5 changed files with 209 additions and 2 deletions

97
src/uci.rs Normal file
View File

@@ -0,0 +1,97 @@
use std::str::SplitWhitespace;
use crate::{game::Game, r#move::Move, search::search};
pub enum Command {
Uci,
IsReady,
UciNewGame,
Position(String),
Go,
Stop,
Quit,
}
pub enum Response {
Id(String),
UciOk,
ReadyOk,
BestMove(String),
Info(String),
}
struct SearchParameters {
movetime: Option<usize>,
depth: Option<u8>,
}
impl SearchParameters {
const fn new() -> Self {
Self {
movetime: None,
depth: None,
}
}
fn add_movetime(&mut self, movetime: usize) {
self.movetime = Some(movetime);
}
fn add_depth(&mut self, depth: u8) {
self.depth = Some(depth);
}
}
impl Default for SearchParameters {
fn default() -> Self {
Self::new()
}
}
pub fn uci_position(mut position: SplitWhitespace) -> Result<Game, String> {
let state = position.next().ok_or("Expected startpos or fen")?;
let mut game = match state {
"startpos" => Game::new(),
"fen" => Game::new_from_fen(position.next().ok_or("Expected fen string")?)?,
_ => return Err("Expected startpos or fen".to_string()),
};
for mv_str in position {
let mv = Move::parse_from_str(mv_str)?;
game.board.make_move(mv, game.board.state.next_turn());
}
Ok(game)
}
const MAX_DEPTH: u8 = 5;
pub fn uci_go(mut go: SplitWhitespace, game: &mut Game) -> Response {
let mut params = SearchParameters::new();
while let Some(subcommand) = go.next() {
match subcommand {
"depth" => params.add_depth(go.next().unwrap().parse::<u8>().ok().unwrap()),
"movetime" => params.add_movetime(go.next().unwrap().parse::<usize>().ok().unwrap()),
_ => (),
}
}
search(game, params.depth.unwrap_or(MAX_DEPTH));
Response::BestMove(String::from("value"))
}
#[cfg(test)]
mod tests {
use crate::fen::from_fen;
const FEN: [&str; 1] = ["r3k2r/2p1p1qp/2npb3/1p3p2/p3P1pP/P1PB1Q2/1P1PNPP1/R3K2R w KQkq - 0 1"];
#[test]
fn test_uci_position() -> Result<(), String> {
let mut _game = from_fen(FEN[0])?;
// check that the board state is as expected after using uci position and compare
// with a separate fen that created the update instance by itself
Ok(())
}
}