From: Geoffrey Allott Date: Sun, 28 Feb 2021 07:54:44 +0000 (+0000) Subject: enable texas hold 'em X-Git-Url: https://git.pointlesshacks.com/?a=commitdiff_plain;h=027ea09079a005ad6a2a6f933a36534fc68cc881;p=pokerwave.git enable texas hold 'em --- diff --git a/src/game/mod.rs b/src/game/mod.rs index c8e01f7..9297388 100644 --- a/src/game/mod.rs +++ b/src/game/mod.rs @@ -10,6 +10,7 @@ use crate::username::Username; use self::chatroom::{Chatroom, ChatroomSettings}; use self::whist::{KnockOutWhist, KnockOutWhistSettings}; +use self::poker::{TexasHoldEm, TexasHoldEmSettings}; pub use self::action::{Action, ActionError, UserAction, ValidatedUserAction}; @@ -43,6 +44,7 @@ impl dyn Game { match settings { GameSettings::Chatroom(settings) => Box::new(Chatroom::new(id, settings)), GameSettings::KnockOutWhist(settings) => Box::new(KnockOutWhist::new(id, settings)), + GameSettings::TexasHoldEm(settings) => Box::new(TexasHoldEm::new(id, settings)), } } } @@ -52,6 +54,7 @@ impl dyn Game { pub enum GameSettings { Chatroom(ChatroomSettings), KnockOutWhist(KnockOutWhistSettings), + TexasHoldEm(TexasHoldEmSettings), } #[derive(Debug, Clone, Serialize, Deserialize)] diff --git a/src/game/poker/holdem.rs b/src/game/poker/holdem.rs index 905be7d..9879147 100644 --- a/src/game/poker/holdem.rs +++ b/src/game/poker/holdem.rs @@ -31,7 +31,7 @@ enum State { Completed, } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Serialize, Deserialize)] pub struct TexasHoldEmSettings { title: String, max_players: u32, @@ -347,7 +347,7 @@ impl Game for TexasHoldEm { } } State::Showdown => { - let winning_hands = self.hands.iter() + let winning_hands: Vec<_> = self.hands.iter() .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); diff --git a/src/game/whist.rs b/src/game/whist.rs index 9d00173..da82f69 100644 --- a/src/game/whist.rs +++ b/src/game/whist.rs @@ -6,6 +6,7 @@ use rand::thread_rng; use crate::card::{Card, Suit, FIFTY_TWO_CARD_DECK}; use crate::seats::Seats; use crate::username::Username; +use crate::util::max::IteratorMaxItems; use super::{Action, ActionError, Game, UserAction, ValidatedUserAction}; @@ -241,18 +242,16 @@ impl Game for KnockOutWhist { self.led = None; self.trick.clear(); if self.tricks_won.values().sum::() == self.cards_to_deal { - if let Some(&most_tricks_won) = self.tricks_won.values().max() { - self.winners = self.tricks_won.iter().filter(|&(_, &tricks)| tricks == most_tricks_won).map(|(&username, _)| username).collect(); - self.cards_to_deal -= 1; - if self.winners.len() == 1 { - self.call = self.winners.iter().next().cloned(); - } else { - self.receiver = self.dealer.and_then(|dealer| self.seats.player_after_in(dealer, &self.winners)); - self.deck = FIFTY_TWO_CARD_DECK.iter().cloned().collect(); - self.hands.clear(); - self.trump_card = None; - self.state = State::CutForCall; - } + self.winners = self.tricks_won.iter().max_items_by_key_map(|&(_, &tricks)| tricks, |(&username, _)| username); + self.cards_to_deal -= 1; + if self.winners.len() == 1 { + self.call = self.winners.iter().next().cloned(); + } else { + self.receiver = self.dealer.and_then(|dealer| self.seats.player_after_in(dealer, &self.winners)); + self.deck = FIFTY_TWO_CARD_DECK.iter().cloned().collect(); + self.hands.clear(); + self.trump_card = None; + self.state = State::CutForCall; } self.active = None; } else { diff --git a/src/util/max.rs b/src/util/max.rs index 7a52101..b7ef75e 100644 --- a/src/util/max.rs +++ b/src/util/max.rs @@ -1,4 +1,6 @@ use std::cmp::Ordering; +use std::convert::identity; +use std::iter::FromIterator; pub trait IteratorMaxItems : Iterator + Sized { fn max_items(self) -> Vec @@ -8,9 +10,19 @@ pub trait IteratorMaxItems : Iterator + Sized { self.max_items_by(Ord::cmp) } - fn max_items_by_key(self, f: F) -> Vec + fn max_items_by_key(self, f: F) -> C where - F: FnMut(&Self::Item) -> B + F: FnMut(&Self::Item) -> B, + C: FromIterator, + { + self.max_items_by_key_map(f, identity) + } + + fn max_items_by_key_map(self, f: F, g: G) -> C + where + F: FnMut(&Self::Item) -> B, + G: FnMut(Self::Item) -> T, + C: FromIterator, { #[inline] fn key(mut f: impl FnMut(&T) -> B) -> impl FnMut(T) -> (B, T) { @@ -22,10 +34,15 @@ pub trait IteratorMaxItems : Iterator + Sized { x_p.cmp(y_p) } + #[inline] + fn snd_map(mut g: impl FnMut(S) -> T) -> impl FnMut((B, S)) -> T { + move |(_, x)| g(x) + } + self.map(key(f)) .max_items_by(compare) .into_iter() - .map(|(_, x)| x) + .map(snd_map(g)) .collect() } @@ -81,6 +98,15 @@ mod tests { #[test] fn multiple_max_items_by_key() { - assert_eq!(vec![&("a", 5), &("e", 5)], [("a", 5), ("b", 4), ("c", 3), ("d", 2), ("e", 5)].iter().max_items_by_key(|&&(_, x)| x)); + let result: Vec<_> = [("a", 5), ("b", 4), ("c", 3), ("d", 2), ("e", 5)].iter() + .max_items_by_key(|&&(_, x)| x); + assert_eq!(vec![&("a", 5), &("e", 5)], result); + } + + #[test] + fn multiple_max_items_by_key_map() { + let result: Vec<_> = [("a", 5), ("b", 4), ("c", 3), ("d", 2), ("e", 5)].iter() + .max_items_by_key_map(|&&(_, x)| x, |&(s, _)| s); + assert_eq!(vec!["a", "e"], result); } }