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
121
122
123
124
125
126
127
|
use crate::games::slots::SlotsGame;
use crate::games::traits::{Game, GameError, GamePhase, GameState};
use std::collections::HashMap;
use std::io::Write;
pub struct GameManager {
current_session: Option<GameState>,
pending_game_type: Option<String>,
games: HashMap<String, Box<dyn Game>>,
}
impl GameManager {
pub fn new() -> Self {
let mut games: HashMap<String, Box<dyn Game>> = HashMap::new();
games.insert("slots".to_string(), Box::new(SlotsGame::new()));
Self {
current_session: None,
pending_game_type: None,
games,
}
}
pub fn get_available_games(&self) -> Vec<(&str, &str)> {
self.games
.iter()
.map(|(k, v)| (k.as_str(), v.get_name()))
.collect()
}
pub fn enter_game(&mut self, game_type: &str) -> Result<(), GameError> {
if self.current_session.is_some() {
return Err(GameError::InvalidAction);
}
if !self.games.contains_key(game_type) {
return Err(GameError::InvalidAction);
}
self.pending_game_type = Some(game_type.to_string());
self.current_session = Some(GameState {
game_type: game_type.to_string(),
bet_amount: 10,
phase: GamePhase::WaitingToStart,
data: HashMap::new(),
});
Ok(())
}
pub fn start_game(
&mut self,
stream: &mut crate::connection::TlsStream,
) -> Result<(), GameError> {
let game_type = self
.pending_game_type
.take()
.ok_or(GameError::InvalidAction)?;
let state = self
.current_session
.as_mut()
.ok_or(GameError::InvalidAction)?;
if state.phase != GamePhase::WaitingToStart {
return Err(GameError::InvalidAction);
}
let bet_amount = state.bet_amount;
let writer = stream;
writeln!(writer, "PLAY_START {} {}", game_type, bet_amount)
.map_err(|_| GameError::NetworkError)?;
Ok(())
}
pub fn get_current_game(&self) -> Option<&dyn Game> {
self.current_session
.as_ref()
.and_then(|session| self.games.get(&session.game_type).map(|game| game.as_ref()))
}
pub fn get_current_state(&self) -> Option<&GameState> {
self.current_session.as_ref()
}
pub fn get_current_render_lines(&self) -> Option<usize> {
let session = self.current_session.as_ref()?;
let game = self.games.get(&session.game_type)?;
Some(game.render_lines(session))
}
pub fn is_in_game(&self) -> bool {
self.current_session.is_some()
}
pub fn is_game_started(&self) -> bool {
self.current_session
.as_ref()
.map(|s| s.phase != GamePhase::WaitingToStart)
.unwrap_or(false)
}
pub fn end_game(&mut self) {
self.current_session = None;
self.pending_game_type = None;
}
pub fn adjust_bet(&mut self, delta: i64) -> Result<u64, GameError> {
if let Some(ref session) = self.current_session {
if session.phase != GamePhase::WaitingToStart {
return Err(GameError::InvalidAction);
}
}
if let Some(ref mut session) = self.current_session {
let current_bet = session.bet_amount as i64;
let new_bet = (current_bet + delta).max(10) as u64;
session.bet_amount = new_bet;
Ok(new_bet)
} else {
Err(GameError::InvalidAction)
}
}
}
|