PKState
A Rust library for representing, serializing, and deserializing the state of a poker game. pkstate
models everything needed to describe a hand in progress or a complete hand history: the game type,
forced bets, the players at the table, the community board cards, and the full sequence of actions
across every street — all serializable to and from human-readable YAML.
Features
- Full game state — captures game type, button position, forced bets, players, board cards, and
action history in a single
PKStatestruct. - Up to 12 players —
Actionvariants cover seats P0 through P11. - Rich action model — per-player
Dealt,Check,CBR(call/bet/raise),Fold,Wins, andLosesactions, plus aDealCommonaction for community cards. - Human-readable YAML — card piles are serialized as Unicode card strings (e.g.
"A♠ K♥") rather than nested structures, keeping hand histories easy to read and edit. - Optional fields —
id,datetime, andboardare skipped whenNone, keeping YAML output clean.
Supported Game Types
| Variant | Cards Dealt | Board Cards |
|---|---|---|
NoLimitHoldem |
2 | 5 |
LimitHoldem |
2 | 5 |
PLO |
4 | 5 |
Razz |
7 | 0 |
Quick Start
Add pkstate to your Cargo.toml:
[]
= "0.1.0"
Building a hand and serializing to YAML
use ;
use *;
let players = vec!;
let preflop = Round;
let state = PKState ;
let yaml = to_string.unwrap;
println!;
Output:
id: example-hand
game: NoLimitHoldem
button: 0
forced_bets:
small: 50
big: 100
players:
- name: Alice
stack: 1000
- name: Bob
stack: 1000
rounds:
- - P0Dealt: A♠ K♠
- P1Dealt: 7♦ 2♣
- P0CBR: 100
- P1Fold
- P0Wins: 100
Deserializing from YAML
let state: PKState = from_str.unwrap;
YAML Format
PKState
| Field | Type | Optional | Description |
|---|---|---|---|
id |
String |
✅ | Unique identifier for the hand |
datetime |
DateTime<Utc> |
✅ | Timestamp of the hand |
game |
GameType |
❌ | Variant of poker being played |
button |
usize |
❌ | Seat index of the dealer button |
forced_bets |
ForcedBets |
❌ | Small blind, big blind, optional straddles / ante |
board |
BasicPile (as string) |
✅ | Community cards, e.g. "9♣ 6♦ 5♥ 5♠ 8♠" |
players |
Vec<Seat> |
❌ | Ordered list of players at the table |
rounds |
Vec<Round> |
❌ | Ordered list of betting rounds |
Action YAML representations
| Variant | YAML |
|---|---|
DealCommon(pile) |
DealCommon: "9♣ 6♦ 5♥" |
PnDealt(pile) |
P0Dealt: "A♠ K♠" |
PnCheck |
P0Check |
PnCBR(amount) |
P0CBR: 200 |
PnFold |
P1Fold |
PnWins(amount) |
P3Wins: 1000 |
PnLoses(amount) |
P4Loses: 1000 |
Modules
act—Actionenum andRoundnewtype. Encodes every per-player and community-card action that can occur during a hand, with custom serde implementations that representBasicPilevalues as Unicode card strings.game—GameTypeenum andForcedBetsstruct. Describes the variant being played and the mandatory bets required to start each hand.seat—Seatstruct. Represents a player at the table: their optional id, display name, and chip stack.util— Shared serde helper functions for serializing and deserializingBasicPileandOption<BasicPile>as card strings.
Resources
- Poker Hand History File Format Specification
cardpackcrate — playing card types used throughout
Development
This project uses cargo-make to manage tasks. Install it with:
cargo install cargo-make
The default cargo make task runs:
cargo fmtcargo cleancargo buildcargo testcargo clippywithclippy::pedanticlint settingscargo doc --no-deps
cargo make
To open the generated docs in your browser:
cargo make docs
License
Licensed under either of:
at your option.