From: Geoffrey Allott Date: Sun, 7 Mar 2021 12:17:58 +0000 (+0000) Subject: fix some issues with players being knocked out X-Git-Url: https://git.pointlesshacks.com/?a=commitdiff_plain;h=fc8c72b8c6a1a278062f3274f2326c68f350546d;p=pokerwave.git fix some issues with players being knocked out --- diff --git a/src/game/poker/holdem.rs b/src/game/poker/holdem.rs index 10bf482..33cf334 100644 --- a/src/game/poker/holdem.rs +++ b/src/game/poker/holdem.rs @@ -195,6 +195,14 @@ impl TexasHoldEm { }; Ok(()) } + + fn next_knocked_out_player(&self) -> Option { + self.stacks.iter() + .filter(|&(username, _)| self.in_hand.contains(username)) + .sorted() + .find(|&(_, &stack)| stack == 0) + .map(|(&username, _)| username) + } } impl Game for TexasHoldEm { @@ -295,9 +303,9 @@ impl Game for TexasHoldEm { self.deck = FIFTY_TWO_CARD_DECK.iter().cloned().collect(); self.hands.clear(); self.community.clear(); - self.receiver = self.seats.player_after(username); self.active = None; self.in_hand = self.seats.player_set().into_iter().filter(|username| !self.ghosts.contains_key(username)).collect(); + self.receiver = self.seats.player_after_where(username, |username| self.in_hand.contains(&username)); self.bets.clear(); self.committed.clear(); if self.pot != 0 { @@ -313,7 +321,7 @@ impl Game for TexasHoldEm { if self.hands.values().all(|hand| hand.len() == 2) { self.receiver = None; } else { - self.receiver = self.receiver.and_then(|player| self.seats.player_after(player)); + self.receiver = self.receiver.and_then(|player| self.seats.player_after_where(player, |player| self.in_hand.contains(&player))); } Ok(()) } @@ -496,7 +504,7 @@ impl Game for TexasHoldEm { error!("There is no player to win the game {:#?}", self); DealerAction::Leave } - } else if let Some((&username, _)) = self.stacks.iter().find(|&(_, &stack)| stack == 0) { + } else if let Some(username) = self.next_knocked_out_player() { DealerAction::TakeAction(ValidatedUserAction(UserAction { timestamp, username, action: Action::KnockedOut })) } else if let Some(username) = self.dealer.and_then(|dealer| self.seats.player_after(dealer)) { DealerAction::TakeAction(ValidatedUserAction(UserAction { timestamp, username, action: Action::NextToDeal })) @@ -529,7 +537,7 @@ impl Game for TexasHoldEm { } } State::Showdown if self.pot == 0 => { - if let Some((&username, _)) = self.stacks.iter().find(|&(_, &stack)| stack == 0) { + if let Some(username) = self.next_knocked_out_player() { DealerAction::TakeAction(ValidatedUserAction(UserAction { timestamp, username, action: Action::KnockedOut })) } else if self.seats.players_len() == 1 { if let Some(&username) = self.seats.player_set().iter().next() { @@ -549,6 +557,7 @@ impl Game for TexasHoldEm { let winning_hands: Vec<_> = self .hands .iter() + .sorted_by_key(|&(username, _)| username) .map(|(&username, hand)| (username, hand.iter().chain(self.community.iter()).cloned().collect::>())) .filter_map(|(username, cards)| cards.try_into().ok().map(rank_7_card_hand).map(|hand| (username, hand))) .max_items_by_key(|(_, hand)| *hand); @@ -1135,53 +1144,48 @@ mod tests { {"timestamp":1614983263398,"username":"mack","action":{"action":"WinHand","chips":2500,"hand":"Straight, J High"}}, {"timestamp":1614983263405,"username":"kat","action":{"action":"KnockedOut"}}, {"timestamp":1614983263412,"username":"geoff","action":{"action":"NextToDeal"}}, - {"timestamp":1614983263419,"username":"kat","action":{"action":"ReceiveCard","card":{"rank":"Ten","suit":"Clubs"}}}, - {"timestamp":1614983263428,"username":"mack","action":{"action":"ReceiveCard","card":{"rank":"Six","suit":"Hearts"}}}, - {"timestamp":1614983263435,"username":"pete","action":{"action":"ReceiveCard","card":{"rank":"Three","suit":"Clubs"}}}, - {"timestamp":1614983263443,"username":"geoff","action":{"action":"ReceiveCard","card":{"rank":"Six","suit":"Clubs"}}}, - {"timestamp":1614983263450,"username":"kat","action":{"action":"ReceiveCard","card":{"rank":"Two","suit":"Clubs"}}}, - {"timestamp":1614983263459,"username":"mack","action":{"action":"ReceiveCard","card":{"rank":"Ace","suit":"Diamonds"}}}, - {"timestamp":1614983263465,"username":"pete","action":{"action":"ReceiveCard","card":{"rank":"Jack","suit":"Hearts"}}}, - {"timestamp":1614983263475,"username":"geoff","action":{"action":"ReceiveCard","card":{"rank":"Eight","suit":"Diamonds"}}}, + {"timestamp":1614983263419,"username":"mack","action":{"action":"ReceiveCard","card":{"rank":"Ten","suit":"Clubs"}}}, + {"timestamp":1614983263428,"username":"pete","action":{"action":"ReceiveCard","card":{"rank":"Six","suit":"Hearts"}}}, + {"timestamp":1614983263435,"username":"geoff","action":{"action":"ReceiveCard","card":{"rank":"Three","suit":"Clubs"}}}, + {"timestamp":1614983263443,"username":"mack","action":{"action":"ReceiveCard","card":{"rank":"Six","suit":"Clubs"}}}, + {"timestamp":1614983263450,"username":"pete","action":{"action":"ReceiveCard","card":{"rank":"Two","suit":"Clubs"}}}, + {"timestamp":1614983263459,"username":"geoff","action":{"action":"ReceiveCard","card":{"rank":"Ace","suit":"Diamonds"}}}, {"timestamp":1614983263482,"username":"geoff","action":{"action":"EndDeal"}}, {"timestamp":1614983263491,"username":"kat","action":{"action":"PostBlind","chips":0}}, {"timestamp":1614983263502,"username":"mack","action":{"action":"PostBlind","chips":50}}, {"timestamp":1614983275207,"username":"pete","action":{"action":"Bet","chips":50}}, {"timestamp":1614983277953,"username":"geoff","action":{"action":"Bet","chips":50}}, {"timestamp":1614983281204,"username":"mack","action":{"action":"Bet","chips":0}}, - {"timestamp":1614983281211,"username":"geoff","action":{"action":"CommunityCard","card":{"rank":"Eight","suit":"Spades"}}}, - {"timestamp":1614983281219,"username":"geoff","action":{"action":"CommunityCard","card":{"rank":"Five","suit":"Diamonds"}}}, - {"timestamp":1614983281227,"username":"geoff","action":{"action":"CommunityCard","card":{"rank":"King","suit":"Diamonds"}}}, + {"timestamp":1614983281211,"username":"geoff","action":{"action":"CommunityCard","card":{"rank":"Three","suit":"Diamonds"}}}, + {"timestamp":1614983281219,"username":"geoff","action":{"action":"CommunityCard","card":{"rank":"Five","suit":"Spades"}}}, + {"timestamp":1614983281227,"username":"geoff","action":{"action":"CommunityCard","card":{"rank":"Nine","suit":"Clubs"}}}, {"timestamp":1614983286335,"username":"mack","action":{"action":"Bet","chips":0}}, {"timestamp":1614983287681,"username":"pete","action":{"action":"Bet","chips":0}}, {"timestamp":1614983292106,"username":"geoff","action":{"action":"Bet","chips":200}}, {"timestamp":1614983293844,"username":"mack","action":{"action":"Bet","chips":200}}, {"timestamp":1614983295211,"username":"pete","action":{"action":"Fold"}}, - {"timestamp":1614983295217,"username":"geoff","action":{"action":"CommunityCard","card":{"rank":"Jack","suit":"Diamonds"}}}, + {"timestamp":1614983295217,"username":"geoff","action":{"action":"CommunityCard","card":{"rank":"Four","suit":"Hearts"}}}, {"timestamp":1614983300431,"username":"mack","action":{"action":"Bet","chips":0}}, {"timestamp":1614983301319,"username":"geoff","action":{"action":"Bet","chips":0}}, - {"timestamp":1614983301327,"username":"geoff","action":{"action":"CommunityCard","card":{"rank":"Five","suit":"Spades"}}}, + {"timestamp":1614983301327,"username":"geoff","action":{"action":"CommunityCard","card":{"rank":"Queen","suit":"Spades"}}}, {"timestamp":1614983308234,"username":"mack","action":{"action":"Bet","chips":250}}, {"timestamp":1614983309575,"username":"geoff","action":{"action":"Bet","chips":250}}, - {"timestamp":1614983309584,"username":"geoff","action":{"action":"WinHand","chips":1050,"hand":"Two Pair, 8s & 5s, K Kicker"}}, - {"timestamp":1614983309592,"username":"kat","action":{"action":"KnockedOut"}}, + {"timestamp":1614983309584,"username":"geoff","action":{"action":"WinHand","chips":1050,"hand":"Pair of 3s, AQ9 Kickers"}}, {"timestamp":1614983309599,"username":"kat","action":{"action":"NextToDeal"}}, - {"timestamp":1614983309619,"username":"mack","action":{"action":"ReceiveCard","card":{"rank":"Nine","suit":"Spades"}}}, + {"timestamp":1614983309619,"username":"mack","action":{"action":"ReceiveCard","card":{"rank":"Eight","suit":"Diamonds"}}}, {"timestamp":1614983309642,"username":"pete","action":{"action":"ReceiveCard","card":{"rank":"Three","suit":"Clubs"}}}, - {"timestamp":1614983309651,"username":"geoff","action":{"action":"ReceiveCard","card":{"rank":"Five","suit":"Clubs"}}}, - {"timestamp":1614983309660,"username":"kat","action":{"action":"ReceiveCard","card":{"rank":"Ace","suit":"Hearts"}}}, - {"timestamp":1614983309673,"username":"mack","action":{"action":"ReceiveCard","card":{"rank":"Ten","suit":"Hearts"}}}, - {"timestamp":1614983309683,"username":"pete","action":{"action":"ReceiveCard","card":{"rank":"Jack","suit":"Spades"}}}, - {"timestamp":1614983309691,"username":"geoff","action":{"action":"ReceiveCard","card":{"rank":"Five","suit":"Hearts"}}}, - {"timestamp":1614983309699,"username":"kat","action":{"action":"ReceiveCard","card":{"rank":"Eight","suit":"Clubs"}}}, + {"timestamp":1614983309651,"username":"geoff","action":{"action":"ReceiveCard","card":{"rank":"Jack","suit":"Spades"}}}, + {"timestamp":1614983309673,"username":"mack","action":{"action":"ReceiveCard","card":{"rank":"Ten","suit":"Diamonds"}}}, + {"timestamp":1614983309683,"username":"pete","action":{"action":"ReceiveCard","card":{"rank":"Three","suit":"Diamonds"}}}, + {"timestamp":1614983309691,"username":"geoff","action":{"action":"ReceiveCard","card":{"rank":"Five","suit":"Diamonds"}}}, {"timestamp":1614983309707,"username":"kat","action":{"action":"EndDeal"}}, {"timestamp":1614983309712,"username":"mack","action":{"action":"PostBlind","chips":25}}, {"timestamp":1614983309720,"username":"pete","action":{"action":"PostBlind","chips":50}}, {"timestamp":1614983320450,"username":"geoff","action":{"action":"Bet","chips":900}}, {"timestamp":1614983322843,"username":"mack","action":{"action":"Bet","chips":875}}, {"timestamp":1614983324378,"username":"pete","action":{"action":"Fold"}}, - {"timestamp":1614983324386,"username":"kat","action":{"action":"CommunityCard","card":{"rank":"Nine","suit":"Diamonds"}}}, - {"timestamp":1614983324395,"username":"kat","action":{"action":"CommunityCard","card":{"rank":"Six","suit":"Spades"}}}, + {"timestamp":1614983324386,"username":"kat","action":{"action":"CommunityCard","card":{"rank":"Three","suit":"Spades"}}}, + {"timestamp":1614983324395,"username":"kat","action":{"action":"CommunityCard","card":{"rank":"Six","suit":"Clubs"}}}, {"timestamp":1614983324402,"username":"kat","action":{"action":"CommunityCard","card":{"rank":"Eight","suit":"Hearts"}}}, {"timestamp":1614983328902,"username":"mack","action":{"action":"Bet","chips":0}} ]"#; @@ -1196,4 +1200,115 @@ mod tests { test_game(actions, settings, seed); } + + #[test] + fn two_players_knocked_out_at_once() { + let actions = r#"[ + {"timestamp":1615110088077,"username":"geoff","action":{"action":"Join","seat":0,"chips":1000}}, + {"timestamp":1615110137727,"username":"kat","action":{"action":"Join","seat":1,"chips":1000}}, + {"timestamp":1615110153252,"username":"pete","action":{"action":"Join","seat":2,"chips":1000}}, + {"timestamp":1615110255181,"username":"mack","action":{"action":"Join","seat":3,"chips":1000}}, + {"timestamp":1615110255184,"username":"pete","action":{"action":"NextToDeal"}}, + {"timestamp":1615110255187,"username":"mack","action":{"action":"ReceiveCard","card":{"rank":"King","suit":"Spades"}}}, + {"timestamp":1615110255188,"username":"geoff","action":{"action":"ReceiveCard","card":{"rank":"Ace","suit":"Clubs"}}}, + {"timestamp":1615110255189,"username":"kat","action":{"action":"ReceiveCard","card":{"rank":"Eight","suit":"Hearts"}}}, + {"timestamp":1615110255191,"username":"pete","action":{"action":"ReceiveCard","card":{"rank":"Ace","suit":"Spades"}}}, + {"timestamp":1615110255192,"username":"mack","action":{"action":"ReceiveCard","card":{"rank":"Eight","suit":"Clubs"}}}, + {"timestamp":1615110255194,"username":"geoff","action":{"action":"ReceiveCard","card":{"rank":"Eight","suit":"Spades"}}}, + {"timestamp":1615110255195,"username":"kat","action":{"action":"ReceiveCard","card":{"rank":"Nine","suit":"Spades"}}}, + {"timestamp":1615110255197,"username":"pete","action":{"action":"ReceiveCard","card":{"rank":"Three","suit":"Hearts"}}}, + {"timestamp":1615110255199,"username":"pete","action":{"action":"EndDeal"}}, + {"timestamp":1615110255200,"username":"mack","action":{"action":"PostBlind","chips":25}}, + {"timestamp":1615110255201,"username":"geoff","action":{"action":"PostBlind","chips":50}}, + {"timestamp":1615110315647,"username":"kat","action":{"action":"Bet","chips":50}}, + {"timestamp":1615110317483,"username":"pete","action":{"action":"Bet","chips":50}}, + {"timestamp":1615110323333,"username":"mack","action":{"action":"Bet","chips":75}}, + {"timestamp":1615110325834,"username":"geoff","action":{"action":"Bet","chips":50}}, + {"timestamp":1615110327150,"username":"kat","action":{"action":"Bet","chips":50}}, + {"timestamp":1615110328299,"username":"pete","action":{"action":"Bet","chips":50}}, + {"timestamp":1615110328302,"username":"pete","action":{"action":"CommunityCard","card":{"rank":"Ten","suit":"Spades"}}}, + {"timestamp":1615110328304,"username":"pete","action":{"action":"CommunityCard","card":{"rank":"Ten","suit":"Diamonds"}}}, + {"timestamp":1615110328306,"username":"pete","action":{"action":"CommunityCard","card":{"rank":"Queen","suit":"Clubs"}}}, + {"timestamp":1615110341162,"username":"mack","action":{"action":"Bet","chips":0}}, + {"timestamp":1615110349157,"username":"geoff","action":{"action":"Bet","chips":100}}, + {"timestamp":1615110350658,"username":"kat","action":{"action":"Bet","chips":100}}, + {"timestamp":1615110352914,"username":"pete","action":{"action":"Fold"}}, + {"timestamp":1615110355566,"username":"mack","action":{"action":"Bet","chips":100}}, + {"timestamp":1615110355569,"username":"pete","action":{"action":"CommunityCard","card":{"rank":"Seven","suit":"Diamonds"}}}, + {"timestamp":1615110360025,"username":"mack","action":{"action":"Bet","chips":0}}, + {"timestamp":1615110363490,"username":"geoff","action":{"action":"Bet","chips":200}}, + {"timestamp":1615110364902,"username":"kat","action":{"action":"Bet","chips":200}}, + {"timestamp":1615110368549,"username":"mack","action":{"action":"Fold"}}, + {"timestamp":1615110368552,"username":"pete","action":{"action":"CommunityCard","card":{"rank":"Seven","suit":"Spades"}}}, + {"timestamp":1615110375784,"username":"geoff","action":{"action":"Bet","chips":0}}, + {"timestamp":1615110376698,"username":"kat","action":{"action":"Bet","chips":0}}, + {"timestamp":1615110376701,"username":"geoff","action":{"action":"WinHand","chips":1100,"hand":"Two Pair, Ts & 7s, A Kicker"}}, + {"timestamp":1615110376702,"username":"mack","action":{"action":"NextToDeal"}}, + {"timestamp":1615110376704,"username":"geoff","action":{"action":"ReceiveCard","card":{"rank":"Four","suit":"Diamonds"}}}, + {"timestamp":1615110376706,"username":"kat","action":{"action":"ReceiveCard","card":{"rank":"Three","suit":"Diamonds"}}}, + {"timestamp":1615110376707,"username":"pete","action":{"action":"ReceiveCard","card":{"rank":"Ten","suit":"Clubs"}}}, + {"timestamp":1615110376709,"username":"mack","action":{"action":"ReceiveCard","card":{"rank":"Four","suit":"Spades"}}}, + {"timestamp":1615110376710,"username":"geoff","action":{"action":"ReceiveCard","card":{"rank":"Ace","suit":"Hearts"}}}, + {"timestamp":1615110376711,"username":"kat","action":{"action":"ReceiveCard","card":{"rank":"Jack","suit":"Clubs"}}}, + {"timestamp":1615110376717,"username":"pete","action":{"action":"ReceiveCard","card":{"rank":"Seven","suit":"Diamonds"}}}, + {"timestamp":1615110376718,"username":"mack","action":{"action":"ReceiveCard","card":{"rank":"Three","suit":"Clubs"}}}, + {"timestamp":1615110376719,"username":"mack","action":{"action":"EndDeal"}}, + {"timestamp":1615110376721,"username":"geoff","action":{"action":"PostBlind","chips":25}}, + {"timestamp":1615110376722,"username":"kat","action":{"action":"PostBlind","chips":50}}, + {"timestamp":1615110388356,"username":"pete","action":{"action":"Bet","chips":900}}, + {"timestamp":1615110390318,"username":"mack","action":{"action":"Bet","chips":800}}, + {"timestamp":1615110396347,"username":"geoff","action":{"action":"Bet","chips":875}}, + {"timestamp":1615110420153,"username":"kat","action":{"action":"Bet","chips":550}}, + {"timestamp":1615110420157,"username":"mack","action":{"action":"CommunityCard","card":{"rank":"Jack","suit":"Diamonds"}}}, + {"timestamp":1615110420159,"username":"mack","action":{"action":"CommunityCard","card":{"rank":"Eight","suit":"Hearts"}}}, + {"timestamp":1615110420161,"username":"mack","action":{"action":"CommunityCard","card":{"rank":"Two","suit":"Spades"}}}, + {"timestamp":1615110420164,"username":"mack","action":{"action":"CommunityCard","card":{"rank":"Six","suit":"Diamonds"}}}, + {"timestamp":1615110420166,"username":"mack","action":{"action":"CommunityCard","card":{"rank":"Nine","suit":"Hearts"}}}, + {"timestamp":1615110420168,"username":"pete","action":{"action":"WinHand","chips":3200,"hand":"Straight, J High"}}, + {"timestamp":1615110420171,"username":"kat","action":{"action":"KnockedOut"}}, + {"timestamp":1615110420174,"username":"mack","action":{"action":"KnockedOut"}}, + {"timestamp":1615110420176,"username":"geoff","action":{"action":"NextToDeal"}}, + {"timestamp":1615110420181,"username":"pete","action":{"action":"ReceiveCard","card":{"rank":"Nine","suit":"Spades"}}}, + {"timestamp":1615110420183,"username":"geoff","action":{"action":"ReceiveCard","card":{"rank":"Three","suit":"Spades"}}}, + {"timestamp":1615110420187,"username":"pete","action":{"action":"ReceiveCard","card":{"rank":"Three","suit":"Hearts"}}}, + {"timestamp":1615110420189,"username":"geoff","action":{"action":"ReceiveCard","card":{"rank":"Ten","suit":"Clubs"}}}, + {"timestamp":1615110420191,"username":"geoff","action":{"action":"EndDeal"}}, + {"timestamp":1615110420193,"username":"kat","action":{"action":"PostBlind","chips":0}}, + {"timestamp":1615110420195,"username":"pete","action":{"action":"PostBlind","chips":50}}, + {"timestamp":1615110467747,"username":"geoff","action":{"action":"Bet","chips":50}}, + {"timestamp":1615110473355,"username":"pete","action":{"action":"Bet","chips":50}}, + {"timestamp":1615110479681,"username":"geoff","action":{"action":"Bet","chips":50}}, + {"timestamp":1615110479684,"username":"geoff","action":{"action":"CommunityCard","card":{"rank":"Three","suit":"Clubs"}}}, + {"timestamp":1615110479685,"username":"geoff","action":{"action":"CommunityCard","card":{"rank":"Queen","suit":"Hearts"}}}, + {"timestamp":1615110479687,"username":"geoff","action":{"action":"CommunityCard","card":{"rank":"Jack","suit":"Clubs"}}}, + {"timestamp":1615110484802,"username":"pete","action":{"action":"Bet","chips":0}}, + {"timestamp":1615110488083,"username":"geoff","action":{"action":"Bet","chips":0}}, + {"timestamp":1615110488086,"username":"geoff","action":{"action":"CommunityCard","card":{"rank":"Queen","suit":"Diamonds"}}}, + {"timestamp":1615110489597,"username":"pete","action":{"action":"Bet","chips":0}}, + {"timestamp":1615110490916,"username":"geoff","action":{"action":"Bet","chips":0}}, + {"timestamp":1615110490919,"username":"geoff","action":{"action":"CommunityCard","card":{"rank":"Five","suit":"Spades"}}}, + {"timestamp":1615110492365,"username":"pete","action":{"action":"Bet","chips":0}}, + {"timestamp":1615110493581,"username":"geoff","action":{"action":"Bet","chips":0}}, + {"timestamp":1615110493586,"username":"geoff","action":{"action":"WinHand","chips":100,"hand":"Two Pair, Qs & 3s, J Kicker"}}, + {"timestamp":1615110493586,"username":"pete","action":{"action":"WinHand","chips":100,"hand":"Two Pair, Qs & 3s, J Kicker"}}, + {"timestamp":1615110493590,"username":"kat","action":{"action":"NextToDeal"}}, + {"timestamp":1615110493591,"username":"pete","action":{"action":"ReceiveCard","card":{"rank":"Ten","suit":"Spades"}}}, + {"timestamp":1615110493592,"username":"geoff","action":{"action":"ReceiveCard","card":{"rank":"Six","suit":"Hearts"}}}, + {"timestamp":1615110493594,"username":"pete","action":{"action":"ReceiveCard","card":{"rank":"Eight","suit":"Hearts"}}}, + {"timestamp":1615110493597,"username":"geoff","action":{"action":"ReceiveCard","card":{"rank":"Six","suit":"Clubs"}}}, + {"timestamp":1615110493599,"username":"kat","action":{"action":"EndDeal"}}, + {"timestamp":1615110493601,"username":"pete","action":{"action":"PostBlind","chips":25}}, + {"timestamp":1615110493603,"username":"geoff","action":{"action":"PostBlind","chips":50}} + ]"#; + let actions = serde_json::from_str(actions).unwrap(); + + let settings = + r#"{"format":"TexasHoldEm","title":"4-Player TexasHoldEm Test","max_players":4,"small_blind":25,"starting_stack":1000,"action_timeout":null}"#; + let settings = serde_json::from_str(settings).unwrap(); + + let seed = r#"{"rng":"ChaCha20","seed":"092b99f45313fff167029dc7420ed69a92becae492e09b65bc06ddcaae3c9e9c"}"#; + let seed = serde_json::from_str(seed).unwrap(); + + test_game(actions, settings, seed); + } }