summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsalmonik <salmonik@tuta.io>2026-08-24 18:11:08 +0200
committersalmonik <salmonik@tuta.io>2026-08-24 18:11:08 +0200
commitfd8ba0d9c7317f24e0b655c6b15ca197d5a23daa (patch)
treed9090d75d559c7f69a62958184db0692e50e9376
parentFix critical game bugs: payout, sessions, balance type, render_lines; add AGE... (diff)
downloadzagan-bet-fd8ba0d9c7317f24e0b655c6b15ca197d5a23daa.tar.gz
zagan-bet-fd8ba0d9c7317f24e0b655c6b15ca197d5a23daa.zip
Fix second-game InvalidAction: reset phase after spin, allow re-spin in Finished state
-rw-r--r--src/bin/client/games/manager.rs11
-rw-r--r--src/bin/client/games/traits.rs2
-rw-r--r--src/bin/client/repl.rs8
3 files changed, 17 insertions, 4 deletions
diff --git a/src/bin/client/games/manager.rs b/src/bin/client/games/manager.rs
index 6959214..0b5b4cb 100644
--- a/src/bin/client/games/manager.rs
+++ b/src/bin/client/games/manager.rs
@@ -55,7 +55,7 @@ impl GameManager {
55 ) -> Result<(), GameError> { 55 ) -> Result<(), GameError> {
56 let game_type = self 56 let game_type = self
57 .pending_game_type 57 .pending_game_type
58 .take() 58 .as_ref()
59 .ok_or(GameError::InvalidAction)?; 59 .ok_or(GameError::InvalidAction)?;
60 60
61 let state = self 61 let state = self
@@ -63,7 +63,7 @@ impl GameManager {
63 .as_mut() 63 .as_mut()
64 .ok_or(GameError::InvalidAction)?; 64 .ok_or(GameError::InvalidAction)?;
65 65
66 if state.phase != GamePhase::WaitingToStart { 66 if state.phase != GamePhase::WaitingToStart && state.phase != GamePhase::Finished {
67 return Err(GameError::InvalidAction); 67 return Err(GameError::InvalidAction);
68 } 68 }
69 69
@@ -103,6 +103,13 @@ impl GameManager {
103 .unwrap_or(false) 103 .unwrap_or(false)
104 } 104 }
105 105
106 pub fn reset_phase_to_waiting(&mut self) {
107 if let Some(ref mut session) = self.current_session {
108 session.phase = GamePhase::WaitingToStart;
109 session.data.clear();
110 }
111 }
112
106 pub fn end_game(&mut self) { 113 pub fn end_game(&mut self) {
107 self.current_session = None; 114 self.current_session = None;
108 self.pending_game_type = None; 115 self.pending_game_type = None;
diff --git a/src/bin/client/games/traits.rs b/src/bin/client/games/traits.rs
index 19f2638..aed0c24 100644
--- a/src/bin/client/games/traits.rs
+++ b/src/bin/client/games/traits.rs
@@ -9,6 +9,8 @@ pub enum GameError {
9#[derive(Debug, Clone, PartialEq)] 9#[derive(Debug, Clone, PartialEq)]
10pub enum GamePhase { 10pub enum GamePhase {
11 WaitingToStart, 11 WaitingToStart,
12 Playing,
13 Finished,
12} 14}
13 15
14#[derive(Debug, Clone)] 16#[derive(Debug, Clone)]
diff --git a/src/bin/client/repl.rs b/src/bin/client/repl.rs
index 91fd10e..dfcf0d2 100644
--- a/src/bin/client/repl.rs
+++ b/src/bin/client/repl.rs
@@ -6,6 +6,7 @@ use std::time::Instant;
6use crate::connection::TlsStream; 6use crate::connection::TlsStream;
7use crate::database; 7use crate::database;
8use crate::games::manager::GameManager; 8use crate::games::manager::GameManager;
9use crate::games::traits::GamePhase;
9 10
10use crossterm::{ 11use crossterm::{
11 cursor::{Hide, MoveToColumn, Show}, 12 cursor::{Hide, MoveToColumn, Show},
@@ -77,12 +78,15 @@ impl ClientState {
77 return true; 78 return true;
78 } 79 }
79 KeyCode::Char(' ') => { 80 KeyCode::Char(' ') => {
80 let should_start = !self.game_manager.is_game_started(); 81 let can_spin = self.game_manager.get_current_state()
81 if should_start { 82 .map(|s| s.phase == GamePhase::WaitingToStart || s.phase == GamePhase::Finished)
83 .unwrap_or(false);
84 if can_spin {
82 if let Some(mut stream) = self.stream.take() { 85 if let Some(mut stream) = self.stream.take() {
83 match self.game_manager.start_game(&mut stream) { 86 match self.game_manager.start_game(&mut stream) {
84 Ok(()) => { 87 Ok(()) => {
85 self.play_spin_animation(&mut stream); 88 self.play_spin_animation(&mut stream);
89 self.game_manager.reset_phase_to_waiting();
86 } 90 }
87 Err(e) => println!("\nError starting game: {:?}", e), 91 Err(e) => println!("\nError starting game: {:?}", e),
88 } 92 }