knock out players correctly upon cut for call; make sure order of players knocked...
authorGeoffrey Allott <geoffrey@allott.email>
Sat, 17 Jun 2023 21:15:51 +0000 (22:15 +0100)
committerGeoffrey Allott <geoffrey@allott.email>
Sat, 17 Jun 2023 21:15:51 +0000 (22:15 +0100)
src/game/whist.rs

index 6d0d39e6f976ee96e7f77d4118de602bf449e289..131070b7058458b5ef9451d0ca0b307c9eda9678 100644 (file)
@@ -262,7 +262,7 @@ impl Game for KnockOutWhist {
                 }
                 Ok(())
             }
-            (State::Playing, Action::KnockedOut) => {
+            (State::Playing | State::CutForCall, Action::KnockedOut) => {
                 if self.dealer == Some(username) {
                     self.dealer = self.seats.player_before(username);
                 }
@@ -357,10 +357,12 @@ impl Game for KnockOutWhist {
             State::ChoosingTrumps => DealerAction::WaitForPlayer,
             State::Playing => {
                 if !self.winners.is_empty() {
-                    for username in self.seats.player_set() {
-                        if matches!(self.tricks_won.get(&username), Some(0) | None) {
-                            return DealerAction::TakeAction(ValidatedUserAction(UserAction { timestamp, username, action: Action::KnockedOut }));
-                        }
+                    let knocked_out_player = self.seats.player_set()
+                        .into_iter()
+                        .filter(|username| matches!(self.tricks_won.get(username), Some(0) | None))
+                        .min();
+                    if let Some(username) = knocked_out_player {
+                        return DealerAction::TakeAction(ValidatedUserAction(UserAction { timestamp, username, action: Action::KnockedOut }));
                     }
                     if self.seats.players_len() == 1 {
                         if let Some(&username) = self.winners.iter().next() {
@@ -378,6 +380,13 @@ impl Game for KnockOutWhist {
                 }
             }
             State::CutForCall => {
+                let knocked_out_player = self.seats.player_set()
+                    .into_iter()
+                    .filter(|username| matches!(self.tricks_won.get(username), Some(0) | None))
+                    .min();
+                if let Some(username) = knocked_out_player {
+                    return DealerAction::TakeAction(ValidatedUserAction(UserAction { timestamp, username, action: Action::KnockedOut }));
+                }
                 if let Some(username) = self.receiver {
                     if let Some(card) = rng.choose_from(self.deck) {
                         DealerAction::TakeAction(ValidatedUserAction(UserAction { timestamp, username, action: Action::CutCard { card } }))
@@ -1178,4 +1187,127 @@ mod tests {
 
         test_game(actions, settings, seed);
     }
+
+    #[test]
+    fn players_knocked_out_on_tie_for_first() {
+        let actions = r#"[
+            {"timestamp":1687025531200,"username":"Steve","action":{"action":"Join","seat":0,"chips":0}},
+            {"timestamp":1687025539806,"username":"Aga","action":{"action":"Join","seat":1,"chips":0}},
+            {"timestamp":1687025544327,"username":"Geoff","action":{"action":"Join","seat":2,"chips":0}},
+            {"timestamp":1687025544328,"username":"Aga","action":{"action":"NextToDeal"}},
+            {"timestamp":1687025544329,"username":"Geoff","action":{"action":"ReceiveCard","card":{"rank":"Seven","suit":"Clubs"}}},
+            {"timestamp":1687025544332,"username":"Steve","action":{"action":"ReceiveCard","card":{"rank":"Five","suit":"Clubs"}}},
+            {"timestamp":1687025544334,"username":"Aga","action":{"action":"ReceiveCard","card":{"rank":"Queen","suit":"Hearts"}}},
+            {"timestamp":1687025544335,"username":"Geoff","action":{"action":"ReceiveCard","card":{"rank":"Ten","suit":"Spades"}}},
+            {"timestamp":1687025544336,"username":"Steve","action":{"action":"ReceiveCard","card":{"rank":"Nine","suit":"Hearts"}}},
+            {"timestamp":1687025544338,"username":"Aga","action":{"action":"ReceiveCard","card":{"rank":"Ten","suit":"Hearts"}}},
+            {"timestamp":1687025544338,"username":"Geoff","action":{"action":"ReceiveCard","card":{"rank":"Ace","suit":"Hearts"}}},
+            {"timestamp":1687025544339,"username":"Steve","action":{"action":"ReceiveCard","card":{"rank":"Nine","suit":"Diamonds"}}},
+            {"timestamp":1687025544339,"username":"Aga","action":{"action":"ReceiveCard","card":{"rank":"Two","suit":"Diamonds"}}},
+            {"timestamp":1687025544339,"username":"Geoff","action":{"action":"ReceiveCard","card":{"rank":"Three","suit":"Spades"}}},
+            {"timestamp":1687025544340,"username":"Steve","action":{"action":"ReceiveCard","card":{"rank":"Queen","suit":"Diamonds"}}},
+            {"timestamp":1687025544340,"username":"Aga","action":{"action":"ReceiveCard","card":{"rank":"King","suit":"Hearts"}}},
+            {"timestamp":1687025544341,"username":"Geoff","action":{"action":"ReceiveCard","card":{"rank":"Jack","suit":"Clubs"}}},
+            {"timestamp":1687025544341,"username":"Steve","action":{"action":"ReceiveCard","card":{"rank":"Ten","suit":"Clubs"}}},
+            {"timestamp":1687025544342,"username":"Aga","action":{"action":"ReceiveCard","card":{"rank":"Three","suit":"Diamonds"}}},
+            {"timestamp":1687025544343,"username":"Geoff","action":{"action":"ReceiveCard","card":{"rank":"Two","suit":"Spades"}}},
+            {"timestamp":1687025544343,"username":"Steve","action":{"action":"ReceiveCard","card":{"rank":"Six","suit":"Spades"}}},
+            {"timestamp":1687025544344,"username":"Aga","action":{"action":"ReceiveCard","card":{"rank":"Ace","suit":"Clubs"}}},
+            {"timestamp":1687025544344,"username":"Geoff","action":{"action":"ReceiveCard","card":{"rank":"Eight","suit":"Hearts"}}},
+            {"timestamp":1687025544345,"username":"Steve","action":{"action":"ReceiveCard","card":{"rank":"Nine","suit":"Clubs"}}},
+            {"timestamp":1687025544345,"username":"Aga","action":{"action":"ReceiveCard","card":{"rank":"Two","suit":"Clubs"}}},
+            {"timestamp":1687025544345,"username":"Aga","action":{"action":"CommunityCard","card":{"rank":"Three","suit":"Hearts"}}},
+            {"timestamp":1687025544346,"username":"Aga","action":{"action":"EndDeal"}},
+            {"timestamp":1687025567895,"username":"Geoff","action":{"action":"PlayCard","card":{"rank":"Jack","suit":"Clubs"}}},
+            {"timestamp":1687025575145,"username":"Steve","action":{"action":"PlayCard","card":{"rank":"Five","suit":"Clubs"}}},
+            {"timestamp":1687025577395,"username":"Aga","action":{"action":"PlayCard","card":{"rank":"Ace","suit":"Clubs"}}},
+            {"timestamp":1687025577396,"username":"Aga","action":{"action":"WinTrick"}},
+            {"timestamp":1687025579295,"username":"Aga","action":{"action":"PlayCard","card":{"rank":"King","suit":"Hearts"}}},
+            {"timestamp":1687025584278,"username":"Geoff","action":{"action":"PlayCard","card":{"rank":"Ace","suit":"Hearts"}}},
+            {"timestamp":1687025585580,"username":"Steve","action":{"action":"PlayCard","card":{"rank":"Nine","suit":"Hearts"}}},
+            {"timestamp":1687025585581,"username":"Geoff","action":{"action":"WinTrick"}},
+            {"timestamp":1687025589478,"username":"Geoff","action":{"action":"PlayCard","card":{"rank":"Ten","suit":"Spades"}}},
+            {"timestamp":1687025593261,"username":"Steve","action":{"action":"PlayCard","card":{"rank":"Six","suit":"Spades"}}},
+            {"timestamp":1687025598728,"username":"Aga","action":{"action":"PlayCard","card":{"rank":"Queen","suit":"Hearts"}}},
+            {"timestamp":1687025598731,"username":"Aga","action":{"action":"WinTrick"}},
+            {"timestamp":1687025602929,"username":"Aga","action":{"action":"PlayCard","card":{"rank":"Two","suit":"Clubs"}}},
+            {"timestamp":1687025605361,"username":"Geoff","action":{"action":"PlayCard","card":{"rank":"Seven","suit":"Clubs"}}},
+            {"timestamp":1687025607462,"username":"Steve","action":{"action":"PlayCard","card":{"rank":"Ten","suit":"Clubs"}}},
+            {"timestamp":1687025607470,"username":"Steve","action":{"action":"WinTrick"}},
+            {"timestamp":1687025610129,"username":"Steve","action":{"action":"PlayCard","card":{"rank":"Queen","suit":"Diamonds"}}},
+            {"timestamp":1687025613629,"username":"Aga","action":{"action":"PlayCard","card":{"rank":"Two","suit":"Diamonds"}}},
+            {"timestamp":1687025615128,"username":"Geoff","action":{"action":"PlayCard","card":{"rank":"Eight","suit":"Hearts"}}},
+            {"timestamp":1687025615129,"username":"Geoff","action":{"action":"WinTrick"}},
+            {"timestamp":1687025616079,"username":"Geoff","action":{"action":"PlayCard","card":{"rank":"Two","suit":"Spades"}}},
+            {"timestamp":1687025620212,"username":"Steve","action":{"action":"PlayCard","card":{"rank":"Nine","suit":"Diamonds"}}},
+            {"timestamp":1687025716180,"username":"Aga","action":{"action":"PlayCard","card":{"rank":"Ten","suit":"Hearts"}}},
+            {"timestamp":1687025716181,"username":"Aga","action":{"action":"WinTrick"}},
+            {"timestamp":1687025717565,"username":"Aga","action":{"action":"PlayCard","card":{"rank":"Three","suit":"Diamonds"}}},
+            {"timestamp":1687025721250,"username":"Geoff","action":{"action":"PlayCard","card":{"rank":"Three","suit":"Spades"}}},
+            {"timestamp":1687025723213,"username":"Steve","action":{"action":"PlayCard","card":{"rank":"Nine","suit":"Clubs"}}},
+            {"timestamp":1687025723214,"username":"Aga","action":{"action":"WinTrick"}},
+            {"timestamp":1687025723214,"username":"Aga","action":{"action":"WinCall"}},
+            {"timestamp":1687025723215,"username":"Geoff","action":{"action":"NextToDeal"}},
+            {"timestamp":1687025723216,"username":"Steve","action":{"action":"ReceiveCard","card":{"rank":"Ace","suit":"Diamonds"}}},
+            {"timestamp":1687025723219,"username":"Aga","action":{"action":"ReceiveCard","card":{"rank":"Two","suit":"Diamonds"}}},
+            {"timestamp":1687025723221,"username":"Geoff","action":{"action":"ReceiveCard","card":{"rank":"Four","suit":"Clubs"}}},
+            {"timestamp":1687025723224,"username":"Steve","action":{"action":"ReceiveCard","card":{"rank":"Ten","suit":"Diamonds"}}},
+            {"timestamp":1687025723227,"username":"Aga","action":{"action":"ReceiveCard","card":{"rank":"Eight","suit":"Spades"}}},
+            {"timestamp":1687025723229,"username":"Geoff","action":{"action":"ReceiveCard","card":{"rank":"Six","suit":"Clubs"}}},
+            {"timestamp":1687025723232,"username":"Steve","action":{"action":"ReceiveCard","card":{"rank":"Jack","suit":"Clubs"}}},
+            {"timestamp":1687025723234,"username":"Aga","action":{"action":"ReceiveCard","card":{"rank":"King","suit":"Hearts"}}},
+            {"timestamp":1687025723235,"username":"Geoff","action":{"action":"ReceiveCard","card":{"rank":"Eight","suit":"Hearts"}}},
+            {"timestamp":1687025723236,"username":"Steve","action":{"action":"ReceiveCard","card":{"rank":"Nine","suit":"Clubs"}}},
+            {"timestamp":1687025723236,"username":"Aga","action":{"action":"ReceiveCard","card":{"rank":"Eight","suit":"Diamonds"}}},
+            {"timestamp":1687025723237,"username":"Geoff","action":{"action":"ReceiveCard","card":{"rank":"Three","suit":"Hearts"}}},
+            {"timestamp":1687025723237,"username":"Steve","action":{"action":"ReceiveCard","card":{"rank":"Queen","suit":"Hearts"}}},
+            {"timestamp":1687025723238,"username":"Aga","action":{"action":"ReceiveCard","card":{"rank":"Seven","suit":"Diamonds"}}},
+            {"timestamp":1687025723238,"username":"Geoff","action":{"action":"ReceiveCard","card":{"rank":"Nine","suit":"Hearts"}}},
+            {"timestamp":1687025723238,"username":"Steve","action":{"action":"ReceiveCard","card":{"rank":"Two","suit":"Spades"}}},
+            {"timestamp":1687025723239,"username":"Aga","action":{"action":"ReceiveCard","card":{"rank":"King","suit":"Clubs"}}},
+            {"timestamp":1687025723239,"username":"Geoff","action":{"action":"ReceiveCard","card":{"rank":"Three","suit":"Diamonds"}}},
+            {"timestamp":1687025723240,"username":"Geoff","action":{"action":"EndDeal"}},
+            {"timestamp":1687025742414,"username":"Aga","action":{"action":"ChooseTrumps","suit":"Spades"}},
+            {"timestamp":1687025937234,"username":"Steve","action":{"action":"PlayCard","card":{"rank":"Jack","suit":"Clubs"}}},
+            {"timestamp":1687025944502,"username":"Aga","action":{"action":"PlayCard","card":{"rank":"King","suit":"Clubs"}}},
+            {"timestamp":1687025945935,"username":"Geoff","action":{"action":"PlayCard","card":{"rank":"Six","suit":"Clubs"}}},
+            {"timestamp":1687025945936,"username":"Aga","action":{"action":"WinTrick"}},
+            {"timestamp":1687025948351,"username":"Aga","action":{"action":"PlayCard","card":{"rank":"King","suit":"Hearts"}}},
+            {"timestamp":1687025950851,"username":"Geoff","action":{"action":"PlayCard","card":{"rank":"Nine","suit":"Hearts"}}},
+            {"timestamp":1687025953734,"username":"Steve","action":{"action":"PlayCard","card":{"rank":"Queen","suit":"Hearts"}}},
+            {"timestamp":1687025953738,"username":"Aga","action":{"action":"WinTrick"}},
+            {"timestamp":1687025961402,"username":"Aga","action":{"action":"PlayCard","card":{"rank":"Eight","suit":"Spades"}}},
+            {"timestamp":1687025965318,"username":"Geoff","action":{"action":"PlayCard","card":{"rank":"Three","suit":"Hearts"}}},
+            {"timestamp":1687025967985,"username":"Steve","action":{"action":"PlayCard","card":{"rank":"Two","suit":"Spades"}}},
+            {"timestamp":1687025967990,"username":"Aga","action":{"action":"WinTrick"}},
+            {"timestamp":1687025970585,"username":"Aga","action":{"action":"PlayCard","card":{"rank":"Eight","suit":"Diamonds"}}},
+            {"timestamp":1687025972251,"username":"Geoff","action":{"action":"PlayCard","card":{"rank":"Three","suit":"Diamonds"}}},
+            {"timestamp":1687025974868,"username":"Steve","action":{"action":"PlayCard","card":{"rank":"Ace","suit":"Diamonds"}}},
+            {"timestamp":1687025974878,"username":"Steve","action":{"action":"WinTrick"}},
+            {"timestamp":1687025976019,"username":"Steve","action":{"action":"PlayCard","card":{"rank":"Ten","suit":"Diamonds"}}},
+            {"timestamp":1687025979902,"username":"Aga","action":{"action":"PlayCard","card":{"rank":"Two","suit":"Diamonds"}}},
+            {"timestamp":1687025981968,"username":"Geoff","action":{"action":"PlayCard","card":{"rank":"Four","suit":"Clubs"}}},
+            {"timestamp":1687025981971,"username":"Steve","action":{"action":"WinTrick"}},
+            {"timestamp":1687025983469,"username":"Steve","action":{"action":"PlayCard","card":{"rank":"Nine","suit":"Clubs"}}},
+            {"timestamp":1687025986068,"username":"Aga","action":{"action":"PlayCard","card":{"rank":"Seven","suit":"Diamonds"}}},
+            {"timestamp":1687025987784,"username":"Geoff","action":{"action":"PlayCard","card":{"rank":"Eight","suit":"Hearts"}}},
+            {"timestamp":1687025987787,"username":"Steve","action":{"action":"WinTrick"}},
+            {"timestamp":1687025987787,"username":"Geoff","action":{"action":"KnockedOut"}},
+            {"timestamp":1687025987790,"username":"Steve","action":{"action":"CutCard","card":{"rank":"Three","suit":"Hearts"}}},
+            {"timestamp":1687025987790,"username":"Aga","action":{"action":"CutCard","card":{"rank":"Three","suit":"Spades"}}},
+            {"timestamp":1687025987790,"username":"Steve","action":{"action":"CutCard","card":{"rank":"Three","suit":"Diamonds"}}},
+            {"timestamp":1687025987790,"username":"Aga","action":{"action":"CutCard","card":{"rank":"Five","suit":"Hearts"}}},
+            {"timestamp":1687025987791,"username":"Aga","action":{"action":"WinCall"}},
+            {"timestamp":1687025987792,"username":"Steve","action":{"action":"NextToDeal"}}
+        ]"#;
+        let actions = serde_json::from_str(actions).unwrap();
+
+        let settings = r#"{"format":"KnockOutWhist","title":"Kingly Juncture","max_players":3,"start_time":null}"#;
+        let settings = serde_json::from_str(settings).unwrap();
+
+        let seed = r#"{"rng":"ChaCha8","seed":"689b3ec1462a1a11a403680f26909f3539f702bc16d074911bb16788e07dfe58"}"#;
+        let seed = serde_json::from_str(seed).unwrap();
+
+        test_game(actions, settings, seed);
+    }
 }