From fd605f34b648467b6fa6d9f5d19423a44652cf25 Mon Sep 17 00:00:00 2001 From: Geoffrey Allott Date: Mon, 1 Mar 2021 22:13:26 +0000 Subject: [PATCH] make whist deterministic based on seed --- src/game/mod.rs | 2 +- src/game/whist.rs | 19 ++++++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/game/mod.rs b/src/game/mod.rs index 6e45935..2ab9e1c 100644 --- a/src/game/mod.rs +++ b/src/game/mod.rs @@ -44,7 +44,7 @@ impl dyn Game { pub fn new(GameSummary{id, settings}: GameSummary, seed: Seed) -> Box { match settings { GameSettings::Chatroom(settings) => Box::new(Chatroom::new(id, settings)), - GameSettings::KnockOutWhist(settings) => Box::new(KnockOutWhist::new(id, settings)), + GameSettings::KnockOutWhist(settings) => Box::new(KnockOutWhist::new(id, settings, seed)), GameSettings::TexasHoldEm(settings) => Box::new(TexasHoldEm::new(id, settings, seed)), } } diff --git a/src/game/whist.rs b/src/game/whist.rs index b2d11a3..8d59f58 100644 --- a/src/game/whist.rs +++ b/src/game/whist.rs @@ -1,9 +1,7 @@ use std::collections::{HashMap, HashSet}; -use rand::seq::IteratorRandom; -use rand::thread_rng; - use crate::card::{Card, Suit, FIFTY_TWO_CARD_DECK}; +use crate::rng::{Seed, WaveRng}; use crate::seats::Seats; use crate::username::Username; use crate::util::max::IteratorMaxItems; @@ -31,6 +29,7 @@ pub struct KnockOutWhistSettings { pub struct KnockOutWhist { id: i64, settings: KnockOutWhistSettings, + rng: WaveRng, actions_len: usize, state: State, seats: Seats, @@ -50,10 +49,11 @@ pub struct KnockOutWhist { } impl KnockOutWhist { - pub fn new(id: i64, settings: KnockOutWhistSettings) -> Self { + pub fn new(id: i64, settings: KnockOutWhistSettings, seed: Seed) -> Self { Self { id, settings, + rng: seed.into_rng(), actions_len: 0, state: State::NotStarted, seats: Seats::new(), @@ -167,6 +167,7 @@ impl Game for KnockOutWhist { fn take_action(&mut self, ValidatedUserAction(UserAction{username, action}): ValidatedUserAction) -> Result<(), ActionError> { self.actions_len += 1; + self.rng.advance(); match (self.state, action) { (_, Action::AddOn{..}) | (_, Action::Fold) | (_, Action::Bet{..}) => { Err(ActionError::InvalidActionForGameType) @@ -302,11 +303,11 @@ impl Game for KnockOutWhist { } fn next_dealer_action(&self) -> Option { - let mut rng = thread_rng(); + let mut rng = self.rng.clone(); match self.state { State::NotStarted => { if self.seats.players_len() == self.settings.max_players as usize { // TODO - if let Some(username) = self.seats.player_set().into_iter().choose(&mut rng) { + if let Some(username) = rng.choose_from(self.seats.player_set()) { return Some(ValidatedUserAction(UserAction{username, action: Action::NextToDeal})); } } @@ -314,12 +315,12 @@ impl Game for KnockOutWhist { } State::Dealing => { if let Some(username) = self.receiver { - let card = self.deck.iter().choose(&mut rng).cloned(); + let card = rng.choose_from(&self.deck).cloned(); Some(ValidatedUserAction(UserAction{username, action: Action::ReceiveCard{card}})) } else if let Some(username) = self.dealer { match (self.call, self.trump_card) { (None, None) => { - if let Some(&card) = self.deck.iter().choose(&mut rng) { + if let Some(&card) = rng.choose_from(&self.deck) { Some(ValidatedUserAction(UserAction{username, action: Action::CommunityCard{card}})) } else { None @@ -358,7 +359,7 @@ impl Game for KnockOutWhist { } State::CutForCall => { if let Some(username) = self.receiver { - if let Some(card) = self.deck.iter().choose(&mut rng).cloned() { + if let Some(card) = rng.choose_from(&self.deck).cloned() { Some(ValidatedUserAction(UserAction{username, action: Action::RevealCard{card}})) } else { None -- 2.34.1