connect4_lib/
games.rs

1use crate::ai::*;
2use crate::game::{check_linear_pattern, Board, Checker, ChipDescrip, Game, Player, PlayerType};
3use crate::io::{BLK, BLU, BRIGHTEN, FILLED, RED, YEL};
4use std::rc::Rc;
5
6pub enum GameType {
7    Connect4,
8    Toto,
9}
10
11pub fn four_in_a_row(chip: ChipDescrip) -> Vec<ChipDescrip> {
12    vec![chip; 4]
13}
14
15pub fn wrap_4_check(chip: ChipDescrip, chip_inner: ChipDescrip) -> Vec<ChipDescrip> {
16    vec![chip, chip_inner, chip_inner, chip]
17}
18
19pub fn is_connect4(game: &Game) -> bool {
20    // TODO: this doesn't ensure that the win conditions match
21    game.get_board().width == 7
22        && game.get_board().height == 6
23        && game.get_player_count() == 2
24        && game.get_player(0).win_conditions.len() == 1
25        && game.get_player(1).win_conditions.len() == 1
26        && game.get_player(0).chip_options.len() == 1
27        && game.get_player(1).chip_options.len() == 1
28        && game.get_player(0).chip_options[0] == RED_CHIP
29        && game.get_player(1).chip_options[0] == YELLOW_CHIP
30}
31
32pub fn is_toto(game: &Game) -> bool {
33    // TODO: this doesn't ensure that the win conditions match
34    game.get_board().width == 6
35        && game.get_board().height == 4
36        && game.get_player_count() == 2
37        && game.get_player(0).win_conditions.len() == 1
38        && game.get_player(1).win_conditions.len() == 1
39        && game.get_player(0).chip_options.len() == 2
40        && game.get_player(1).chip_options.len() == 2
41        && game.get_player(0).chip_options[0] == T_CHIP
42        && game.get_player(0).chip_options[1] == O_CHIP
43        && game.get_player(1).chip_options[0] == T_CHIP
44        && game.get_player(1).chip_options[1] == O_CHIP
45}
46
47pub const RED_CHIP: ChipDescrip = ChipDescrip {
48    bg_color: BLK as isize + BRIGHTEN as isize,
49    fg_color: RED as isize,
50    graphic: FILLED,
51};
52pub const YELLOW_CHIP: ChipDescrip = ChipDescrip {
53    bg_color: BLK as isize + BRIGHTEN as isize,
54    fg_color: YEL as isize,
55    graphic: FILLED,
56};
57pub const BLUE_CHIP: ChipDescrip = ChipDescrip {
58    bg_color: BLK as isize + BRIGHTEN as isize,
59    fg_color: BLU as isize,
60    graphic: FILLED,
61};
62
63pub const T_CHIP: ChipDescrip = ChipDescrip {
64    bg_color: BLK as isize + BRIGHTEN as isize,
65    fg_color: RED as isize,
66    graphic: 't',
67};
68pub const O_CHIP: ChipDescrip = ChipDescrip {
69    bg_color: BLK as isize + BRIGHTEN as isize,
70    fg_color: YEL as isize,
71    graphic: 'o',
72};
73
74pub fn connect4_large_ai() -> Game {
75    let board = Board::new(14, 10);
76
77    let players = vec![
78        Player {
79            player_type: PlayerType::AI(MID_AI),
80            chip_options: vec![RED_CHIP],
81            win_conditions: vec![four_in_a_row(RED_CHIP)],
82        },
83        Player {
84            player_type: PlayerType::Local,
85            chip_options: vec![YELLOW_CHIP],
86            win_conditions: vec![four_in_a_row(YELLOW_CHIP)],
87        },
88    ];
89
90    Game::new(board, players)
91}
92
93pub fn connect4_ai() -> Game {
94    let board = Board::new(7, 6);
95
96    let players = vec![
97        Player {
98            player_type: PlayerType::AI(HARD_AI),
99            chip_options: vec![RED_CHIP],
100            win_conditions: vec![four_in_a_row(RED_CHIP)],
101        },
102        Player {
103            player_type: PlayerType::Local,
104            chip_options: vec![YELLOW_CHIP],
105            win_conditions: vec![four_in_a_row(YELLOW_CHIP)],
106        },
107    ];
108
109    Game::new(board, players)
110}
111
112pub fn connect4_ai_p2() -> Game {
113    let board = Board::new(7, 6);
114
115    let players = vec![
116        Player {
117            player_type: PlayerType::Local,
118            chip_options: vec![RED_CHIP],
119            win_conditions: vec![four_in_a_row(RED_CHIP)],
120        },
121        Player {
122            player_type: PlayerType::AI(HARD_AI),
123            chip_options: vec![YELLOW_CHIP],
124            win_conditions: vec![four_in_a_row(YELLOW_CHIP)],
125        },
126    ];
127
128    Game::new(board, players)
129}
130
131pub fn connect4() -> Game {
132    connect4_custom(PlayerType::Local, PlayerType::Local)
133}
134
135pub fn connect4_custom(player1_type: PlayerType, player2_type: PlayerType) -> Game {
136    let board = Board::new(7, 6);
137
138    let players = vec![
139        Player {
140            player_type: player1_type,
141            chip_options: vec![RED_CHIP],
142            win_conditions: vec![four_in_a_row(RED_CHIP)],
143        },
144        Player {
145            player_type: player2_type,
146            chip_options: vec![YELLOW_CHIP],
147            win_conditions: vec![four_in_a_row(YELLOW_CHIP)],
148        },
149    ];
150
151    Game::new(board, players)
152}
153
154pub fn toto_ai() -> Game {
155    let board = Board::new(6, 4);
156
157    let players = vec![
158        Player {
159            player_type: PlayerType::AI(HARD_AI),
160            chip_options: vec![T_CHIP, O_CHIP],
161            win_conditions: vec![wrap_4_check(T_CHIP, O_CHIP)],
162        },
163        Player {
164            player_type: PlayerType::Local,
165            chip_options: vec![T_CHIP, O_CHIP],
166            win_conditions: vec![wrap_4_check(O_CHIP, T_CHIP)],
167        },
168    ];
169
170    Game::new(board, players)
171}
172
173pub fn toto() -> Game {
174    toto_custom(PlayerType::Local, PlayerType::Local)
175}
176
177pub fn toto_custom(player1_type: PlayerType, player2_type: PlayerType) -> Game {
178    let board = Board::new(6, 4);
179
180    let players = vec![
181        Player {
182            player_type: player1_type,
183            chip_options: vec![T_CHIP, O_CHIP],
184            win_conditions: vec![wrap_4_check(T_CHIP, O_CHIP)],
185        },
186        Player {
187            player_type: player2_type,
188            chip_options: vec![T_CHIP, O_CHIP],
189            win_conditions: vec![wrap_4_check(O_CHIP, T_CHIP)],
190        },
191    ];
192
193    Game::new(board, players)
194}
195
196pub fn connect4_3player() -> Game {
197    let board = Board::new(9, 7);
198
199    let players = vec![
200        Player {
201            player_type: PlayerType::Local,
202            chip_options: vec![RED_CHIP],
203            win_conditions: vec![four_in_a_row(RED_CHIP)],
204        },
205        Player {
206            player_type: PlayerType::Local,
207            chip_options: vec![YELLOW_CHIP],
208            win_conditions: vec![four_in_a_row(YELLOW_CHIP)],
209        },
210        Player {
211            player_type: PlayerType::Local,
212            chip_options: vec![BLUE_CHIP],
213            win_conditions: vec![four_in_a_row(BLUE_CHIP)],
214        },
215    ];
216
217    Game::new(board, players)
218}
219
220pub fn build_game(game_type: GameType, player1_type: PlayerType, player2_type: PlayerType) -> Game {
221    match game_type {
222        GameType::Connect4 => connect4_custom(player1_type, player2_type),
223        GameType::Toto => toto_custom(player1_type, player2_type),
224    }
225}
226
227#[cfg(test)]
228mod test {
229    //use super::*;
230
231    #[test]
232    fn test_is_connect4() {}
233
234    #[test]
235    fn test_is_toto() {}
236}