extern crate argparse; extern crate chrono; mod consulter; mod game; mod gui; mod parser; use crate::game::*; use crate::gui::*; use crate::parser::parse_start_type; use argparse::*; use chrono::Local; use std::env; use std::time::SystemTime; fn main() { let mut p1_name = match env::var("USER") { Err(_) => String::from("Player1"), Ok(user) => user, }; let mut p2_name = String::from("Player2"); let mut engine = String::new(); let mut name = String::new(); let mut size: u8 = 5; let mut start_type_string = String::new(); { let mut ap = ArgumentParser::new(); ap.set_description("Test description."); ap.refer(&mut p1_name).add_option( &["--player1"], Store, "Name of first player, defaults to $USER. See --name-white below for Black/White assignment.", ); ap.refer(&mut p2_name).add_option( &["--player2"], Store, "Name of second player, defaults to ``Player2'' and is overridden by the arument ENGINE of --engine when applicable.", ); ap.refer(&mut start_type_string) .add_option( &["-v", "--variant-start"], Store, "Select the rule variant for the start of play. Valid choices are CPSn, FCS, FES, TPS, and CZS. The default starting type, which matches the original rules, is CPS2.", ) .metavar("VRNT"); ap.refer(&mut engine).add_option( &["-e", "--engine"], Store, "Name of process which will be used as a computer opponent. The process must accept a single argument point to a PTN file of the current game state, and must generate a single PTN action on STDOUT. The engine will replace the second player, and the name of player 2 is set to this argument.", ); ap.refer(&mut name).add_option( &["--name-white"], Store, "Force the player named NAME to play white. If not supplied, assignment is ``random''.", ).metavar("NAME"); ap.refer(&mut size).add_option( &["-s", "--size"], Store, "Size of board (one dimension), default is 5.", ); ap.add_option( &["-V", "--version"], Print(env!("CARGO_PKG_VERSION").to_string()), "Show version", ); ap.parse_args_or_exit(); } let start_type; if !start_type_string.is_empty() { match parse_start_type(&start_type_string) { Err(e) => panic!("Invalid start rule variant provided: {}", e), Ok(st) => start_type = st, } } else { start_type = StartType::CPS(2); } let call_proc; if !engine.is_empty() { p2_name = engine.clone(); call_proc = true; } else { call_proc = false; } let p1_white; if !name.is_empty() { if name == p1_name { p1_white = true; } else if name == p2_name { p1_white = false; } else { panic!( "Player named as white ({}) is not a player in this game (only ``{}'' and ``{}'' are).", name, p1_name, p2_name ); } } else { // Very random choice p1_white = match SystemTime::now().duration_since(SystemTime::UNIX_EPOCH) { Ok(n) => n.as_millis() % 2 == 0, Err(_) => false, }; } let date_string = Local::now().to_string(); let (mut game, warning) = if p1_white { Game::new(size, &p1_name, &p2_name, &date_string, start_type) } else { Game::new(size, &p2_name, &p1_name, &date_string, start_type) }; let mut gui = GUI::new(&game, warning); loop { let inp = gui.query_input(&game, call_proc, p1_white, &engine); if !gui.handle_input(&mut game, call_proc, p1_white, inp) { break; } } // board_gui.read_action(); endwin(); }