diff --git a/src/game.rs b/src/game.rs index 11d5026..2df7e66 100644 --- a/src/game.rs +++ b/src/game.rs @@ -1,3 +1,5 @@ +use std::collections::HashMap; + use crate::card::{create_deck, draw_card, PlayingCard}; use crate::player::{self, Player}; use rand::Rng; @@ -10,30 +12,62 @@ enum GameStage { } struct BettingPot { - players: Vec>, - pennies: u32, + /// **Key**: Player ID + /// + /// **Value**: Pennies + bets: HashMap, + pot_total: u32, } impl BettingPot { - pub fn distribute(&mut self) { - let player_count = self.players.len() as u32; - let split = self.pennies / player_count; - let remainder = self.pennies % player_count; - for p in &mut self.players { + pub fn new(players: Vec) -> BettingPot { + let mut m: HashMap = HashMap::new(); + for p in players { + m.insert(p, 0); + } + BettingPot { + bets: m, + pot_total: 0, + } + } + + 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; - self.players[num].pay(remainder); + let r: Vec<&u32> = self.bets.keys().collect(); + let p = game.get_player_mut(*r[num]); + p.pay(split); } } } - pub struct PokerGame { players: Vec>, - pots: Vec, + table: Vec, big_blind: u32, // Index of player who should post the Big Blind - pot: u32, // Money in pennies + pots: Vec, stage: GameStage, deck: Vec, } @@ -41,16 +75,60 @@ pub struct PokerGame { impl PokerGame { pub fn new(players: Vec>) -> PokerGame { let first_player = 0; + let mut p_ids: Vec = vec![]; + players.iter().for_each(|p| p_ids.push(p.id())); PokerGame { players, - pots: vec![], + table: vec![], + pots: vec![BettingPot::new(p_ids)], big_blind: 0, - pot: 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 { + self.players + .iter() + .find(|p| p.id() == id) + .expect("No player found!") + } + + pub fn get_player_mut(&mut self, id: u32) -> &mut Box { + self.players + .iter_mut() + .find(|p| p.id() == id) + .expect("No player found!") + } + + pub fn get_bets(&mut self) { + let ids: Vec = self.players.iter().map(|p| p.id()).collect(); + for id in ids { + 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)); + } + self.pots.last_mut().unwrap().add_bet(id, current_bet); + } + player::TurnAction::Raise(_) => todo!(), + } + } + } + pub fn play_stage(&mut self) { match self.stage { GameStage::PreFlop => self.play_preflop(), @@ -70,17 +148,34 @@ impl PokerGame { 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(&self) {} + 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(&self) {} + 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