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() } }