use self::chatroom::{Chatroom, ChatroomSettings};
use self::whist::{KnockOutWhist, KnockOutWhistSettings};
+use self::poker::{TexasHoldEm, TexasHoldEmSettings};
pub use self::action::{Action, ActionError, UserAction, ValidatedUserAction};
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)),
}
}
}
pub enum GameSettings {
Chatroom(ChatroomSettings),
KnockOutWhist(KnockOutWhistSettings),
+ TexasHoldEm(TexasHoldEmSettings),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
Completed,
}
-#[derive(Clone, Debug)]
+#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct TexasHoldEmSettings {
title: String,
max_players: u32,
}
}
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::<Vec<_>>()))
.filter_map(|(username, cards)| cards.try_into().ok().map(rank_7_card_hand).map(|hand| (username, hand)))
.max_items_by_key(|(_, hand)| *hand);
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};
self.led = None;
self.trick.clear();
if self.tricks_won.values().sum::<u32>() == 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 {
use std::cmp::Ordering;
+use std::convert::identity;
+use std::iter::FromIterator;
pub trait IteratorMaxItems : Iterator + Sized {
fn max_items(self) -> Vec<Self::Item>
self.max_items_by(Ord::cmp)
}
- fn max_items_by_key<B: Ord, F>(self, f: F) -> Vec<Self::Item>
+ fn max_items_by_key<B: Ord, F, C>(self, f: F) -> C
where
- F: FnMut(&Self::Item) -> B
+ F: FnMut(&Self::Item) -> B,
+ C: FromIterator<Self::Item>,
+ {
+ self.max_items_by_key_map(f, identity)
+ }
+
+ fn max_items_by_key_map<B: Ord, F, T, G, C>(self, f: F, g: G) -> C
+ where
+ F: FnMut(&Self::Item) -> B,
+ G: FnMut(Self::Item) -> T,
+ C: FromIterator<T>,
{
#[inline]
fn key<T, B>(mut f: impl FnMut(&T) -> B) -> impl FnMut(T) -> (B, T) {
x_p.cmp(y_p)
}
+ #[inline]
+ fn snd_map<B, S, T>(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()
}
#[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);
}
}