use crate::core::{Card, Hand, PlayerBitSet, Rank};
use super::game_state::Round;
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
pub enum AgentAction {
Fold,
Call,
Bet(f32),
AllIn,
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct GameStartPayload {
pub ante: f32,
pub small_blind: f32,
pub big_blind: f32,
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct PlayerSitPayload {
pub idx: usize,
pub player_stack: f32,
pub name: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct DealStartingHandPayload {
pub card: Card,
pub idx: usize,
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum ForcedBetType {
Ante,
SmallBlind,
BigBlind,
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ForcedBetPayload {
pub bet: f32,
pub player_stack: f32,
pub idx: usize,
pub forced_bet_type: ForcedBetType,
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct PlayedActionPayload {
pub action: AgentAction,
pub idx: usize,
pub round: Round,
pub player_stack: f32,
pub starting_pot: f32,
pub final_pot: f32,
pub starting_bet: f32,
pub final_bet: f32,
pub starting_min_raise: f32,
pub final_min_raise: f32,
pub starting_player_bet: f32,
pub final_player_bet: f32,
pub players_active: PlayerBitSet,
pub players_all_in: PlayerBitSet,
}
impl PlayedActionPayload {
pub fn raise_amount(&self) -> f32 {
self.final_bet - self.starting_bet
}
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct FailedActionPayload {
pub action: AgentAction,
pub result: PlayedActionPayload,
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct AwardPayload {
pub total_pot: f32,
pub award_amount: f32,
pub rank: Option<Rank>,
pub hand: Option<Hand>,
pub idx: usize,
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum Action {
GameStart(GameStartPayload),
PlayerSit(PlayerSitPayload),
DealStartingHand(DealStartingHandPayload),
RoundAdvance(Round),
PlayedAction(PlayedActionPayload),
FailedAction(FailedActionPayload),
ForcedBet(ForcedBetPayload),
DealCommunity(Card),
Award(AwardPayload),
}
#[cfg(test)]
mod tests {
use crate::core::PlayerBitSet;
use super::*;
#[test]
fn test_bet() {
let a = AgentAction::Bet(100.0);
assert_eq!(AgentAction::Bet(100.0), a);
}
#[test]
fn test_raise_amount_calculation() {
let payload = PlayedActionPayload {
action: AgentAction::Bet(100.0),
idx: 0,
round: Round::Preflop,
player_stack: 500.0,
starting_pot: 15.0,
final_pot: 115.0,
starting_bet: 10.0,
final_bet: 30.0, starting_min_raise: 10.0,
final_min_raise: 20.0,
starting_player_bet: 0.0,
final_player_bet: 30.0,
players_active: PlayerBitSet::new(2),
players_all_in: PlayerBitSet::default(),
};
assert_eq!(payload.raise_amount(), 20.0);
}
#[test]
fn test_raise_amount_different_values() {
let payload = PlayedActionPayload {
action: AgentAction::Bet(50.0),
idx: 0,
round: Round::Flop,
player_stack: 200.0,
starting_pot: 50.0,
final_pot: 100.0,
starting_bet: 25.0,
final_bet: 75.0,
starting_min_raise: 25.0,
final_min_raise: 50.0,
starting_player_bet: 0.0,
final_player_bet: 75.0,
players_active: PlayerBitSet::new(3),
players_all_in: PlayerBitSet::default(),
};
assert_eq!(payload.raise_amount(), 50.0);
}
#[test]
fn test_raise_amount_no_raise() {
let payload = PlayedActionPayload {
action: AgentAction::Bet(10.0),
idx: 1,
round: Round::Preflop,
player_stack: 100.0,
starting_pot: 15.0,
final_pot: 25.0,
starting_bet: 10.0,
final_bet: 10.0, starting_min_raise: 10.0,
final_min_raise: 10.0,
starting_player_bet: 0.0,
final_player_bet: 10.0,
players_active: PlayerBitSet::new(2),
players_all_in: PlayerBitSet::default(),
};
assert_eq!(payload.raise_amount(), 0.0);
}
}