Compare commits
7 Commits
55fbeb43a0
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 055bd860b2 | |||
| bc1a7380f0 | |||
| a9e90bc447 | |||
| 899edd7c7f | |||
| 6ab8839d6c | |||
| ca47f2df2b | |||
| 30a2280268 |
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"rust-analyzer.showUnlinkedFileNotification": false
|
||||||
|
}
|
||||||
@@ -26,7 +26,7 @@ pub enum CardValue {
|
|||||||
Ace,
|
Ace,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq)]
|
#[derive(PartialEq, Eq, Clone, Copy)]
|
||||||
pub struct PlayingCard {
|
pub struct PlayingCard {
|
||||||
pub value: CardValue,
|
pub value: CardValue,
|
||||||
pub suit: CardSuit,
|
pub suit: CardSuit,
|
||||||
|
|||||||
272
src/game.rs
Normal file
272
src/game.rs
Normal file
@@ -0,0 +1,272 @@
|
|||||||
|
use std::collections::{HashMap, VecDeque};
|
||||||
|
|
||||||
|
use crate::card::{create_deck, draw_card, PlayingCard};
|
||||||
|
use crate::player::{self, Player};
|
||||||
|
use rand::Rng;
|
||||||
|
enum GameStage {
|
||||||
|
PreFlop,
|
||||||
|
Flop,
|
||||||
|
Turn,
|
||||||
|
River,
|
||||||
|
Reveal,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct BettingPot {
|
||||||
|
/// **Key**: Player ID
|
||||||
|
///
|
||||||
|
/// **Value**: Pennies
|
||||||
|
bets: HashMap<u32, u32>,
|
||||||
|
pot_total: u32,
|
||||||
|
/// If there are multiple pots, represents the max value of this pot.
|
||||||
|
/// Calls or raises above this go into the next pot.
|
||||||
|
pot_cap: Option<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BettingPot {
|
||||||
|
pub fn new(players: Vec<u32>, starting_bets: Option<HashMap<u32, u32>>) -> BettingPot {
|
||||||
|
let mut m: HashMap<u32, u32> = starting_bets.unwrap_or_default();
|
||||||
|
for p in players {
|
||||||
|
if !m.contains_key(&p) {
|
||||||
|
m.insert(p, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BettingPot {
|
||||||
|
bets: m,
|
||||||
|
pot_total: 0,
|
||||||
|
pot_cap: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cap_pot(&mut self, pennies: u32) -> HashMap<u32, u32> {
|
||||||
|
self.pot_cap = Some(pennies);
|
||||||
|
let mut new_map: HashMap<u32, u32> = HashMap::new();
|
||||||
|
self.bets.iter_mut().for_each(|bet| {
|
||||||
|
if *bet.1 > pennies {
|
||||||
|
let difference = *bet.1 - pennies;
|
||||||
|
self.pot_total -= difference;
|
||||||
|
*bet.1 = pennies;
|
||||||
|
new_map.insert(*bet.0, difference);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
new_map
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn declare_winner(&self, id: u32, game: &mut PokerGame) {
|
||||||
|
game.get_player_mut(id).pay(self.pot_total);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove_player(&mut self, id: u32) {
|
||||||
|
self.bets.remove(&id);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_bet(&mut self, id: u32, pennies: u32) {
|
||||||
|
if let Some(b) = self.bets.get_mut(&id) {
|
||||||
|
*b += pennies;
|
||||||
|
}
|
||||||
|
self.pot_total += pennies;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_bet(&self, id: u32) -> Option<&u32> {
|
||||||
|
self.bets.get(&id)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn distribute(&mut self, game: &mut PokerGame) {
|
||||||
|
let player_count = self.bets.len() as u32;
|
||||||
|
|
||||||
|
let split = self.pot_total / player_count;
|
||||||
|
let remainder = self.pot_total % player_count;
|
||||||
|
for b in &mut self.bets {
|
||||||
|
let p = game.get_player_mut(*b.0);
|
||||||
|
p.pay(split);
|
||||||
|
}
|
||||||
|
if remainder > 0 {
|
||||||
|
let num = rand::thread_rng().gen_range(0..player_count) as usize;
|
||||||
|
let r: Vec<&u32> = self.bets.keys().collect();
|
||||||
|
let p = game.get_player_mut(*r[num]);
|
||||||
|
p.pay(split);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub struct PokerGame {
|
||||||
|
players: Vec<Box<dyn Player>>,
|
||||||
|
table: Vec<PlayingCard>,
|
||||||
|
big_blind: u32, // Index of player who should post the Big Blind
|
||||||
|
pots: Vec<BettingPot>,
|
||||||
|
stage: GameStage,
|
||||||
|
deck: Vec<PlayingCard>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PokerGame {
|
||||||
|
pub fn new(players: Vec<Box<dyn Player>>) -> PokerGame {
|
||||||
|
let first_player = 0;
|
||||||
|
let mut p_ids: Vec<u32> = vec![];
|
||||||
|
players.iter().for_each(|p| p_ids.push(p.id()));
|
||||||
|
PokerGame {
|
||||||
|
players,
|
||||||
|
table: vec![],
|
||||||
|
pots: vec![BettingPot::new(p_ids, None)],
|
||||||
|
big_blind: 0,
|
||||||
|
stage: GameStage::PreFlop,
|
||||||
|
deck: create_deck(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_player(&mut self, id: u32) {
|
||||||
|
self.players.retain(|p| p.id() != id);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_player(&self, id: u32) -> &Box<dyn Player> {
|
||||||
|
self.players
|
||||||
|
.iter()
|
||||||
|
.find(|p| p.id() == id)
|
||||||
|
.expect("No player found!")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_player_mut(&mut self, id: u32) -> &mut Box<dyn Player> {
|
||||||
|
self.players
|
||||||
|
.iter_mut()
|
||||||
|
.find(|p| p.id() == id)
|
||||||
|
.expect("No player found!")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_bets(&mut self) {
|
||||||
|
let ids: Vec<u32> = self.players.iter().map(|p| p.id()).collect();
|
||||||
|
|
||||||
|
// Queue of players that still need to bet. When this is empty,
|
||||||
|
// all players have placed there bets and the next round is ready to start.
|
||||||
|
let mut bet_queue: VecDeque<u32> = VecDeque::new();
|
||||||
|
self.players
|
||||||
|
.iter()
|
||||||
|
.for_each(|p| bet_queue.push_back(p.id()));
|
||||||
|
|
||||||
|
while !bet_queue.is_empty() {
|
||||||
|
let id = bet_queue.pop_front().unwrap();
|
||||||
|
let action = self.get_player(id).get_move(self);
|
||||||
|
let mut current_bet = 0;
|
||||||
|
match action {
|
||||||
|
player::TurnAction::Fold => {
|
||||||
|
// Remove player from this game
|
||||||
|
self.remove_player(id);
|
||||||
|
// Remove player from all pots
|
||||||
|
self.pots.iter_mut().for_each(|pot| pot.remove_player(id));
|
||||||
|
}
|
||||||
|
player::TurnAction::Call => {
|
||||||
|
if current_bet > 0 {
|
||||||
|
let message = format!("You called ${}.", (current_bet as f64) / 100.0);
|
||||||
|
self.get_player_mut(id).deduct(current_bet, Some(&message));
|
||||||
|
}
|
||||||
|
let mut bet = current_bet.clone();
|
||||||
|
self.pots.iter_mut().for_each(|pot| match pot.pot_cap {
|
||||||
|
Some(cap) => {
|
||||||
|
if cap > bet {
|
||||||
|
panic!("There's something wrong with the logic, bet is less than the cap??");
|
||||||
|
}
|
||||||
|
pot.add_bet(id, cap);
|
||||||
|
bet -= cap;
|
||||||
|
},
|
||||||
|
None => {
|
||||||
|
if bet > 0 {
|
||||||
|
pot.add_bet(id, bet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
self.pots.last_mut().unwrap().add_bet(id, current_bet);
|
||||||
|
}
|
||||||
|
player::TurnAction::AllIn(amount) => {
|
||||||
|
// Remove money from player and add it to the pot
|
||||||
|
let message = format!(
|
||||||
|
"You went all in with your last ${}.",
|
||||||
|
(current_bet as f64) / 100.0
|
||||||
|
);
|
||||||
|
self.get_player_mut(id).deduct(amount, Some(&message));
|
||||||
|
self.pots.last_mut().unwrap().add_bet(id, amount);
|
||||||
|
|
||||||
|
// Take the difference between the current bet and create a new pot
|
||||||
|
let pot_cap = *self.pots.last().unwrap().bets.get(&id).unwrap();
|
||||||
|
let new_betmap = self.pots.last_mut().unwrap().cap_pot(pot_cap);
|
||||||
|
let new_pot_players: Vec<u32> = self
|
||||||
|
.players
|
||||||
|
.iter()
|
||||||
|
.filter(|p| p.id() != id)
|
||||||
|
.map(|p| p.id())
|
||||||
|
.collect();
|
||||||
|
let new_pot = BettingPot::new(new_pot_players, Some(new_betmap));
|
||||||
|
self.pots.push(new_pot);
|
||||||
|
}
|
||||||
|
player::TurnAction::Raise(raise) => {
|
||||||
|
// New current bet
|
||||||
|
current_bet = current_bet + raise;
|
||||||
|
let message = format!("You raised ${}.", (current_bet as f64) / 100.0);
|
||||||
|
|
||||||
|
// Remove money from player
|
||||||
|
self.get_player_mut(id).deduct(current_bet, Some(&message));
|
||||||
|
|
||||||
|
// Add money to current pot
|
||||||
|
self.pots.last_mut().unwrap().add_bet(id, current_bet);
|
||||||
|
|
||||||
|
// Reset queue of players waiting to bet.
|
||||||
|
// Everyone now has to decide whether to match the raise.
|
||||||
|
self.players.iter().for_each(|p| {
|
||||||
|
if !bet_queue.contains(&p.id()) && p.id() != id {
|
||||||
|
bet_queue.push_back(p.id())
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn play_stage(&mut self) {
|
||||||
|
match self.stage {
|
||||||
|
GameStage::PreFlop => self.play_preflop(),
|
||||||
|
GameStage::Flop => self.play_flop(),
|
||||||
|
GameStage::Turn => self.play_turn_or_river(),
|
||||||
|
GameStage::River => self.play_turn_or_river(),
|
||||||
|
GameStage::Reveal => self.play_reveal(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Preflop:
|
||||||
|
/// - Deal cards to all of the players
|
||||||
|
/// - Collect big and small blinds
|
||||||
|
/// - Players make their first round of actions
|
||||||
|
fn play_preflop(&mut self) {
|
||||||
|
for player in &mut self.players {
|
||||||
|
let dealt_cards = vec![draw_card(&mut self.deck), draw_card(&mut self.deck)];
|
||||||
|
player.deal_cards(dealt_cards);
|
||||||
|
}
|
||||||
|
self.get_bets();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Flop:
|
||||||
|
/// - Play three cards to the table
|
||||||
|
/// - Players make a round of bets
|
||||||
|
fn play_flop(&mut self) {
|
||||||
|
println!("The Flop:");
|
||||||
|
let mut flop_cards = vec![];
|
||||||
|
for _ in 0..3 {
|
||||||
|
let card = draw_card(&mut self.deck);
|
||||||
|
println!("{}", card);
|
||||||
|
flop_cards.push(card);
|
||||||
|
}
|
||||||
|
flop_cards.iter_mut().for_each(|c| self.table.push(*c));
|
||||||
|
self.get_bets();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Turn:
|
||||||
|
/// - Play another card to the table
|
||||||
|
/// - Players make a round of bets
|
||||||
|
fn play_turn_or_river(&mut self) {
|
||||||
|
println!("Next up:");
|
||||||
|
let card = draw_card(&mut self.deck);
|
||||||
|
println!("{}", card);
|
||||||
|
self.table.push(card);
|
||||||
|
self.get_bets();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reveal:
|
||||||
|
/// - All players cards are revealed
|
||||||
|
/// - Hands are compared, winner is decided
|
||||||
|
/// - Payout is presented
|
||||||
|
fn play_reveal(&self) {}
|
||||||
|
}
|
||||||
435
src/hand.rs
435
src/hand.rs
@@ -2,7 +2,7 @@ use crate::card::{CardValue, PlayingCard};
|
|||||||
use core::fmt;
|
use core::fmt;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Ord, PartialOrd)]
|
#[derive(Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Debug)]
|
||||||
pub enum HandType {
|
pub enum HandType {
|
||||||
HighCard,
|
HighCard,
|
||||||
OnePair,
|
OnePair,
|
||||||
@@ -16,7 +16,7 @@ pub enum HandType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq)]
|
#[derive(PartialEq)]
|
||||||
struct PokerHand {
|
pub struct PokerHand {
|
||||||
cards: Vec<PlayingCard>,
|
cards: Vec<PlayingCard>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,7 +47,7 @@ impl fmt::Display for PokerHand {
|
|||||||
|
|
||||||
impl PartialOrd for PokerHand {
|
impl PartialOrd for PokerHand {
|
||||||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||||
if self.hand_type() > other.hand_type() {
|
if self.hand_type() != other.hand_type() {
|
||||||
return self.hand_type().partial_cmp(&other.hand_type());
|
return self.hand_type().partial_cmp(&other.hand_type());
|
||||||
}
|
}
|
||||||
let selfmap = self.hash_map();
|
let selfmap = self.hash_map();
|
||||||
@@ -143,7 +143,7 @@ impl PartialOrd for PokerHand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl PokerHand {
|
impl PokerHand {
|
||||||
fn new(mut cards: Vec<PlayingCard>) -> Self {
|
pub fn new(mut cards: Vec<PlayingCard>) -> Self {
|
||||||
assert!(cards.len() == 5);
|
assert!(cards.len() == 5);
|
||||||
|
|
||||||
// Sorted highest card first
|
// Sorted highest card first
|
||||||
@@ -172,7 +172,7 @@ impl PokerHand {
|
|||||||
count
|
count
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hand_type(&self) -> HandType {
|
pub fn hand_type(&self) -> HandType {
|
||||||
if is_straight_flush(self) {
|
if is_straight_flush(self) {
|
||||||
return HandType::StraightFlush;
|
return HandType::StraightFlush;
|
||||||
}
|
}
|
||||||
@@ -214,8 +214,8 @@ fn is_straight_flush(hand: &PokerHand) -> bool {
|
|||||||
assert!(hand.len() == 5);
|
assert!(hand.len() == 5);
|
||||||
|
|
||||||
let suit = hand[0].suit;
|
let suit = hand[0].suit;
|
||||||
let mut min_val = CardValue::Two;
|
let mut min_val = CardValue::Ace;
|
||||||
let mut max_val = CardValue::Ace;
|
let mut max_val = CardValue::Two;
|
||||||
|
|
||||||
// Must all be the same suit
|
// Must all be the same suit
|
||||||
for i in 0..5 {
|
for i in 0..5 {
|
||||||
@@ -294,7 +294,7 @@ fn is_flush(hand: &PokerHand) -> bool {
|
|||||||
fn is_straight(hand: &PokerHand) -> bool {
|
fn is_straight(hand: &PokerHand) -> bool {
|
||||||
for i in 1..4 {
|
for i in 1..4 {
|
||||||
let current_card = hand.cards[i].value as u8;
|
let current_card = hand.cards[i].value as u8;
|
||||||
let previous_card = hand.cards[i].value as u8;
|
let previous_card = hand.cards[i - 1].value as u8;
|
||||||
if current_card != previous_card - 1 {
|
if current_card != previous_card - 1 {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -325,3 +325,422 @@ fn is_one_pair(hand: &PokerHand) -> bool {
|
|||||||
// https://stackoverflow.com/questions/45353757/how-to-count-the-elements-in-a-vector-with-some-value-without-looping
|
// https://stackoverflow.com/questions/45353757/how-to-count-the-elements-in-a-vector-with-some-value-without-looping
|
||||||
count.iter().filter(|&n| *n == 2).count() == 1
|
count.iter().filter(|&n| *n == 2).count() == 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::card::CardSuit;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn one_pair_test() {
|
||||||
|
let card1 = PlayingCard {
|
||||||
|
suit: CardSuit::Clubs,
|
||||||
|
value: CardValue::Ace,
|
||||||
|
};
|
||||||
|
let card2 = PlayingCard {
|
||||||
|
suit: CardSuit::Diamonds,
|
||||||
|
value: CardValue::Ace,
|
||||||
|
};
|
||||||
|
let card3 = PlayingCard {
|
||||||
|
suit: CardSuit::Diamonds,
|
||||||
|
value: CardValue::Two,
|
||||||
|
};
|
||||||
|
let card4 = PlayingCard {
|
||||||
|
suit: CardSuit::Diamonds,
|
||||||
|
value: CardValue::Five,
|
||||||
|
};
|
||||||
|
let card5 = PlayingCard {
|
||||||
|
suit: CardSuit::Diamonds,
|
||||||
|
value: CardValue::Eight,
|
||||||
|
};
|
||||||
|
|
||||||
|
let pair = vec![card1, card2, card3, card4, card5];
|
||||||
|
let hand = PokerHand::new(pair);
|
||||||
|
assert_eq!(hand.hand_type(), HandType::OnePair);
|
||||||
|
|
||||||
|
let card1 = PlayingCard {
|
||||||
|
suit: CardSuit::Clubs,
|
||||||
|
value: CardValue::Ace,
|
||||||
|
};
|
||||||
|
let card2 = PlayingCard {
|
||||||
|
suit: CardSuit::Diamonds,
|
||||||
|
value: CardValue::King,
|
||||||
|
};
|
||||||
|
let card3 = PlayingCard {
|
||||||
|
suit: CardSuit::Diamonds,
|
||||||
|
value: CardValue::Two,
|
||||||
|
};
|
||||||
|
let card4 = PlayingCard {
|
||||||
|
suit: CardSuit::Diamonds,
|
||||||
|
value: CardValue::Five,
|
||||||
|
};
|
||||||
|
let card5 = PlayingCard {
|
||||||
|
suit: CardSuit::Diamonds,
|
||||||
|
value: CardValue::Eight,
|
||||||
|
};
|
||||||
|
|
||||||
|
let nopair = vec![card1, card2, card3, card4, card5];
|
||||||
|
let hand = PokerHand::new(nopair);
|
||||||
|
assert_eq!(hand.hand_type(), HandType::HighCard);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn two_pair_test() {
|
||||||
|
let card1 = PlayingCard {
|
||||||
|
suit: CardSuit::Clubs,
|
||||||
|
value: CardValue::Ace,
|
||||||
|
};
|
||||||
|
let card2 = PlayingCard {
|
||||||
|
suit: CardSuit::Diamonds,
|
||||||
|
value: CardValue::Ace,
|
||||||
|
};
|
||||||
|
let card3 = PlayingCard {
|
||||||
|
suit: CardSuit::Diamonds,
|
||||||
|
value: CardValue::Two,
|
||||||
|
};
|
||||||
|
let card4 = PlayingCard {
|
||||||
|
suit: CardSuit::Diamonds,
|
||||||
|
value: CardValue::Five,
|
||||||
|
};
|
||||||
|
let card5 = PlayingCard {
|
||||||
|
suit: CardSuit::Diamonds,
|
||||||
|
value: CardValue::Five,
|
||||||
|
};
|
||||||
|
|
||||||
|
let pair = vec![card1, card2, card3, card4, card5];
|
||||||
|
let hand = PokerHand::new(pair);
|
||||||
|
assert_eq!(hand.hand_type(), HandType::TwoPair);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn three_of_a_kind_tests() {
|
||||||
|
let card1 = PlayingCard {
|
||||||
|
suit: CardSuit::Clubs,
|
||||||
|
value: CardValue::Ace,
|
||||||
|
};
|
||||||
|
let card2 = PlayingCard {
|
||||||
|
suit: CardSuit::Diamonds,
|
||||||
|
value: CardValue::Ace,
|
||||||
|
};
|
||||||
|
let card3 = PlayingCard {
|
||||||
|
suit: CardSuit::Spades,
|
||||||
|
value: CardValue::Ace,
|
||||||
|
};
|
||||||
|
let card4 = PlayingCard {
|
||||||
|
suit: CardSuit::Diamonds,
|
||||||
|
value: CardValue::Five,
|
||||||
|
};
|
||||||
|
let card5 = PlayingCard {
|
||||||
|
suit: CardSuit::Diamonds,
|
||||||
|
value: CardValue::Two,
|
||||||
|
};
|
||||||
|
|
||||||
|
let pair = vec![card1, card2, card3, card4, card5];
|
||||||
|
let hand = PokerHand::new(pair);
|
||||||
|
assert_eq!(hand.hand_type(), HandType::ThreeOfAKind);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn staight_test() {
|
||||||
|
let card1 = PlayingCard {
|
||||||
|
suit: CardSuit::Clubs,
|
||||||
|
value: CardValue::Six,
|
||||||
|
};
|
||||||
|
let card2 = PlayingCard {
|
||||||
|
suit: CardSuit::Diamonds,
|
||||||
|
value: CardValue::Eight,
|
||||||
|
};
|
||||||
|
let card3 = PlayingCard {
|
||||||
|
suit: CardSuit::Spades,
|
||||||
|
value: CardValue::Seven,
|
||||||
|
};
|
||||||
|
let card4 = PlayingCard {
|
||||||
|
suit: CardSuit::Diamonds,
|
||||||
|
value: CardValue::Five,
|
||||||
|
};
|
||||||
|
let card5 = PlayingCard {
|
||||||
|
suit: CardSuit::Diamonds,
|
||||||
|
value: CardValue::Nine,
|
||||||
|
};
|
||||||
|
|
||||||
|
let pair = vec![card1, card2, card3, card4, card5];
|
||||||
|
let hand = PokerHand::new(pair);
|
||||||
|
assert_eq!(hand.hand_type(), HandType::Straight);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn flush_test() {
|
||||||
|
let card1 = PlayingCard {
|
||||||
|
suit: CardSuit::Clubs,
|
||||||
|
value: CardValue::Six,
|
||||||
|
};
|
||||||
|
let card2 = PlayingCard {
|
||||||
|
suit: CardSuit::Clubs,
|
||||||
|
value: CardValue::Two,
|
||||||
|
};
|
||||||
|
let card3 = PlayingCard {
|
||||||
|
suit: CardSuit::Clubs,
|
||||||
|
value: CardValue::Queen,
|
||||||
|
};
|
||||||
|
let card4 = PlayingCard {
|
||||||
|
suit: CardSuit::Clubs,
|
||||||
|
value: CardValue::Jack,
|
||||||
|
};
|
||||||
|
let card5 = PlayingCard {
|
||||||
|
suit: CardSuit::Clubs,
|
||||||
|
value: CardValue::Ace,
|
||||||
|
};
|
||||||
|
|
||||||
|
let pair = vec![card1, card2, card3, card4, card5];
|
||||||
|
let hand = PokerHand::new(pair);
|
||||||
|
assert_eq!(hand.hand_type(), HandType::Flush);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn full_house_test() {
|
||||||
|
let card1 = PlayingCard {
|
||||||
|
suit: CardSuit::Diamonds,
|
||||||
|
value: CardValue::Six,
|
||||||
|
};
|
||||||
|
let card2 = PlayingCard {
|
||||||
|
suit: CardSuit::Clubs,
|
||||||
|
value: CardValue::Six,
|
||||||
|
};
|
||||||
|
let card3 = PlayingCard {
|
||||||
|
suit: CardSuit::Spades,
|
||||||
|
value: CardValue::Two,
|
||||||
|
};
|
||||||
|
let card4 = PlayingCard {
|
||||||
|
suit: CardSuit::Clubs,
|
||||||
|
value: CardValue::Six,
|
||||||
|
};
|
||||||
|
let card5 = PlayingCard {
|
||||||
|
suit: CardSuit::Clubs,
|
||||||
|
value: CardValue::Two,
|
||||||
|
};
|
||||||
|
|
||||||
|
let pair = vec![card1, card2, card3, card4, card5];
|
||||||
|
let hand = PokerHand::new(pair);
|
||||||
|
assert_eq!(hand.hand_type(), HandType::FullHouse);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn four_of_a_kind_test() {
|
||||||
|
let card1 = PlayingCard {
|
||||||
|
suit: CardSuit::Diamonds,
|
||||||
|
value: CardValue::Six,
|
||||||
|
};
|
||||||
|
let card2 = PlayingCard {
|
||||||
|
suit: CardSuit::Clubs,
|
||||||
|
value: CardValue::Six,
|
||||||
|
};
|
||||||
|
let card3 = PlayingCard {
|
||||||
|
suit: CardSuit::Spades,
|
||||||
|
value: CardValue::Six,
|
||||||
|
};
|
||||||
|
let card4 = PlayingCard {
|
||||||
|
suit: CardSuit::Clubs,
|
||||||
|
value: CardValue::Six,
|
||||||
|
};
|
||||||
|
let card5 = PlayingCard {
|
||||||
|
suit: CardSuit::Clubs,
|
||||||
|
value: CardValue::Two,
|
||||||
|
};
|
||||||
|
|
||||||
|
let pair = vec![card1, card2, card3, card4, card5];
|
||||||
|
let hand = PokerHand::new(pair);
|
||||||
|
assert_eq!(hand.hand_type(), HandType::FourOfAKind);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn straight_flush_test() {
|
||||||
|
let card1 = PlayingCard {
|
||||||
|
suit: CardSuit::Diamonds,
|
||||||
|
value: CardValue::Jack,
|
||||||
|
};
|
||||||
|
let card2 = PlayingCard {
|
||||||
|
suit: CardSuit::Diamonds,
|
||||||
|
value: CardValue::Ten,
|
||||||
|
};
|
||||||
|
let card3 = PlayingCard {
|
||||||
|
suit: CardSuit::Diamonds,
|
||||||
|
value: CardValue::Nine,
|
||||||
|
};
|
||||||
|
let card4 = PlayingCard {
|
||||||
|
suit: CardSuit::Diamonds,
|
||||||
|
value: CardValue::Seven,
|
||||||
|
};
|
||||||
|
let card5 = PlayingCard {
|
||||||
|
suit: CardSuit::Diamonds,
|
||||||
|
value: CardValue::Eight,
|
||||||
|
};
|
||||||
|
|
||||||
|
let pair = vec![card1, card2, card3, card4, card5];
|
||||||
|
let hand = PokerHand::new(pair);
|
||||||
|
assert_eq!(hand.hand_type(), HandType::StraightFlush);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn comp_test1() {
|
||||||
|
// Hand 1
|
||||||
|
let card1 = PlayingCard {
|
||||||
|
suit: CardSuit::Diamonds,
|
||||||
|
value: CardValue::Jack,
|
||||||
|
};
|
||||||
|
let card2 = PlayingCard {
|
||||||
|
suit: CardSuit::Diamonds,
|
||||||
|
value: CardValue::Jack,
|
||||||
|
};
|
||||||
|
let card3 = PlayingCard {
|
||||||
|
suit: CardSuit::Diamonds,
|
||||||
|
value: CardValue::Nine,
|
||||||
|
};
|
||||||
|
let card4 = PlayingCard {
|
||||||
|
suit: CardSuit::Diamonds,
|
||||||
|
value: CardValue::Ace,
|
||||||
|
};
|
||||||
|
let card5 = PlayingCard {
|
||||||
|
suit: CardSuit::Diamonds,
|
||||||
|
value: CardValue::Eight,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Hand 2
|
||||||
|
let card6 = PlayingCard {
|
||||||
|
suit: CardSuit::Diamonds,
|
||||||
|
value: CardValue::Queen,
|
||||||
|
};
|
||||||
|
let card7 = PlayingCard {
|
||||||
|
suit: CardSuit::Clubs,
|
||||||
|
value: CardValue::Ten,
|
||||||
|
};
|
||||||
|
let card8 = PlayingCard {
|
||||||
|
suit: CardSuit::Diamonds,
|
||||||
|
value: CardValue::Queen,
|
||||||
|
};
|
||||||
|
let card9 = PlayingCard {
|
||||||
|
suit: CardSuit::Diamonds,
|
||||||
|
value: CardValue::Two,
|
||||||
|
};
|
||||||
|
let card10 = PlayingCard {
|
||||||
|
suit: CardSuit::Diamonds,
|
||||||
|
value: CardValue::Eight,
|
||||||
|
};
|
||||||
|
|
||||||
|
let cardset1 = vec![card1, card2, card3, card4, card5];
|
||||||
|
let cardset2 = vec![card6, card7, card8, card9, card10];
|
||||||
|
let flush = PokerHand::new(cardset1);
|
||||||
|
let onepair = PokerHand::new(cardset2);
|
||||||
|
assert!(flush > onepair);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn straight_flush_ord_test() {
|
||||||
|
// Hand 1
|
||||||
|
let card1 = PlayingCard {
|
||||||
|
suit: CardSuit::Clubs,
|
||||||
|
value: CardValue::Jack,
|
||||||
|
};
|
||||||
|
let card2 = PlayingCard {
|
||||||
|
suit: CardSuit::Diamonds,
|
||||||
|
value: CardValue::Ten,
|
||||||
|
};
|
||||||
|
let card3 = PlayingCard {
|
||||||
|
suit: CardSuit::Diamonds,
|
||||||
|
value: CardValue::Nine,
|
||||||
|
};
|
||||||
|
let card4 = PlayingCard {
|
||||||
|
suit: CardSuit::Diamonds,
|
||||||
|
value: CardValue::Eight,
|
||||||
|
};
|
||||||
|
let card5 = PlayingCard {
|
||||||
|
suit: CardSuit::Diamonds,
|
||||||
|
value: CardValue::Seven,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Hand 2
|
||||||
|
let card6 = PlayingCard {
|
||||||
|
suit: CardSuit::Diamonds,
|
||||||
|
value: CardValue::Queen,
|
||||||
|
};
|
||||||
|
let card7 = PlayingCard {
|
||||||
|
suit: CardSuit::Clubs,
|
||||||
|
value: CardValue::Jack,
|
||||||
|
};
|
||||||
|
let card8 = PlayingCard {
|
||||||
|
suit: CardSuit::Diamonds,
|
||||||
|
value: CardValue::Ten,
|
||||||
|
};
|
||||||
|
let card9 = PlayingCard {
|
||||||
|
suit: CardSuit::Diamonds,
|
||||||
|
value: CardValue::Nine,
|
||||||
|
};
|
||||||
|
let card10 = PlayingCard {
|
||||||
|
suit: CardSuit::Diamonds,
|
||||||
|
value: CardValue::Eight,
|
||||||
|
};
|
||||||
|
|
||||||
|
let cardset1 = vec![card1, card2, card3, card4, card5];
|
||||||
|
let cardset2 = vec![card6, card7, card8, card9, card10];
|
||||||
|
let hand1 = PokerHand::new(cardset1);
|
||||||
|
let hand2 = PokerHand::new(cardset2);
|
||||||
|
assert!(hand1 < hand2);
|
||||||
|
assert!(hand1 >= hand1);
|
||||||
|
assert!(hand2 <= hand2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn four_kind_ord_test() {
|
||||||
|
// Hand 1
|
||||||
|
let card1 = PlayingCard {
|
||||||
|
suit: CardSuit::Clubs,
|
||||||
|
value: CardValue::Jack,
|
||||||
|
};
|
||||||
|
let card2 = PlayingCard {
|
||||||
|
suit: CardSuit::Hearts,
|
||||||
|
value: CardValue::Jack,
|
||||||
|
};
|
||||||
|
let card3 = PlayingCard {
|
||||||
|
suit: CardSuit::Diamonds,
|
||||||
|
value: CardValue::Jack,
|
||||||
|
};
|
||||||
|
let card4 = PlayingCard {
|
||||||
|
suit: CardSuit::Spades,
|
||||||
|
value: CardValue::Jack,
|
||||||
|
};
|
||||||
|
let card5 = PlayingCard {
|
||||||
|
suit: CardSuit::Diamonds,
|
||||||
|
value: CardValue::Seven,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Hand 2
|
||||||
|
let card6 = PlayingCard {
|
||||||
|
suit: CardSuit::Spades,
|
||||||
|
value: CardValue::Queen,
|
||||||
|
};
|
||||||
|
let card7 = PlayingCard {
|
||||||
|
suit: CardSuit::Hearts,
|
||||||
|
value: CardValue::Queen,
|
||||||
|
};
|
||||||
|
let card8 = PlayingCard {
|
||||||
|
suit: CardSuit::Clubs,
|
||||||
|
value: CardValue::Queen,
|
||||||
|
};
|
||||||
|
let card9 = PlayingCard {
|
||||||
|
suit: CardSuit::Diamonds,
|
||||||
|
value: CardValue::Queen,
|
||||||
|
};
|
||||||
|
let card10 = PlayingCard {
|
||||||
|
suit: CardSuit::Diamonds,
|
||||||
|
value: CardValue::Eight,
|
||||||
|
};
|
||||||
|
|
||||||
|
let cardset1 = vec![card1, card2, card3, card4, card5];
|
||||||
|
let cardset2 = vec![card6, card7, card8, card9, card10];
|
||||||
|
let hand1 = PokerHand::new(cardset1);
|
||||||
|
let hand2 = PokerHand::new(cardset2);
|
||||||
|
assert!(hand1 < hand2);
|
||||||
|
assert!(hand1 >= hand1);
|
||||||
|
assert!(hand2 <= hand2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,15 +1,17 @@
|
|||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
#![allow(unused_variables)]
|
||||||
use std::vec;
|
use std::vec;
|
||||||
|
|
||||||
mod card;
|
mod card;
|
||||||
|
mod game;
|
||||||
mod hand;
|
mod hand;
|
||||||
|
mod player;
|
||||||
|
|
||||||
use crate::card::{create_deck, CardSuit, CardValue, PlayingCard};
|
use crate::card::{create_deck, CardSuit, CardValue, PlayingCard};
|
||||||
use crate::hand::HandType;
|
use crate::hand::HandType;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut deck = create_deck();
|
let deck = create_deck();
|
||||||
|
|
||||||
let card1: PlayingCard = PlayingCard {
|
let card1: PlayingCard = PlayingCard {
|
||||||
suit: CardSuit::Clubs,
|
suit: CardSuit::Clubs,
|
||||||
|
|||||||
279
src/player.rs
Normal file
279
src/player.rs
Normal file
@@ -0,0 +1,279 @@
|
|||||||
|
use crate::card::PlayingCard;
|
||||||
|
use crate::game::PokerGame;
|
||||||
|
use crate::hand::PokerHand;
|
||||||
|
use std::io;
|
||||||
|
|
||||||
|
pub enum TurnAction {
|
||||||
|
Fold,
|
||||||
|
Call,
|
||||||
|
AllIn(u32),
|
||||||
|
Raise(u32),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Player {
|
||||||
|
fn id(&self) -> u32;
|
||||||
|
fn display_name(&self) -> &str;
|
||||||
|
fn deal_cards(&mut self, cards: Vec<PlayingCard>);
|
||||||
|
fn get_move(&self, game_state: &PokerGame) -> TurnAction;
|
||||||
|
fn money(&self) -> u32;
|
||||||
|
fn pay(&mut self, pennies: u32);
|
||||||
|
fn deduct(&mut self, pennies: u32, message: Option<&str>);
|
||||||
|
fn get_hand(&self, table: Vec<PlayingCard>) -> PokerHand;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct HumanPlayer {
|
||||||
|
id: u32,
|
||||||
|
name: String,
|
||||||
|
money: u32,
|
||||||
|
cards: Vec<PlayingCard>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HumanPlayer {
|
||||||
|
pub fn new(money: u32, id: u32) -> HumanPlayer {
|
||||||
|
let mut user_input = String::new();
|
||||||
|
print!("Enter your name\n> ");
|
||||||
|
let stdin = io::stdin();
|
||||||
|
let _ = stdin.read_line(&mut user_input);
|
||||||
|
HumanPlayer {
|
||||||
|
id,
|
||||||
|
name: user_input,
|
||||||
|
money,
|
||||||
|
cards: vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Player for HumanPlayer {
|
||||||
|
fn id(&self) -> u32 {
|
||||||
|
self.id
|
||||||
|
}
|
||||||
|
|
||||||
|
fn display_name(&self) -> &str {
|
||||||
|
&self.name
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deal_cards(&mut self, mut cards: Vec<PlayingCard>) {
|
||||||
|
self.cards.clear();
|
||||||
|
self.cards.append(&mut cards);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_move(&self, game_state: &PokerGame) -> TurnAction {
|
||||||
|
let mut user_input = String::new();
|
||||||
|
let stdin = io::stdin();
|
||||||
|
loop {
|
||||||
|
print!("What would you like to do?\nR: Raise\nC: Call\n:F\n Fold\n> ");
|
||||||
|
let _ = stdin.read_line(&mut user_input);
|
||||||
|
if user_input.len() == 0 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let first_char = user_input.to_lowercase().chars().next().unwrap();
|
||||||
|
match first_char {
|
||||||
|
'f' => {
|
||||||
|
return TurnAction::Fold;
|
||||||
|
}
|
||||||
|
'r' => {
|
||||||
|
return TurnAction::Raise(self.get_raise());
|
||||||
|
}
|
||||||
|
'c' => {
|
||||||
|
return TurnAction::Call;
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn money(&self) -> u32 {
|
||||||
|
self.money
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pay(&mut self, pennies: u32) {
|
||||||
|
self.money = self.money + pennies;
|
||||||
|
println!("You received ${}.", (pennies as f64) / 100.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deduct(&mut self, pennies: u32, message: Option<&str>) {
|
||||||
|
if pennies > self.money {
|
||||||
|
panic!("Deducted more money than the player had!");
|
||||||
|
}
|
||||||
|
self.money = self.money - pennies;
|
||||||
|
if message.is_some() {
|
||||||
|
println!("{}", message.unwrap().to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_hand(&self, table: Vec<PlayingCard>) -> PokerHand {
|
||||||
|
let mut table_clone = table.clone();
|
||||||
|
let mut total_cards = self.cards.clone();
|
||||||
|
total_cards.append(&mut table_clone);
|
||||||
|
PokerHand::new(total_cards)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HumanPlayer {
|
||||||
|
fn get_raise(&self) -> u32 {
|
||||||
|
let mut user_input: String = String::new();
|
||||||
|
let stdin = io::stdin();
|
||||||
|
loop {
|
||||||
|
print!("Enter your raise.\n> ");
|
||||||
|
let _ = stdin.read_line(&mut user_input);
|
||||||
|
let user_input = user_input.replace("$", "");
|
||||||
|
if user_input.len() == 0 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let money = user_input.parse::<f64>();
|
||||||
|
match money {
|
||||||
|
Ok(_) => {
|
||||||
|
let pennies = (money.unwrap() * 100.0).floor() as u32;
|
||||||
|
if pennies > self.money {
|
||||||
|
println!("You flat-footed dingus, you don't have that much money!");
|
||||||
|
}
|
||||||
|
return pennies;
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
print!("That's not a number, dufus. What, are you trying to bet your bitcoin wallet or something? Enter a number.\n>");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct RemotePlayer {
|
||||||
|
id: u32,
|
||||||
|
name: String,
|
||||||
|
money: u32,
|
||||||
|
cards: Vec<PlayingCard>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RemotePlayer {
|
||||||
|
pub fn new(name: &str, money: u32, id: u32) -> RemotePlayer {
|
||||||
|
RemotePlayer {
|
||||||
|
id,
|
||||||
|
name: name.to_string(),
|
||||||
|
money,
|
||||||
|
cards: vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Player for RemotePlayer {
|
||||||
|
fn id(&self) -> u32 {
|
||||||
|
self.id
|
||||||
|
}
|
||||||
|
|
||||||
|
fn display_name(&self) -> &str {
|
||||||
|
&self.name
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deal_cards(&mut self, mut cards: Vec<PlayingCard>) {
|
||||||
|
self.cards.clear();
|
||||||
|
self.cards.append(&mut cards);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_move(&self, game_state: &PokerGame) -> TurnAction {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn money(&self) -> u32 {
|
||||||
|
self.money
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pay(&mut self, pennies: u32) {
|
||||||
|
self.money = self.money + pennies;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deduct(&mut self, pennies: u32, message: Option<&str>) {
|
||||||
|
if pennies > self.money {
|
||||||
|
panic!("Deducted more money than the player had!");
|
||||||
|
}
|
||||||
|
self.money = self.money - pennies;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_hand(&self, table: Vec<PlayingCard>) -> PokerHand {
|
||||||
|
let mut table_clone = table.clone();
|
||||||
|
let mut total_cards = self.cards.clone();
|
||||||
|
total_cards.append(&mut table_clone);
|
||||||
|
PokerHand::new(total_cards)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct BotPlayer {
|
||||||
|
id: u32,
|
||||||
|
name: String,
|
||||||
|
money: u32,
|
||||||
|
cards: Vec<PlayingCard>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BotPlayer {
|
||||||
|
pub fn new(name: &str, money: u32, id: u32) -> BotPlayer {
|
||||||
|
BotPlayer {
|
||||||
|
id,
|
||||||
|
name: format!("[BOT] {}", name.to_string()),
|
||||||
|
money,
|
||||||
|
cards: vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Player for BotPlayer {
|
||||||
|
fn id(&self) -> u32 {
|
||||||
|
self.id
|
||||||
|
}
|
||||||
|
|
||||||
|
fn display_name(&self) -> &str {
|
||||||
|
&self.name
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deal_cards(&mut self, mut cards: Vec<PlayingCard>) {
|
||||||
|
self.cards.clear();
|
||||||
|
self.cards.append(&mut cards);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_move(&self, game_state: &PokerGame) -> TurnAction {
|
||||||
|
return TurnAction::Fold;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn money(&self) -> u32 {
|
||||||
|
self.money
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pay(&mut self, pennies: u32) {
|
||||||
|
self.money = self.money + pennies;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deduct(&mut self, pennies: u32, message: Option<&str>) {
|
||||||
|
if pennies > self.money {
|
||||||
|
panic!("Deducted more money than the player had!");
|
||||||
|
}
|
||||||
|
self.money = self.money - pennies;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_hand(&self, table: Vec<PlayingCard>) -> PokerHand {
|
||||||
|
let mut table_clone = table.clone();
|
||||||
|
let mut total_cards = self.cards.clone();
|
||||||
|
total_cards.append(&mut table_clone);
|
||||||
|
PokerHand::new(total_cards)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ling Lallister
|
||||||
|
// Bao Amdahl
|
||||||
|
// Troy Cyberson
|
||||||
|
// Turbo Pocket
|
||||||
|
// Frances Netwall
|
||||||
|
// Nate Packer
|
||||||
|
// Lela Bacon
|
||||||
|
// Hinge Romton
|
||||||
|
// Deming Stellis
|
||||||
|
// Ryker Dedex
|
||||||
|
// Lillix Borg
|
||||||
|
// Alan Onishi
|
||||||
|
// Leeloo Phiser
|
||||||
|
// Cloud Sine
|
||||||
|
// Han Onishi
|
||||||
|
// Magda Hertz
|
||||||
|
// Akira Gallister
|
||||||
|
// Groat
|
||||||
|
// Tim
|
||||||
Reference in New Issue
Block a user