tictactoe_rust/game/
mod.rs

1use super::board::Board;
2pub struct Game {
3    config: Config,
4    board: Board,
5}
6
7impl Game {
8    pub fn start(&mut self) {
9        use super::interface;
10        interface::ask_and_run_command(&mut self.config, &mut self.board);
11    }
12
13    pub fn text_print_board(board: &Board, config: &Config) {
14        let spaces = " ".repeat(2);
15        for (i, player) in board.board.iter().enumerate() {
16            let cell: &str = match player {
17                Some(Players::Player1) => config.players.0.piece.as_str(),
18                Some(Players::Player2) => config.players.1.piece.as_str(),
19                None => config.empty_piece.as_str(),
20            };
21
22            if (i + 1) % 3 == 0 {
23                println!("{}", cell);
24            } else if i % 3 == 0 {
25                print!("{}{}|", spaces, cell);
26            } else {
27                print!("{}|", cell);
28            }
29        }
30    }
31
32    pub fn new(mode: Mode) -> Game {
33        Game {
34            config: Config::new(mode),
35            board: Default::default(),
36        }
37    }
38}
39
40impl Default for Game {
41    fn default() -> Game {
42        Game {
43            config: Config::new(Mode::PVC),
44            board: Default::default(),
45        }
46    }
47}
48
49pub struct Config {
50    pub mode: Mode,
51    pub players: (Player, Player),
52    pub first: Players,
53    pub empty_piece: String,
54    pub ai_smartness: SmartLevel,
55}
56
57impl Config {
58    pub fn new(mode: Mode) -> Config {
59        match mode {
60            Mode::PVC => Config {
61                mode: Mode::PVC,
62                players: (
63                    Player {
64                        name: String::from("User1"),
65                        piece: String::from("X"),
66                        is_ai: false,
67                    },
68                    Player {
69                        name: String::from("AI1"),
70                        piece: String::from("O"),
71                        is_ai: true,
72                    },
73                ),
74                first: Players::Player1,
75                empty_piece: String::from("."),
76                ai_smartness: SmartLevel::Elementary,
77            },
78            Mode::PVP => Config {
79                mode: Mode::PVP,
80                players: (
81                    Player {
82                        name: String::from("User1"),
83                        piece: String::from("X"),
84                        is_ai: false,
85                    },
86                    Player {
87                        name: String::from("User2"),
88                        piece: String::from("O"),
89                        is_ai: false,
90                    },
91                ),
92                first: Players::Player1,
93                empty_piece: String::from("."),
94                ai_smartness: SmartLevel::Elementary,
95            },
96            Mode::CVC => Config {
97                mode: Mode::CVC,
98                players: (
99                    Player {
100                        name: String::from("AI1"),
101                        piece: String::from("X"),
102                        is_ai: true,
103                    },
104                    Player {
105                        name: String::from("AI2"),
106                        piece: String::from("O"),
107                        is_ai: true,
108                    },
109                ),
110                first: Players::Player1,
111                empty_piece: String::from("."),
112                ai_smartness: SmartLevel::Elementary,
113            },
114        }
115    }
116}
117
118impl Config {
119    pub fn text_print_config(&self, with_number: bool) {
120        let prefixs: [&str; 6] = if with_number {
121            ["  "; 6]
122        } else {
123            ["  [1] ", "  [2] ", "  [3] ", "  [4] ", "  [5] ", "  [6] "]
124        };
125
126        println!("{}Mode: {}", prefixs[0], self.mode);
127        println!(
128            "{}Player1 ({}): \"{}\"",
129            prefixs[1], self.players.0.name, self.players.0.piece
130        );
131        println!(
132            "{}Player2 ({}): \"{}\"",
133            prefixs[2], self.players.1.name, self.players.1.piece
134        );
135        println!("{}Whose turn first: {}", prefixs[3], self.first);
136        println!("{}Ai smartness Level: {}", prefixs[4], self.ai_smartness);
137        println!("{}Empty piece: \"{}\"", prefixs[5], self.empty_piece);
138    }
139
140    pub fn text_print_player_page_config(&self) {
141        println!("  [1] Player1 name: {}", self.players.0.name);
142        println!("  [2] Player2 name: {}", self.players.1.name);
143        println!("  [3] Player1 piece: {}", self.players.0.piece);
144        println!("  [4] Player2 piece: {}", self.players.1.piece);
145    }
146}
147
148#[derive(Clone, Copy)]
149pub enum Mode {
150    PVP,
151    PVC,
152    CVC,
153}
154
155pub struct Player {
156    pub name: String,
157    pub piece: String,
158    pub is_ai: bool,
159}
160
161#[derive(Clone, Copy, PartialEq, Debug)]
162pub enum Players {
163    Player1,
164    Player2,
165}
166
167#[derive(Debug, Clone, Copy)]
168pub enum SmartLevel {
169    Kindergarden,
170    Elementary,
171    Graduate,
172    God,
173}
174
175use std::fmt;
176impl fmt::Display for Mode {
177    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
178        write!(
179            f,
180            "{}",
181            match &self {
182                Mode::PVP => "PVP",
183                Mode::PVC => "PVC",
184                Mode::CVC => "CVC",
185            }
186        )
187    }
188}
189
190impl fmt::Display for SmartLevel {
191    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
192        write!(
193            f,
194            "{}",
195            match &self {
196                SmartLevel::Kindergarden => "Kindergarden",
197                SmartLevel::Elementary => "Elementary",
198                SmartLevel::Graduate => "Graduate",
199                SmartLevel::God => "God",
200            }
201        )
202    }
203}
204
205impl fmt::Display for Players {
206    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
207        write!(
208            f,
209            "{}",
210            match &self {
211                Players::Player1 => "Player1",
212                Players::Player2 => "Player2",
213            }
214        )
215    }
216}
217
218#[cfg(test)]
219mod tests;