console_games/
game_center.rs1use std::io::{stdin, stdout, Write};
2
3use console::{style, Term};
4
5use crate::{games::*, Play};
6
7pub struct GameCenter;
8
9impl GameCenter {
10 pub fn games() -> [Box<dyn Play>; 6] {
12 [
13 Box::new(GuessTheWord),
14 Box::new(GuessTheNumber),
15 Box::new(WordType),
16 Box::new(FourInALine),
17 Box::new(TowerOfHanoi),
18 Box::new(MineSweeper),
19 ]
20 }
21
22 pub fn enter() {
24 let term = Term::stdout();
25 term.clear_screen().expect("Failed to clear screen");
26
27 println!("{}\n", style("press ctrl + c to exit").red());
28
29 let mut games = Self::games();
30
31 loop {
32 term.set_title("Console Games");
33 let (game_idx_err_msg, game_idx) = match Self::select_game(&games) {
34 Some(value) => value,
35 None => continue,
36 };
37 println!();
38
39 match games.get_mut(game_idx) {
40 Some(game) => {
41 let name = game.name();
42
43 term.set_title(name);
44 term.clear_screen().expect("Failed to clear screen");
45
46 println!("Welcome to {}!\n", style(name).green());
47 if let Some(instructions) = game.instructions() {
48 println!("{}\n", instructions);
49 }
50
51 game.start();
52 }
53 None => println!("{}", &game_idx_err_msg),
54 };
55 }
56 }
57
58 fn select_game(games: &[Box<dyn Play>]) -> Option<(String, usize)> {
59 println!("{}", style("Select your game").cyan());
60 for (i, game) in games.iter().enumerate() {
61 println!("{}: {}", i, game.name())
62 }
63 print!("Game number: ");
64 stdout().flush().expect("Flush failed");
65
66 let mut game_idx = String::new();
67 stdin()
68 .read_line(&mut game_idx)
69 .expect("Cannot read game number");
70 let game_idx_err_msg = format!(
71 "Game number must be an integer between {} to {}",
72 0,
73 games.len() - 1,
74 );
75 let game_idx: usize = match game_idx.trim_end().parse() {
76 Ok(idx) => idx,
77 Err(_) => {
78 println!("{}", &game_idx_err_msg);
79 return None;
80 }
81 };
82
83 Some((game_idx_err_msg, game_idx))
84 }
85}