use crate::{api, usr, sys}; use crate::api::console::Style; use crate::api::prompt::Prompt; use alloc::format; use alloc::string::String; use alloc::sync::Arc; use alloc::vec::Vec; use littlewing::chess::*; use lazy_static::lazy_static; use spin::Mutex; lazy_static! { static ref MOVES: Mutex> = Mutex::new(Vec::new()); } const FEN: &str = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"; const COMMANDS: [&str; 8] = ["quit", "help", "init", "time", "move", "undo", "show", "perf"]; fn update_autocomplete(prompt: &mut Prompt, game: &mut Game) { *MOVES.lock() = game.get_moves().into_iter().map(|m| m.to_lan()).collect(); fn chess_completer(line: &str) -> Vec { let mut entries = Vec::new(); let args: Vec<&str> = line.split(' ').collect(); let i = args.len() - 1; if i == 0 { // Autocomplete command for &cmd in &COMMANDS { if let Some(entry) = cmd.strip_prefix(args[i]) { entries.push(entry.into()); } } } else if i == 1 && (args[0] == "move" || args[0] == "m") { // Autocomplete moves for m in &*MOVES.lock() { if let Some(entry) = m.strip_prefix(args[1]) { entries.push(entry.into()); } } } entries } prompt.completion.set(&chess_completer); } fn system_time() -> u128 { (api::syscall::realtime() * 1000.0) as u128 } struct Chess { game: Game, csi_color: Style, csi_error: Style, csi_notif: Style, csi_reset: Style, } impl Chess { fn new() -> Self { Self { game: Game::new(), csi_color: Style::color("Cyan"), csi_error: Style::color("LightRed"), csi_notif: Style::color("Yellow"), csi_reset: Style::reset(), } } fn play(&mut self) { println!("MOROS Chess v0.1.0\n"); let prompt_string = format!("{}>{} ", self.csi_color, self.csi_reset); let mut prompt = Prompt::new(); let history_file = "~/.chess-history"; prompt.history.load(history_file); self.game.show_coordinates = true; self.game.clock = Clock::new(40, 5 * 60 * 1000); // 40 moves in 5 minutes self.game.clock.system_time = Arc::new(system_time); let size = 1 << 20; // MB self.game.tt_resize(size); self.game.load_fen(FEN).unwrap(); println!("{}", self.game); update_autocomplete(&mut prompt, &mut self.game); while let Some(cmd) = prompt.input(&prompt_string) { let args: Vec<&str> = cmd.trim().split(' ').collect(); match args[0] { "q" | "quit" | "exit" => break, "h" | "help" => self.cmd_help(args), "i" | "init" => self.cmd_init(args), "t" | "time" => self.cmd_time(args), "m" | "move" => self.cmd_move(args), "u" | "undo" => self.cmd_undo(args), "p" | "perf" => self.cmd_perf(args), //"s" | "show" => self.cmd_show(args), cmd => { if cmd.is_empty() { println!(); } else { println!("{}Error:{} unknown command '{}'\n", self.csi_error, self.csi_reset, cmd); } } } prompt.history.add(&cmd); prompt.history.save(history_file); update_autocomplete(&mut prompt, &mut self.game); } } fn cmd_help(&mut self, _args: Vec<&str>) { println!("{}Commands:{}", self.csi_notif, self.csi_reset); let cmds = [ ("q", "uit", "Exit this program\n"), ("h", "elp", "Display this screen\n"), ("i", "nit", "Initialize a new game\n"), ("t", "ime