From 6e2787d792de64c003eff03b62a2df798ef851c0 Mon Sep 17 00:00:00 2001 From: salmonik Date: Thu, 29 Oct 2026 20:43:09 +0100 Subject: v2.3.0: add crash with local multiplier and pushed crash event --- src/client/games/crash.rs | 91 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 src/client/games/crash.rs (limited to 'src/client/games/crash.rs') diff --git a/src/client/games/crash.rs b/src/client/games/crash.rs new file mode 100644 index 0000000..19733f2 --- /dev/null +++ b/src/client/games/crash.rs @@ -0,0 +1,91 @@ +use super::traits::{Game, GameState}; + +pub const CRASH_BOARD_LINES: usize = 6; + +pub struct CrashGame; + +impl CrashGame { + pub fn new() -> Self { + Self + } + + fn value<'a>(state: &'a GameState, key: &str) -> Option<&'a str> { + state.data.get(key).map(String::as_str) + } + + fn status_text(state: &GameState) -> String { + let status = Self::value(state, "status").unwrap_or("ready"); + match status { + "starting" => "Starting...".to_string(), + "running" => "Rising... cash out before it crashes.".to_string(), + "cashed" => format!( + "Cashed out at {}x Won {} PLN", + Self::value(state, "multiplier").unwrap_or("1.00"), + Self::value(state, "payout").unwrap_or("0") + ), + "crashed" => format!( + "CRASHED at {}x Bet lost", + Self::value(state, "crash_point").unwrap_or("?") + ), + "forfeit" => "Forfeited. Bet lost.".to_string(), + _ => "Press [SPACE] to start.".to_string(), + } + } + + fn controls(state: &GameState) -> &'static str { + if Self::value(state, "status") == Some("running") { + "[C] Cash out [Q] Forfeit" + } else { + "[SPACE] Play [+/=/-] Bet [Q] Quit" + } + } +} + +impl Game for CrashGame { + fn get_name(&self) -> &'static str { + "Crash" + } + + fn render(&self, state: &GameState) -> String { + let balance = Self::value(state, "balance").unwrap_or("?"); + let multiplier = Self::value(state, "multiplier").unwrap_or("1.00"); + let potential = Self::value(state, "potential") + .map(str::to_string) + .unwrap_or_else(|| state.bet_amount.to_string()); + + if let Some(error) = Self::value(state, "error") { + return format!( + "=== CRASH ===\r\nBalance: {balance} PLN Bet: {} PLN\r\n\r\nERROR: {error}\r\n\r\n[SPACE] Play [+/=/-] Bet [Q] Quit", + state.bet_amount + ); + } + + format!( + "=== CRASH ===\r\nBalance: {} PLN Bet: {} PLN\r\nMultiplier: {}x\r\nPotential: {} PLN\r\n{}\r\n{}", + balance, + state.bet_amount, + multiplier, + potential, + Self::status_text(state), + Self::controls(state) + ) + } + + fn render_lines(&self, _state: &GameState) -> usize { + CRASH_BOARD_LINES + } + + fn get_help(&self) -> String { + "CRASH\n\ + =====\n\ + The multiplier rises from 1.00x and crashes at a hidden point.\n\ + Cash out before it crashes to win bet x multiplier.\n\ + A round can crash at 1.00x, so an instant cashout still risks the bet.\n\ + \n\ + C - cash out at the server's current multiplier\n\ + SPACE - start the next round\n\ + +/- - change the next round's bet\n\ + Q - forfeit an active round (bet is lost), or leave when idle" + .to_string() + } +} -- cgit v1.2.3