The most advanced open-source poker library available. Hand evaluation at 50M+ hands/sec per core, a CFR solver for game-theory optimal strategy approximation, Omaha support (PLO4-PLO7), multi-agent arena simulation, Monte Carlo equity calculation, and ICM tournament simulation — all in Rust.
Available as both a library (rs_poker) and a CLI binary (rsp).
rsp CLIInstall the binary:
cargo install rs_poker --features rsp
Rank a hand:
rsp holdem rank AcKdQhJsTs
Monte Carlo equity simulation (3M hands by default):
rsp holdem simulate AdKh 8c8s
Calculate outs with board cards:
rsp holdem outs AcAd KsKh --board QhJhTh --detailed
Rank an Omaha hand:
rsp omaha rank AhAsKhKs QhJhTh
Pit agents against each other:
rsp arena compare ./examples/configs -n 5000 -p 3

Generate hand histories in Open Hand History format:
rsp arena generate ./examples/configs -o hands.ohh -n 1000
Convert chipEV to $EV in tournaments:
rsp icm simulate --chip-stacks 1500 1250 600 500 850 800 --payments 50 30 20 --iterations 50000
Add to your project:
cargo add rs_poker
use rs_poker::core::{FlatHand, Rankable};
let hand = FlatHand::new_from_str("AcKdQhJsTs").unwrap();
let rank = hand.rank();
println!("{}", rank); // StraightFlush
use rs_poker::core::{Card, Hand, Suit, Value};
use rs_poker::holdem::MonteCarloGame;
let hero = Hand::new_with_cards(vec![
Card::new(Value::Ace, Suit::Spade),
Card::new(Value::Ace, Suit::Heart),
]);
let villain = Hand::new_with_cards(vec![
Card::new(Value::King, Suit::Spade),
Card::new(Value::King, Suit::Heart),
]);
let mut sim = MonteCarloGame::new(vec![hero, villain]).unwrap();
let equity = sim.estimate_equity(100_000);
// equity[0] ≈ 0.82 (AA vs KK)
use rs_poker::core::Rankable;
use rs_poker::omaha::OmahaHand;
let hand = OmahaHand::new_from_str("AhAsKhKs", "QhJhTh").unwrap();
let rank = hand.rank();
println!("{}", rank); // StraightFlush — uses exactly 2 hole + 3 board
Foundational types for all poker variants:
CardBitSet (u64)Hand evaluation runs at 50M+ hands/sec per core (~20ns per 5-card hand, <25ns per 7-card hand). This is achieved through:
Full support for Omaha variants: PLO4, PLO5, PLO6, and PLO7.
Rankable trait as Hold'em — one API for all variantsuse rs_poker::core::Rankable;
use rs_poker::omaha::OmahaHand;
// PLO5 with 5 hole cards
let hand = OmahaHand::new_from_str("AhAsKhKs9d", "QhJhTh").unwrap();
let rank = hand.rank();
Texas Hold'em-specific tools:
"AKs", "TT+", "JTs-67s", "KQo+"MonteCarloGameuse rs_poker::holdem::StartingHand;
// Parse a range of hands
let hands = StartingHand::new_from_range("TT+").unwrap();
// Returns: TT, JJ, QQ, KK, AA
Multi-agent simulation framework for autonomous poker play. Supports 2-16 players with configurable blinds, antes, and stack sizes.
Implement act() to create a custom strategy:
use rs_poker::arena::{Agent, AgentAction, GameState};
struct MyAgent;
impl Agent for MyAgent {
fn act(&mut self, _id: u128, game_state: &GameState) -> AgentAction {
AgentAction::Call(game_state.current_bet())
}
fn name(&self) -> &str { "my-agent" }
}
| Agent | Strategy |
|---|---|
CallingAgent |
Always calls |
FoldingAgent |
Always folds (checks when possible) |
AllInAgent |
Always goes all-in |
RandomAgent |
Configurable fold/call probabilities per street |
RandomPotControlAgent |
Random with pot-size-aware bet limiting |
ConfigAgentBuilder |
JSON-configurable preflop ranges + postflop strategy |
VecReplayAgent |
Replays a recorded action sequence |
CFRAgent |
Counterfactual Regret Minimization solver |
Event recorders that observe every action during simulation:
| Historian | Purpose |
|---|---|
VecHistorian |
Collects all actions in memory |
StatsTrackingHistorian |
Aggregates VPIP, PFR, 3-bet, win rate, positional profit |
DirectoryHistorian |
Writes hand histories to disk |
OpenHandHistoryHistorian |
Exports in OHH format |
FnHistorian |
Closure-based custom recording |
NullHistorian |
No-op (discards all records) |
HoldemCompetition — run multiple cash game hands and track per-player P&L, win/loss counts, and per-street statisticsSingleTableTournament — elimination-style tournament with finishing positions and stack trackingThe CFR (Counterfactual Regret Minimization) agent learns game-theory optimal strategies by exploring the game tree and minimizing regret over iterations.
ArcVec by index for cache-friendly traversalRun CFR agents via the CLI:
rsp arena compare ./examples/configs -n 5000 -p 3
Or configure them via JSON:
{
"type": "cfr_configurable",
"name": "CFR-Agent",
"exploration": {
"max_recursion_depth": 3,
"act_deadline_ms": 250,
"budget": { "type": "per_depth_iterations", "counts": [24, 3, 1] }
},
"action_config": {
"preflop": {
"call_enabled": true,
"raise_mult": [4.0],
"pot_mult": [],
"setup_shove": false,
"all_in": true
},
"flop": {
"call_enabled": true,
"raise_mult": [],
"pot_mult": [0.5, 1.0],
"setup_shove": false,
"all_in": true
}
}
}
Monte Carlo-based ICM (Independent Chip Model) tournament equity calculation.
use rs_poker::simulated_icm::simulate_icm_tournament;
let chip_stacks = vec![10000, 5000, 3000, 2000];
let payments = vec![100, 50, 25, 10];
let winnings = simulate_icm_tournament(&chip_stacks, &payments);
// winnings[i] = expected payout for player i based on chip stack
Avoids the O(N!) complexity of traditional ICM by simulating all-in confrontations. Parallelizable across independent tournaments.
| Flag | Default | Description |
|---|---|---|
arena |
Yes | Multi-agent simulation framework, CFR solver |
serde |
Yes | JSON serialization for hands, game states, configs |
omaha |
Yes | Omaha (PLO4/PLO5/PLO6/PLO7) hand evaluation |
open-hand-history |
Yes | Open Hand History format import/export |
rsp |
No | CLI binary with all features enabled |
arena-test-util |
No | Approximate comparison helpers for tests |
open-hand-history-test-util |
No | OHH format testing helpers |
cargo-mutants validates test coverage catches real bugsApache-2.0
$ claude mcp add rs-poker \
-- python -m otcore.mcp_server <graph>