From 86d5f832c8452aad2313489b82eb8fd514215b95 Mon Sep 17 00:00:00 2001 From: salmonik Date: Wed, 28 Oct 2026 22:28:20 +0100 Subject: v0.2.3: add ClientCore and fix the game board rendering --- src/client/games/slots.rs | 58 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 14 deletions(-) (limited to 'src/client/games/slots.rs') diff --git a/src/client/games/slots.rs b/src/client/games/slots.rs index 6e2ebbe..5eed34d 100644 --- a/src/client/games/slots.rs +++ b/src/client/games/slots.rs @@ -1,4 +1,8 @@ -use super::traits::{Game, GameState}; +use super::traits::{Game, GamePhase, GameState}; + +/// Height of the game board. It must never depend on the spin result, or an +/// in-place redraw would move to the wrong line. +pub const SLOT_BOARD_LINES: usize = 7; pub struct SlotsGame; @@ -8,17 +12,36 @@ impl SlotsGame { } fn render_reels(&self, reels: &str) -> String { - if reels.is_empty() { - "[ ? ] [ ? ] [ ? ]".to_string() - } else { - let chars: Vec = reels.chars().collect(); - format!( - "[ {} ] [ {} ] [ {} ]\r", - chars.get(0).unwrap_or(&'?'), - chars.get(1).unwrap_or(&'?'), - chars.get(2).unwrap_or(&'?') - ) + let mut chars = reels.chars(); + format!( + "[ {} ] [ {} ] [ {} ]", + chars.next().unwrap_or('?'), + chars.next().unwrap_or('?'), + chars.next().unwrap_or('?') + ) + } + + /// The fifth board line: current status, result, or error. + fn render_status(&self, state: &GameState) -> String { + if let Some(error) = state.data.get("error") { + return format!("ERROR: {error}"); + } + if state.phase == GamePhase::Playing { + return "Spinning...".to_string(); + } + if state.phase == GamePhase::Finished { + let winnings = state + .data + .get("winnings") + .map(String::as_str) + .unwrap_or("0"); + return match state.data.get("win_type").map(String::as_str) { + Some("jackpot") => format!("JACKPOT! Winnings: {winnings} PLN"), + Some("two") => format!("Two of a kind! Winnings: {winnings} PLN"), + _ => "No win.".to_string(), + }; } + "Press [SPACE] to spin!".to_string() } } @@ -29,16 +52,23 @@ impl Game for SlotsGame { fn render(&self, state: &GameState) -> String { let reels = state.data.get("reels").cloned().unwrap_or_default(); + let balance = state + .data + .get("balance") + .map(String::as_str) + .unwrap_or("?"); format!( - "=== SLOTS ===\r\nBet: {} PLN\r\n{}\r\n\r\nPress [SPACE] to spin!\r\n\r\nControls: [+/-] Adjust Bet [Q] Quit", + "=== SLOTS ===\r\nBet: {} PLN Balance: {} PLN\r\n{}\r\n\r\n{}\r\n\r\n[+/-] Adjust Bet [Q] Quit", state.bet_amount, - self.render_reels(&reels) + balance, + self.render_reels(&reels), + self.render_status(state) ) } fn render_lines(&self, _state: &GameState) -> usize { - 6 + SLOT_BOARD_LINES } fn get_help(&self) -> String { -- cgit v1.2.3