From 2915d826f744612e0d975282f5bddf13270b9f3f Mon Sep 17 00:00:00 2001 From: salmonik Date: Wed, 28 Oct 2026 23:19:52 +0100 Subject: v1.1.0: highlight winning symbols on the slots board --- src/client/games/manager.rs | 11 +++++++++++ src/client/games/response.rs | 18 +++++++++++++----- src/client/games/slots.rs | 29 ++++++++++++++++++++++++----- 3 files changed, 48 insertions(+), 10 deletions(-) (limited to 'src/client') diff --git a/src/client/games/manager.rs b/src/client/games/manager.rs index 8436142..168c49d 100644 --- a/src/client/games/manager.rs +++ b/src/client/games/manager.rs @@ -76,6 +76,7 @@ impl GameManager { session.data.remove("reels"); session.data.remove("win_type"); session.data.remove("win_lines"); + session.data.remove("win_cells"); session.data.remove("winnings"); Ok(()) } @@ -101,6 +102,15 @@ impl GameManager { .collect::>() .join(","), ); + session.data.insert( + "win_cells".to_string(), + result + .win_cells + .iter() + .map(usize::to_string) + .collect::>() + .join(","), + ); session .data .insert("winnings".to_string(), result.winnings.to_string()); @@ -118,6 +128,7 @@ impl GameManager { session.data.remove("reels"); session.data.remove("win_type"); session.data.remove("win_lines"); + session.data.remove("win_cells"); session.data.remove("winnings"); session.data.insert("error".to_string(), message.into()); } diff --git a/src/client/games/response.rs b/src/client/games/response.rs index de22a75..d7f9d45 100644 --- a/src/client/games/response.rs +++ b/src/client/games/response.rs @@ -7,6 +7,7 @@ pub struct SpinResult { pub reels: String, pub win_type: String, pub win_lines: Vec, + pub win_cells: Vec, } /// Parse one server reply to `PLAY_START`. @@ -52,11 +53,11 @@ pub fn parse_spin_response(response: &str) -> Result { let win_lines = parts .get(7) - .map(|raw| { - raw.split(',') - .filter_map(|value| value.trim().parse::().ok()) - .collect() - }) + .map(|raw| parse_indices(raw)) + .unwrap_or_default(); + let win_cells = parts + .get(8) + .map(|raw| parse_indices(raw)) .unwrap_or_default(); Ok(SpinResult { @@ -67,5 +68,12 @@ pub fn parse_spin_response(response: &str) -> Result { reels: parts[5].to_string(), win_type: parts[6].to_string(), win_lines, + win_cells, }) } + +fn parse_indices(raw: &str) -> Vec { + raw.split(',') + .filter_map(|value| value.trim().parse::().ok()) + .collect() +} diff --git a/src/client/games/slots.rs b/src/client/games/slots.rs index 39c43b2..c367fcb 100644 --- a/src/client/games/slots.rs +++ b/src/client/games/slots.rs @@ -13,22 +13,40 @@ impl SlotsGame { Self } - fn cell(chars: &[char], row: usize, col: usize) -> char { - if chars.len() == REELS * ROWS { + fn cell(chars: &[char], row: usize, col: usize, winning: &[usize]) -> String { + let symbol = if chars.len() == REELS * ROWS { chars.get(col * ROWS + row).copied().unwrap_or('?') } else if chars.len() == 3 && row == 0 { // Legacy 3-symbol server: degrade to the first row. chars.get(col).copied().unwrap_or('?') } else { '?' + }; + + if winning.contains(&(col * ROWS + row)) { + format!("{{ {} }}", symbol) + } else { + format!("[ {} ]", symbol) } } - fn render_grid(&self, reels: &str) -> [String; ROWS] { + fn highlighted_cells(state: &GameState) -> Vec { + state + .data + .get("win_cells") + .map(|raw| { + raw.split(',') + .filter_map(|value| value.trim().parse::().ok()) + .collect() + }) + .unwrap_or_default() + } + + fn render_grid(&self, reels: &str, winning: &[usize]) -> [String; ROWS] { let chars: Vec = reels.chars().collect(); std::array::from_fn(|row| { (0..REELS) - .map(|col| format!("[ {} ]", Self::cell(&chars, row, col))) + .map(|col| Self::cell(&chars, row, col, winning)) .collect::>() .join(" ") }) @@ -84,7 +102,8 @@ impl Game for SlotsGame { .get("balance") .map(String::as_str) .unwrap_or("?"); - let grid = self.render_grid(&reels); + let winning = Self::highlighted_cells(state); + let grid = self.render_grid(&reels, &winning); format!( "=== SLOTS ===\r\nBet: {} PLN Lines: {} Balance: {} PLN\r\n{}\r\n{}\r\n{}\r\n\r\n{}\r\n{}\r\n[+/-] Bet [SPACE] Spin [Q] Quit", -- cgit v1.2.3