use std::{io::stdin, thread::{Builder, JoinHandle}, str::Split}; use crate::{board::{Board, io::IO}, moves::Move}; use super::Grossmeister; const NAME: &str = "Chessnost"; const AUTHOR: &str = "Eugene Sokolov"; impl Grossmeister { pub fn start(&mut self) { let mut search_handle = None; loop { let mut cmd = String::new(); stdin().read_line(&mut cmd).unwrap(); let mut tokens = cmd.trim().split(' '); if let Some(token) = tokens.next() { match token { "uci" => { println!("id name {}", NAME); println!("id author {}", AUTHOR); println!("uciok"); } "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); }, } }; } "isready" => { println!("readyok"); } "setoption" => { todo!() } "ucinewgame" => { // TODO: clear transposition table } "position" => { if let Some(token) = tokens.next() { match token { "startpos" => { self.board = Board::new(); 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") } } "go" => { search_handle = Some(self.parse_go(tokens)); } "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); } "ponderhit" => todo!(), "quit" => break, _ => {}, } } } } fn parse_go(&mut self, mut tokens: Split) -> JoinHandle { if let Some(token) = tokens.next() { match token { "searchmoves" => todo!(), "ponder" => todo!(), "wtime" => {} "btime" => {} "winc" => {} "binc" => {} "movestogo" => {} "depth" => { if let Some(depth) = tokens.next() { let depth: u8 = depth.parse().unwrap(); return self.create_search_thread(depth); } }, "nodes" => todo!(), "mate" => todo!(), "movetime" => todo!(), "infinite" => { return self.create_search_thread(u8::MAX); }, _ => {} } return self.parse_go(tokens) } self.create_search_thread(6) } fn create_search_thread(&self, depth: u8) -> JoinHandle { // Clone current self and move it // into thread to analyze a position let mut gm = self.clone(); let builder = Builder::new(); builder.spawn(move || { gm.iterative_deepening(depth); gm }).unwrap() } }