summaryrefslogtreecommitdiff
path: root/src/main.rs
blob: 3c29ea36ab3ddadb0438039a039fd0511ae5a489 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
extern crate argparse;
extern crate chrono;

mod consulter;
mod game;
mod gui;
mod parser;

use crate::game::*;
use crate::gui::*;

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 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 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 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 ({} and {}).",
                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)
    } else {
        Game::new(size, &p2_name, &p1_name, &date_string)
    };

    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();
}