summaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
authortslil clingman <>2020-02-01 11:42:12 -0800
committertslil clingman <>2020-02-01 11:42:12 -0800
commit8413caf1d6429bade43a90e4b8d4a662f0fd7deb (patch)
treea36e52e395c071c5865839d66e8377b6d6a22499 /src/main.rs
parent10f615418ebc5cf4a12b82bbcb95a74cbde8c339 (diff)
Features complete for v 0.1.0
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs263
1 files changed, 2 insertions, 261 deletions
diff --git a/src/main.rs b/src/main.rs
index ec8bc7a..3c29ea3 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -6,268 +6,14 @@ mod game;
mod gui;
mod parser;
-use crate::consulter::*;
use crate::game::*;
use crate::gui::*;
-use crate::parser::*;
use argparse::*;
use chrono::Local;
use std::env;
use std::time::SystemTime;
-enum InputSource {
- Player,
- Log,
-}
-
-struct GUI {
- screen: Window,
- game_log: GameLog,
- message_log: MessageLog,
- action_entry: ActionEntry,
- board_gui: BoardGUI,
- input_source: InputSource,
-}
-
-impl GUI {
- fn write_header(&self, header: &str) {
- self.screen.mv(0, 0);
- self.screen.clrtoeol();
- self.screen.addstr(format!(
- "takwrap {} | <TAB> to switch GUI element | {}",
- env!("CARGO_PKG_VERSION").to_string(),
- header
- ));
- self.screen.mvchgat(0, 0, -1, A_REVERSE, -1);
- self.screen.refresh();
- }
-
- fn new(size: u8) -> GUI {
- let screen = initscr();
- cbreak();
- noecho();
- curs_set(2);
-
- let has_colours = has_colors();
- let (black_colour, white_colour, red_colour): (u8, u8, u8) = (1, 2, 3);
-
- if has_colours {
- start_color();
- use_default_colors();
- init_pair(black_colour as i16, -1, COLOR_RED);
- init_pair(white_colour as i16, -1, COLOR_BLUE);
- init_pair(red_colour as i16, COLOR_RED, -1);
- }
-
- let voff = 2;
-
- // let width = screen.get_max_x();
- let height = screen.get_max_y() - voff;
-
- screen.refresh();
-
- let cell_height = 4;
- let cell_width = 8;
- let hoff = 3;
-
- let board_bottom = voff + (size * cell_height + 3) as i32;
- let board_right = (hoff + size * cell_width + 3) as i32;
-
- let board_gui = BoardGUI::new(
- voff,
- 0,
- size,
- cell_height,
- cell_width,
- hoff,
- has_colours,
- white_colour,
- black_colour,
- );
-
- let game_log = GameLog::new(
- voff,
- board_right,
- height - 2,
- 30,
- has_colours,
- white_colour,
- black_colour,
- );
-
- // Need room for '8___011111111', for example
- let action_entry = ActionEntry::new(board_bottom, 0, 13);
-
- let message_log = MessageLog::new(
- board_bottom + 2,
- 0,
- height - board_bottom - 1,
- board_right,
- has_colours,
- red_colour,
- );
-
- GUI {
- screen,
- game_log,
- message_log,
- action_entry,
- board_gui,
- input_source: InputSource::Player,
- }
- }
-
- fn query_input(
- &mut self,
- game: &Game,
- call_proc: bool,
- p1_white: bool,
- engine: &str,
- ) -> Result<GUIResult, String> {
- match self.input_source {
- InputSource::Player => {
- let player = game.query_current_player();
-
- let inp = match player {
- Player::Black => {
- if call_proc && p1_white {
- self.message_log
- .log_message(String::from("Opponent is thinking..."));
- consult_next_action(&game, &engine)
- } else {
- Ok(self.action_entry.read_action())
- }
- }
- Player::White => {
- if call_proc && (!p1_white) {
- self.message_log
- .log_message(String::from("Opponent is thinking..."));
- consult_next_action(&game, &engine)
- } else {
- Ok(self.action_entry.read_action())
- }
- }
- };
-
- match inp {
- Err(e) => Err(format!("Error: {}", e)),
- Ok(ok) => Ok(ok),
- }
- }
- InputSource::Log => Ok(self.game_log.read_action()),
- }
- }
-
- fn handle_input(
- &mut self,
- game: &mut Game,
- call_proc: bool,
- p1_white: bool,
- input: Result<GUIResult, String>,
- ) -> bool {
- let player = game.query_current_player();
- let engine_turn = call_proc
- && ((p1_white && player == Player::Black) || ((!p1_white) && player == Player::White));
-
- match input {
- Err(e) => {
- if engine_turn {
- self.message_log
- .log_error(format!("Unrecoverable error: {}", e));
- return false;
- }
- }
- Ok(gui_result) => match gui_result {
- GUIResult::Quit => {
- self.message_log
- .log_message(String::from("Press any key to quit."));
- return false;
- }
- GUIResult::SwitchElement => match self.input_source {
- InputSource::Player => {
- self.input_source = InputSource::Log;
- self.write_header(LOG_HEADER);
- }
- InputSource::Log => {
- self.input_source = InputSource::Player;
- self.write_header(ACTION_HEADER);
- }
- },
- GUIResult::Undo => match game.undo() {
- Ok(pos_vec) => {
- self.message_log
- .log_message(String::from("Game undone by one turn."));
- self.board_gui.update(&game, pos_vec);
- self.game_log.update(&game);
- }
- Err(err) => {
- self.message_log.log_error(err);
- }
- },
- GUIResult::Raw(raw) => {
- let stone_owner = game.query_stone_owner();
- let act = parse_action(stone_owner, &raw);
- match act {
- Err(err) => {
- self.message_log
- .log_error(format!("Input \"{}\": {}", raw, err));
- if engine_turn {
- return false;
- }
- }
- Ok(act) => {
- let pn = game.query_current_player_name();
- self.message_log.log_message(format!(
- "{} performs {}{}",
- pn,
- act,
- if stone_owner != player {
- format!(" with a {} stone.", stone_owner)
- } else {
- String::from(".")
- }
- ));
- let act_string = act.to_string();
- match game.perform_action(act) {
- Err(e) => {
- if engine_turn {
- self.message_log.log_error(String::from(
- "Error: external and internal game states disagree. Press any key to quit.",
- ));
- return false;
- } else {
- self.message_log.log_error(format!(
- "Cannot perform \"{}\": {}",
- act_string, e
- ));
- }
- }
-
- Ok((pos_vec, win)) => {
- self.board_gui.update(&game, pos_vec);
- self.game_log.update(&game);
- if let Some(w) = win {
- self.message_log.log_message(format!(
- "Game over: {}\nPress any key to quit.",
- w
- ));
- return false;
- }
- }
- }
- }
- }
- }
- },
- }
- return true;
- }
-}
-
-const ACTION_HEADER: &str = "Enter action in PTN";
-const LOG_HEADER: &str = "U to undo a turn | <UP>/<DOWN> to scroll | Q to quit";
-
fn main() {
let mut p1_name = match env::var("USER") {
Err(_) => String::from("Player1"),
@@ -329,13 +75,10 @@ fn main() {
if !engine.is_empty() {
p2_name = engine.clone();
call_proc = true;
- // Perhaps there's a better way.
} else {
call_proc = false;
}
- let mut gui = GUI::new(size);
-
let p1_white;
if !name.is_empty() {
if name == p1_name {
@@ -349,6 +92,7 @@ fn main() {
);
}
} else {
+ // Very random choice
p1_white = match SystemTime::now().duration_since(SystemTime::UNIX_EPOCH) {
Ok(n) => n.as_millis() % 2 == 0,
Err(_) => false,
@@ -361,15 +105,12 @@ fn main() {
} else {
Game::new(size, &p2_name, &p1_name, &date_string)
};
- gui.message_log.log_error(warning);
- gui.game_log.update(&game);
- gui.write_header(ACTION_HEADER);
+ 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) {
- gui.screen.getch();
break;
}
}