Source code for maverick.rules
from __future__ import annotations
from pydantic import BaseModel, Field
from .enums import Street
__all__ = [
"DealingRules",
"StakesRules",
"ShowdownRules",
"PokerRules",
]
[docs]
class DealingRules(BaseModel):
"""
Rules related to seating limits and how cards are dealt.
Fields
------
max_players
Maximum number of seats allowed at the table. Typical values:
- 6 for "6-max"
- 9 for "full ring"
min_players
Minimum number of active players required to start a new hand. In most
poker games, 2 is the minimum (heads-up).
hole_cards
Number of private cards dealt to each player at the start of a hand.
- Hold'em: 2
- Omaha: 4 (commonly)
board_cards_total
Total number of community cards dealt by the end of the hand.
- Hold'em / Omaha: 5
- Some games have 0 community cards.
board_deal_pattern
How board cards are revealed over the streets, expressed as a dictionary mapping
Street to int.
For standard Hold'em:
{
Street.PRE_FLOP: 0,
Street.FLOP: 3,
Street.TURN: 1,
Street.RIVER: 1,
}
meaning:
- preflop: 0 board cards dealt (only hole cards)
- flop: 3 board cards
- turn: 1 board card
- river: 1 board card
This pattern also implicitly defines how many betting rounds exist if you
align each entry with one "street".
"""
max_players: int = Field(default=9, ge=2, le=10)
min_players: int = Field(default=2, ge=2, le=10)
hole_cards: int = Field(default=2, ge=1, le=4)
board_cards_total: int = Field(default=5, ge=0, le=5)
board_deal_pattern: dict[Street, int] = {
Street.PRE_FLOP: 0,
Street.FLOP: 3,
Street.TURN: 1,
Street.RIVER: 1,
}
[docs]
class StakesRules(BaseModel):
"""
Rules related to blinds, antes, and straddles (forced or optional preflop bets).
Fields
------
small_blind
The small blind amount. This is a forced bet posted by the player left
of the button in standard games.
big_blind
The big blind amount. This is a forced bet posted by the player left of
the small blind, and it typically defines:
- the price to call preflop
- the default minimum opening bet/raise (in no-limit/pot-limit)
ante
The ante amount. This is a forced bet posted by all players before the hand starts.
"""
small_blind: int = Field(..., ge=0)
big_blind: int = Field(..., gt=0)
ante: int = Field(default=0, ge=0)
[docs]
class ShowdownRules(BaseModel):
"""
Rules related to how final hands are constructed and compared.
Fields
------
hole_cards_required
Number of private cards that must be used in the final hand. This is relevant for
variants like Omaha where players must use a specific number of their hole cards
in combination with community cards to form their best hand.
Defaults to 0, which means any number of hole cards can be used.
"""
hole_cards_required: int = Field(0, ge=0)
[docs]
class PokerRules(BaseModel):
"""
Full configuration for a poker game.
This config is intended to be:
- serializable (store it in hand histories, reproduce games deterministically)
- explicit (no hidden defaults beyond what you set here)
- reusable (same rules can be applied across many games)
Fields
------
name
Human-readable label for the ruleset (e.g., "NLHE", "OMAHA").
Useful for logs, exports, and UI.
dealing
Card dealing and seating-related rules (variant, hole cards, board pattern, etc.).
stakes
Blind/ante/straddle rules.
betting
Bet sizing and raising structure rules.
showdown
Rules governing showdown.
rules_version
Version tag for the rules schema.
"""
name: str = "NLHE"
dealing: DealingRules
stakes: StakesRules
showdown: ShowdownRules
rules_version: str = "1.0"