Rewriting things based on traits!
This commit is contained in:
35
src/game.rs
35
src/game.rs
@@ -1,7 +1,6 @@
|
|||||||
use crate::{
|
use crate::card::{create_deck, draw_card, PlayingCard};
|
||||||
card::{create_deck, draw_card, PlayingCard},
|
use crate::player::{self, Player};
|
||||||
pokerplayer::PokerPlayer,
|
use rand::Rng;
|
||||||
};
|
|
||||||
enum GameStage {
|
enum GameStage {
|
||||||
PreFlop,
|
PreFlop,
|
||||||
Flop,
|
Flop,
|
||||||
@@ -10,8 +9,29 @@ enum GameStage {
|
|||||||
Reveal,
|
Reveal,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PokerGame {
|
struct BettingPot {
|
||||||
players: Vec<PokerPlayer>,
|
players: Vec<Box<dyn Player>>,
|
||||||
|
pennies: 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 {
|
||||||
|
p.pay(split);
|
||||||
|
}
|
||||||
|
if remainder > 0 {
|
||||||
|
let num = rand::thread_rng().gen_range(0..player_count) as usize;
|
||||||
|
self.players[num].pay(remainder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct PokerGame {
|
||||||
|
players: Vec<Box<dyn Player>>,
|
||||||
|
pots: Vec<BettingPot>,
|
||||||
big_blind: u32, // Index of player who should post the Big Blind
|
big_blind: u32, // Index of player who should post the Big Blind
|
||||||
pot: u32, // Money in pennies
|
pot: u32, // Money in pennies
|
||||||
stage: GameStage,
|
stage: GameStage,
|
||||||
@@ -19,10 +39,11 @@ struct PokerGame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl PokerGame {
|
impl PokerGame {
|
||||||
pub fn new(players: Vec<PokerPlayer>) -> PokerGame {
|
pub fn new(players: Vec<Box<dyn Player>>) -> PokerGame {
|
||||||
let first_player = 0;
|
let first_player = 0;
|
||||||
PokerGame {
|
PokerGame {
|
||||||
players,
|
players,
|
||||||
|
pots: vec![],
|
||||||
big_blind: 0,
|
big_blind: 0,
|
||||||
pot: 0,
|
pot: 0,
|
||||||
stage: GameStage::PreFlop,
|
stage: GameStage::PreFlop,
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use std::vec;
|
|||||||
mod card;
|
mod card;
|
||||||
mod game;
|
mod game;
|
||||||
mod hand;
|
mod hand;
|
||||||
mod pokerplayer;
|
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;
|
||||||
|
|||||||
259
src/player.rs
Normal file
259
src/player.rs
Normal file
@@ -0,0 +1,259 @@
|
|||||||
|
use crate::card::PlayingCard;
|
||||||
|
use crate::game::PokerGame;
|
||||||
|
use crate::hand::PokerHand;
|
||||||
|
use std::io;
|
||||||
|
|
||||||
|
pub enum TurnAction {
|
||||||
|
Fold,
|
||||||
|
Call,
|
||||||
|
Raise(u32),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Player {
|
||||||
|
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 {
|
||||||
|
name: String,
|
||||||
|
money: u32,
|
||||||
|
cards: Vec<PlayingCard>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HumanPlayer {
|
||||||
|
pub fn new(money: 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 {
|
||||||
|
name: user_input,
|
||||||
|
money,
|
||||||
|
cards: vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Player for HumanPlayer {
|
||||||
|
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 {
|
||||||
|
name: String,
|
||||||
|
money: u32,
|
||||||
|
cards: Vec<PlayingCard>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RemotePlayer {
|
||||||
|
pub fn new(name: &str, money: u32) -> RemotePlayer {
|
||||||
|
RemotePlayer {
|
||||||
|
name: name.to_string(),
|
||||||
|
money,
|
||||||
|
cards: vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Player for RemotePlayer {
|
||||||
|
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 {
|
||||||
|
name: String,
|
||||||
|
money: u32,
|
||||||
|
cards: Vec<PlayingCard>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BotPlayer {
|
||||||
|
pub fn new(name: &str, money: u32) -> BotPlayer {
|
||||||
|
BotPlayer {
|
||||||
|
name: format!("[BOT] {}", name.to_string()),
|
||||||
|
money,
|
||||||
|
cards: vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Player for BotPlayer {
|
||||||
|
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
|
||||||
@@ -1,106 +0,0 @@
|
|||||||
use crate::card::PlayingCard;
|
|
||||||
use crate::hand::PokerHand;
|
|
||||||
use std::io;
|
|
||||||
|
|
||||||
pub enum TurnAction {
|
|
||||||
Fold,
|
|
||||||
Call,
|
|
||||||
Raise(u32),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct PokerPlayer {
|
|
||||||
money: u32,
|
|
||||||
bet: u32,
|
|
||||||
cards: Vec<PlayingCard>,
|
|
||||||
is_remote: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PokerPlayer {
|
|
||||||
pub fn new(money: u32) -> Self {
|
|
||||||
PokerPlayer {
|
|
||||||
money,
|
|
||||||
bet: 0,
|
|
||||||
cards: vec![],
|
|
||||||
is_remote: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn deal_cards(&mut self, mut cards: Vec<PlayingCard>) {
|
|
||||||
self.cards.clear();
|
|
||||||
self.cards.append(&mut cards);
|
|
||||||
// Todo send cards over the network
|
|
||||||
println!(
|
|
||||||
"You've been dealt the cards: {}, {}",
|
|
||||||
self.cards[0], self.cards[1]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_hand(self, cards_on_table: &Vec<PlayingCard>) -> PokerHand {
|
|
||||||
let mut hand_cards = self.cards.clone();
|
|
||||||
hand_cards.append(&mut cards_on_table.clone());
|
|
||||||
let hand = PokerHand::new(hand_cards);
|
|
||||||
hand
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_action(&self) -> TurnAction {
|
|
||||||
if self.is_remote {
|
|
||||||
return TurnAction::Fold;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_raise(&self) -> u32 {
|
|
||||||
if self.is_remote {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user