aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortslil clingman <>2020-01-27 23:12:51 -0800
committertslil clingman <>2020-01-27 23:12:51 -0800
commit04d6efc6eaf31a3ba8c304884725d3c5e9bab9ae (patch)
treed302225eda75570562d04fed20a6d005d0ef24cc
parent38200848953b1d8d7ba083752c2621603842b54e (diff)
Names, who goes first, date in PTN
-rw-r--r--Cargo.lock54
-rw-r--r--Cargo.toml1
-rw-r--r--src/game.rs27
-rw-r--r--src/gui.rs6
-rw-r--r--src/main.rs85
5 files changed, 137 insertions, 36 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 62ff9fa..be79879 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -6,6 +6,11 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
+name = "autocfg"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
name = "cc"
version = "1.0.49"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -16,6 +21,16 @@ version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
+name = "chrono"
+version = "0.4.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "libc"
version = "0.2.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -39,6 +54,23 @@ dependencies = [
]
[[package]]
+name = "num-integer"
+version = "0.1.42"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "num-traits"
+version = "0.2.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "pancurses"
version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -65,14 +97,30 @@ version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
+name = "redox_syscall"
+version = "0.1.56"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
name = "takwrap"
version = "0.1.0"
dependencies = [
"argparse 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
"pancurses 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
+name = "time"
+version = "0.1.42"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "winapi"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -101,14 +149,20 @@ dependencies = [
[metadata]
"checksum argparse 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3f8ebf5827e4ac4fd5946560e6a99776ea73b596d80898f357007317a7141e47"
+"checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
"checksum cc 1.0.49 (registry+https://github.com/rust-lang/crates.io-index)" = "e450b8da92aa6f274e7c6437692f9f2ce6d701fb73bacfcf87897b3f89a4c20e"
"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
+"checksum chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "31850b4a4d6bae316f7a09e691c944c28299298837edc0a03f755618c23cbc01"
"checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558"
"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
"checksum ncurses 5.99.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15699bee2f37e9f8828c7b35b2bc70d13846db453f2d507713b758fabe536b82"
+"checksum num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba"
+"checksum num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096"
"checksum pancurses 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d3058bc37c433096b2ac7afef1c5cdfae49ede0a4ffec3dfc1df1df0959d0ff0"
"checksum pdcurses-sys 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "084dd22796ff60f1225d4eb6329f33afaf4c85419d51d440ab6b8c6f4529166b"
"checksum pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677"
+"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
+"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
diff --git a/Cargo.toml b/Cargo.toml
index 4d6172b..9a6c10a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -9,3 +9,4 @@ edition = "2018"
[dependencies]
pancurses = "0.16.1"
argparse = "0.2.2"
+chrono = "0.4.10"
diff --git a/src/game.rs b/src/game.rs
index 3c15796..5db2c48 100644
--- a/src/game.rs
+++ b/src/game.rs
@@ -670,14 +670,20 @@ pub struct Game {
size: u8,
current_player: Player,
turn_order: TurnOrder,
- white_player_name: String,
- black_player_name: String,
actions: Vec<Action>,
states: Vec<GameState>,
+ white_player_name: String,
+ black_player_name: String,
+ date_string: String,
}
impl Game {
- pub fn new(size: u8, white_player_name: &str, black_player_name: &str) -> (Game, String) {
+ pub fn new(
+ size: u8,
+ white_player_name: &str,
+ black_player_name: &str,
+ date_str: &str,
+ ) -> (Game, String) {
let (size, warning) = if (size <= 3) || (size >= 8) {
(5, format!("Warning: the requested game size of {}x{} is not supported, defaulting to 5x5.",
size, size))
@@ -688,12 +694,13 @@ impl Game {
(
Game {
size: size,
- white_player_name: white_player_name.to_string(),
- black_player_name: black_player_name.to_string(),
states: vec![GameState::new(size)],
actions: Vec::new(),
current_player: Player::White,
turn_order: TurnOrder::WhitePlacesBlack,
+ white_player_name: white_player_name.to_string(),
+ black_player_name: black_player_name.to_string(),
+ date_string: date_str.to_string(),
},
warning,
)
@@ -709,6 +716,13 @@ impl Game {
self.last_state().query_pos(pos)
}
+ pub fn query_current_player_name(&self) -> &str {
+ match self.current_player {
+ Player::Black => &self.black_player_name,
+ Player::White => &self.white_player_name,
+ }
+ }
+
pub fn query_pieces(&self, player: Player, stone: Stone) -> u8 {
self.last_state().remaining_pieces(player, stone)
}
@@ -826,7 +840,8 @@ impl fmt::Display for Game {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
- "[Date \"\"]\n[Player1 \"{}\"]\n[Player2 \"{}\"]\n[Size \"{}\"]\n{}",
+ "[Date \"{}\"]\n[Player1 \"{}\"]\n[Player2 \"{}\"]\n[Size \"{}\"]\n{}",
+ self.date_string,
self.white_player_name,
self.black_player_name,
self.size,
diff --git a/src/gui.rs b/src/gui.rs
index 1b5f8a2..ed5acb5 100644
--- a/src/gui.rs
+++ b/src/gui.rs
@@ -33,8 +33,7 @@ impl GameLog {
}
pub fn update(&self, game: &Game) {
- // No need to clear, always stays the same size
- self.pieces_window.mv(0, 0);
+ self.pieces_window.clear();
if self.has_colours {
self.pieces_window.attrset(ColorPair(self.white_colour));
@@ -85,15 +84,14 @@ impl GameLog {
if self.has_colours {
self.pieces_window.attrset(ColorPair(self.black_colour));
}
- self.pieces_window.addstr("Black");
}
Player::White => {
if self.has_colours {
self.pieces_window.attrset(ColorPair(self.white_colour));
}
- self.pieces_window.addstr("White");
}
}
+ self.pieces_window.addstr(game.query_current_player_name());
self.pieces_window.refresh();
diff --git a/src/main.rs b/src/main.rs
index 6a2f70a..e46a855 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,4 +1,5 @@
extern crate argparse;
+extern crate chrono;
mod consulter;
mod game;
@@ -11,6 +12,8 @@ use crate::gui::*;
use crate::parser::*;
use argparse::*;
+use chrono::Local;
+use std::env;
use std::io::Error;
use std::time::SystemTime;
@@ -79,10 +82,10 @@ fn init_gui(size: u8) -> GUI {
let action_entry = ActionEntry::new(board_bottom, 0, 13);
let message_log = MessageLog::new(
- board_bottom + 1,
+ board_bottom + 2,
0,
height - board_bottom - 1,
- width,
+ board_right,
has_colours,
red_colour,
);
@@ -116,9 +119,13 @@ fn human_action(gui: &GUI, game: &Game) -> Result<Action, Error> {
}
fn main() {
- let mut p1_name = String::from("Player1");
+ let mut p1_name = match env::var("USER") {
+ Err(_) => String::from("Player1"),
+ Ok(user) => user,
+ };
let mut p2_name = String::from("Player2");
- let mut computer_opponent = String::new();
+ let mut engine = String::new();
+ let mut name = String::new();
let mut size: u8 = 5;
{
@@ -128,25 +135,32 @@ fn main() {
ap.refer(&mut p1_name).add_option(
&["--player1"],
Store,
- "Name of first player, Black/White assignment is still random.",
+ "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, ignored if playing against a
- computer opponent.",
+ "Name of second player, defaults to ``Player2'' and is
+ overridden by the arument ENGINE of --engine when applicable.",
);
- ap.refer(&mut computer_opponent).add_option(
+ 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.",
+ 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,
@@ -161,39 +175,57 @@ fn main() {
ap.parse_args_or_exit();
}
- let human_first;
let call_proc;
- if !computer_opponent.is_empty() {
- p2_name = computer_opponent.clone();
+ if !engine.is_empty() {
+ p2_name = engine.clone();
call_proc = true;
- // Perhaps there's a better way.
- human_first = match SystemTime::now().duration_since(SystemTime::UNIX_EPOCH) {
- Ok(n) => n.as_secs() % 2 == 0,
- Err(_) => false,
- };
+ // Perhaps there's a better way.
} else {
- human_first = false;
call_proc = false;
}
let gui = init_gui(size);
- let (mut game, warning) = Game::new(size, &p1_name, &p2_name);
+ 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 ({} and {}).",
+ name, p1_name, p2_name
+ );
+ }
+ } else {
+ 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)
+ } else {
+ Game::new(size, &p2_name, &p1_name, &date_string)
+ };
gui.message_log.log_error(warning);
gui.game_log.update(&game);
loop {
let inp = match game.query_current_player() {
Player::Black => {
- if call_proc && human_first {
- consult_next_action(&game, &computer_opponent)
+ if call_proc && p1_white {
+ consult_next_action(&game, &engine)
} else {
human_action(&gui, &game)
}
}
Player::White => {
- if call_proc && (!human_first) {
- consult_next_action(&game, &computer_opponent)
+ if call_proc && (!p1_white) {
+ consult_next_action(&game, &engine)
} else {
human_action(&gui, &game)
}
@@ -208,10 +240,11 @@ fn main() {
Ok(act) => {
let stone_owner = game.query_stone_owner();
let player = game.query_current_player();
+ let pn = game.query_current_player_name();
gui.message_log.log_message(format!(
"{} performs {}{}",
- player,
+ pn,
act,
if stone_owner != player {
format!(" with a {} stone.", stone_owner)
@@ -224,8 +257,8 @@ fn main() {
gui.message_log.log_error(e);
let current = game.query_current_player();
if call_proc
- && ((human_first && current == Player::Black)
- || ((!human_first) && current == Player::White))
+ && ((p1_white && current == Player::Black)
+ || ((!p1_white) && current == Player::White))
{
gui.message_log.log_error(String::from(
"Error: external and internal game states disagree.",