Skip to main content

pokerproof/game/
state.rs

1//! Game state types
2//!
3//! Contains the runtime state of a poker game.
4
5use crate::card::Card;
6use crate::hand::HandRank;
7use serde::{Deserialize, Serialize};
8
9/// Current phase of the poker hand
10#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
11pub enum GamePhase {
12    WaitingForPlayers,
13    AwaitingStraddle, // Straddle prompt before cards are dealt
14    PreFlop,
15    Flop,
16    Turn,
17    River,
18    Showdown,
19    AwaitingShowMuck, // Winner by fold can choose to show or muck cards
20    Finished,
21    GameOver, // Only one player has chips remaining - game is complete
22}
23
24/// Tracks active straddles for the current hand
25#[derive(Debug, Clone, Serialize, Deserialize, Default)]
26pub struct StraddleState {
27    pub straddles: Vec<StraddleInfo>, // Stack of straddles (first = initial, last = highest)
28    pub current_straddle_amount: u64, // Current straddle bet level
29}
30
31/// Information about a single straddle
32#[derive(Debug, Clone, Serialize, Deserialize)]
33pub struct StraddleInfo {
34    pub player_index: usize,
35    pub amount: u64,
36}
37
38/// Status of run-it-twice for the current hand
39#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
40pub enum RunItTwiceStatus {
41    #[default]
42    NotOffered, // Not an all-in situation or not enabled
43    Offered,  // All players all-in, waiting for decisions
44    Accepted, // All players agreed to run it twice
45    Declined, // At least one player declined
46}
47
48/// Tracks run-it-twice state for the current hand
49#[derive(Debug, Clone, Serialize, Deserialize, Default)]
50pub struct RunItTwiceState {
51    pub status: RunItTwiceStatus,
52    pub player_decisions: Vec<Option<bool>>, // None = pending, Some(true) = accept, Some(false) = decline
53    pub first_board: Vec<Card>,              // First runout's remaining community cards
54    pub second_board: Vec<Card>,             // Second runout's remaining community cards
55    pub first_runout_winner: Option<usize>,  // Winner of first runout
56    pub second_runout_winner: Option<usize>, // Winner of second runout
57    pub first_runout_hand: Option<HandRank>, // Winning hand for first runout
58    pub second_runout_hand: Option<HandRank>, // Winning hand for second runout
59}
60
61/// Represents a pot and who is eligible to win it
62#[derive(Debug, Clone, Serialize, Deserialize)]
63pub struct Pot {
64    pub amount: u64,
65    pub eligible_players: Vec<usize>, // Indices of players who can win this pot
66}
67
68/// The complete state of a poker game
69#[derive(Debug, Clone, Serialize, Deserialize)]
70pub struct GameState {
71    pub phase: GamePhase,
72    pub pot: u64,
73    pub current_bet: u64,
74    pub community_cards: Vec<Card>,
75    pub dealer_position: usize,
76    pub current_player: usize,
77    /// Last player to bet/raise (betting round ends when we're back to them)
78    pub last_aggressor: Option<usize>,
79    /// First player to act in this betting round (for tracking full circles when no aggressor)
80    pub first_to_act: Option<usize>,
81    /// Minimum raise amount (must match last raise or big blind)
82    pub min_raise: u64,
83    /// Winner of the hand (at showdown) - for main pot
84    pub winner_index: Option<usize>,
85    /// Winning hand rank
86    pub winning_hand: Option<HandRank>,
87    /// The specific 5 cards that make up the winning hand
88    pub winning_cards: Option<Vec<Card>>,
89    /// Winners of side pots (if any)
90    pub side_pot_winners: Vec<usize>,
91    /// Active straddles for this hand
92    pub straddle_state: StraddleState,
93    /// Run it twice tracking
94    pub run_it_twice_state: RunItTwiceState,
95    /// Overall game winner (when only one player has chips remaining)
96    pub game_winner: Option<usize>,
97    /// Provably fair: SHA256 hash of the deck seed (shown before dealing)
98    #[serde(skip_serializing_if = "Option::is_none")]
99    pub seed_hash: Option<String>,
100    /// Provably fair: The actual seed (only revealed after hand finishes)
101    #[serde(skip_serializing_if = "Option::is_none")]
102    pub deck_seed: Option<String>,
103    /// Cards shown by winner (when they choose to show after win by fold)
104    #[serde(skip_serializing_if = "Option::is_none")]
105    pub shown_cards: Option<Vec<Card>>,
106}