use std::io::{self, BufRead}; use std::collections::BTreeMap; use std::sync::mpsc::{Receiver, Sender}; use std::process::exit; use engine::{EngineMsg, InterfaceMsg, SearchInfo}; use game::{Game}; use log::info; pub fn run(r: Receiver, s: Sender) { //unsafe { debug_log = Box::new(File::open("debug.log").unwrap()); } //unsafe { debug_log = Arc::new(Some(Mutex::new(File::create("~/debug.log").unwrap()))) }; let stdin = io::stdin(); for line_m in stdin.lock().lines() { let line = line_m.unwrap(); info!("received line: {}", line); let split = line.split_whitespace().collect::>(); run_command(split, &r, &s); } } fn run_command(mut cmd: Vec<&str>, r: &Receiver, s: &Sender) { if cmd.len() > 0 { let command = cmd[0]; cmd.drain(0..1); match command { "uci" => cmd_uci(cmd), "isready" => cmd_isready(cmd, r, s), "position" => cmd_position(cmd, r, s), "print" => cmd_print(cmd, r, s), "go" => cmd_go(cmd, r, s), "stop" => cmd_stop(cmd, r, s), "ucinewgame" => cmd_newgame(cmd, r, s), //"setoption" => cmd_setoption(cmd, r, s), "quit" | "exit" => cmd_quit(cmd, r, s), cmd => { println!("unknown command: {}", cmd); } } } } fn cmd_uci(_args: Vec<&str>) { println!("id name bishop 1.0"); println!("id author Geile Siech"); println!("uciok"); } fn cmd_isready(_args: Vec<&str>, _r: &Receiver, s: &Sender) { s.send(EngineMsg::IsReady).unwrap(); } fn cmd_position(mut args: Vec<&str>, _r: &Receiver, s: &Sender) { let position = args[0]; args.drain(0..1); let mut game = Game::default(); if position == "startpos" { } else if position == "fen" { let fen_parts: Vec<&str> = Vec::from(&args[0..6]).into_iter().collect::>(); game = Game::from_fen(fen_parts.as_slice()).unwrap_or_else(|| { info!("invalid fen"); println!("invalid fen"); Game::default() }); args.drain(0..6); } let moves = if args.len() > 0 { if args[0] != "moves" { info!("unexpected {}", args[6]); println!("unexpected {}", args[6]); } args.drain(0..1); args.into_iter().map(|m| String::from(m)).collect::>() } else { Vec::new() }; s.send(EngineMsg::SetBoard{ pos: game, moves }).unwrap(); } fn cmd_print(mut _args: Vec<&str>, _r: &Receiver, s: &Sender) { s.send(EngineMsg::Print).unwrap(); } fn cmd_go(args: Vec<&str>, _r: &Receiver, s: &Sender) { let mut options: BTreeMap = BTreeMap::new(); let mut opt_name: Option<&str> = None; let mut si = SearchInfo::new(); for arg in args { if let Some(on) = opt_name { options.insert(on.to_owned(), arg.to_owned()); opt_name = None; } else if arg == "infinite" { si.infinite = true; } else if arg == "perft" { si.perft = true; } else { opt_name = Some(arg); } } si.movetime = options.get("movetime").map(|x| x.parse::<_>().unwrap_or(0)); si.depth = options.get("depth").map(|x| x.parse::<_>().unwrap_or(0)); si.wtime = options.get("wtime").map(|x| x.parse::<_>().unwrap_or(0)); si.btime = options.get("btime").map(|x| x.parse::<_>().unwrap_or(0)); si.winc = options.get("winc").map(|x| x.parse::<_>().unwrap_or(0)); si.binc = options.get("binc").map(|x| x.parse::<_>().unwrap_or(0)); si.movestogo = options.get("movestogo").map(|x| x.parse::<_>().unwrap_or(0)); s.send(EngineMsg::Search(si)).unwrap(); } fn cmd_stop(_args: Vec<&str>, _r: &Receiver, s: &Sender) { s.send(EngineMsg::Stop).unwrap(); } fn cmd_newgame(_args: Vec<&str>, _r: &Receiver, s: &Sender) { s.send(EngineMsg::NewGame).unwrap(); } fn cmd_quit(_args: Vec<&str>, _r: &Receiver, _s: &Sender) { exit(0); }