BLG-003
Why a Hybrid Poker System Taught Me About State Machines
A digital + physical poker table revealed the power of immutable state transitions and why modular design scales.
The problem: Two systems, one truth
In a physical poker game, chips move from player to pot, blinds rotate, and pots split. A hybrid system — real cards on the table, betting tracked on an app — faces a challenge: where is the source of truth?
If I track state in both the physical setup and the app independently, they drift. A player forgets to log their bet. Someone misreads the pot. The two systems become incompatible.
State machines save you
The solution was a single, immutable state machine. Every bet, every fold, every blind advancement was a transition, not a mutation.
class GameState(Enum):
PRE_FLOP = "pre_flop"
FLOP = "flop"
TURN = "turn"
RIVER = "river"
SHOWDOWN = "showdown"
class PokerTable:
def __init__(self):
self.state = GameState.PRE_FLOP
self.players = []
self.pot = 0
self.history = []
def place_bet(self, player_id, amount):
if not self.is_valid_bet(player_id, amount):
return False
self.pot += amount
self.history.append({
'action': 'bet',
'player': player_id,
'amount': amount,
'state': self.state
})
return True
def advance_round(self):
transitions = {
GameState.PRE_FLOP: GameState.FLOP,
GameState.FLOP: GameState.TURN,
GameState.TURN: GameState.RIVER,
GameState.RIVER: GameState.SHOWDOWN
}
self.state = transitions[self.state]
self.history.append({
'action': 'round_advance',
'to_state': self.state
})
Every state change is logged. Players can see the history on the app. The physical chips and the digital record agree because there’s only one source of truth.
The lesson: Modularity scales
Because state was separate from logic, I could later add:
- Undo functionality (replay the history without the last transition)
- Replay mode (debug a hand from any point)
- Variations (tournament rules vs. cash rules) as state machine variants
Changing one system didn’t break the other. That’s what good modular design looks like.