summaryrefslogtreecommitdiffstats
path: root/src/client/games/manager.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/games/manager.rs')
-rw-r--r--src/client/games/manager.rs131
1 files changed, 131 insertions, 0 deletions
diff --git a/src/client/games/manager.rs b/src/client/games/manager.rs
new file mode 100644
index 0000000..be96b1a
--- /dev/null
+++ b/src/client/games/manager.rs
@@ -0,0 +1,131 @@
1use super::slots::SlotsGame;
2use super::traits::{Game, GameError, GamePhase, GameState};
3use std::collections::HashMap;
4use std::io::Write;
5
6pub struct GameManager {
7 current_session: Option<GameState>,
8 pending_game_type: Option<String>,
9 games: HashMap<String, Box<dyn Game>>,
10}
11
12impl GameManager {
13 pub fn new() -> Self {
14 let mut games: HashMap<String, Box<dyn Game>> = HashMap::new();
15 games.insert("slots".to_string(), Box::new(SlotsGame::new()));
16
17 Self {
18 current_session: None,
19 pending_game_type: None,
20 games,
21 }
22 }
23
24 pub fn get_available_games(&self) -> Vec<(&str, &str)> {
25 self.games
26 .iter()
27 .map(|(k, v)| (k.as_str(), v.get_name()))
28 .collect()
29 }
30
31 pub fn enter_game(&mut self, game_type: &str) -> Result<(), GameError> {
32 if self.current_session.is_some() {
33 return Err(GameError::InvalidAction);
34 }
35
36 if !self.games.contains_key(game_type) {
37 return Err(GameError::InvalidAction);
38 }
39
40 self.pending_game_type = Some(game_type.to_string());
41
42 self.current_session = Some(GameState {
43 game_type: game_type.to_string(),
44 bet_amount: 10,
45 phase: GamePhase::WaitingToStart,
46 data: HashMap::new(),
47 });
48
49 Ok(())
50 }
51
52 pub fn start_game<W: Write>(&mut self, stream: &mut W) -> Result<(), GameError> {
53 let game_type = self
54 .pending_game_type
55 .as_ref()
56 .ok_or(GameError::InvalidAction)?;
57
58 let state = self
59 .current_session
60 .as_mut()
61 .ok_or(GameError::InvalidAction)?;
62
63 if state.phase != GamePhase::WaitingToStart && state.phase != GamePhase::Finished {
64 return Err(GameError::InvalidAction);
65 }
66
67 let bet_amount = state.bet_amount;
68
69 let writer = stream;
70 writeln!(writer, "PLAY_START {} {}", game_type, bet_amount)
71 .map_err(|_| GameError::NetworkError)?;
72
73 Ok(())
74 }
75
76 pub fn get_current_game(&self) -> Option<&dyn Game> {
77 self.current_session
78 .as_ref()
79 .and_then(|session| self.games.get(&session.game_type).map(|game| game.as_ref()))
80 }
81
82 pub fn get_current_state(&self) -> Option<&GameState> {
83 self.current_session.as_ref()
84 }
85
86 pub fn get_current_render_lines(&self) -> Option<usize> {
87 let session = self.current_session.as_ref()?;
88 let game = self.games.get(&session.game_type)?;
89 Some(game.render_lines(session))
90 }
91
92 pub fn is_in_game(&self) -> bool {
93 self.current_session.is_some()
94 }
95
96 pub fn is_game_started(&self) -> bool {
97 self.current_session
98 .as_ref()
99 .map(|s| s.phase != GamePhase::WaitingToStart)
100 .unwrap_or(false)
101 }
102
103 pub fn reset_phase_to_waiting(&mut self) {
104 if let Some(ref mut session) = self.current_session {
105 session.phase = GamePhase::WaitingToStart;
106 session.data.clear();
107 }
108 }
109
110 pub fn end_game(&mut self) {
111 self.current_session = None;
112 self.pending_game_type = None;
113 }
114
115 pub fn adjust_bet(&mut self, delta: i64) -> Result<u64, GameError> {
116 if let Some(ref session) = self.current_session {
117 if session.phase != GamePhase::WaitingToStart {
118 return Err(GameError::InvalidAction);
119 }
120 }
121
122 if let Some(ref mut session) = self.current_session {
123 let current_bet = session.bet_amount as i64;
124 let new_bet = (current_bet + delta).max(10) as u64;
125 session.bet_amount = new_bet;
126 Ok(new_bet)
127 } else {
128 Err(GameError::InvalidAction)
129 }
130 }
131}