Download README.md from ThreeSixNine/poker-risk-engine: direct link, hf CLI and curl.
- Browser
- Download file 2.76 kB
-
https://huggingface.co/ThreeSixNine/poker-risk-engine/resolve/main/README.md
- Command line
-
hf download hf://ThreeSixNine/poker-risk-engine/README.md
-
curl -L -o README.md https://huggingface.co/ThreeSixNine/poker-risk-engine/resolve/main/README.md
title: Poker decision engine with a calibrated risk knob
license: mit
tags:
- ml-intern
- poker
- decision-engine
- risk-control
- monte-carlo
poker-risk-engine
A poker decision engine where risk appetite is a single, calibrated scalar
knob r ∈ [0,1] — the piece our survey found missing from every public poker
agent: levers exist in the literature, but nobody ships an aggression dial with
measured, monotone response curves.
The knob
r simultaneously and monotonically controls: calling threshold
(pot_odds − 0.20·r), raise threshold (0.62 − 0.10·r), bet threshold
(0.60 − 0.12·r), and bet sizing (0.45 + 0.55·r of pot). Equity is Monte
Carlo vs uniform opponents (treys).
Calibration (120 seeded scenarios, eval_knobs.py)
| r | VPIP | PFR | Aggr. rate | Bet/pot |
|---|---|---|---|---|
| 0.0 | 0.36 | 0.00 | 0.15 | 0.91 |
| 0.5 | 0.55 | 0.06 | 0.19 | 1.35 |
| 1.0 | 0.72 | 0.16 | 0.22 | 1.82 |
All four aggression metrics are monotone in r (script-verified). Honest caveat: heuristic mean EV rises monotonically to r=1.0 with no interior peak — under a fold-equity-only EV model, aggression is never penalized, so the EV curve reflects the EV model's known weakness, not an uncalibrated knob. An EV model with value-realization dynamics would likely produce the expected interior peak; that's the next refinement.
Misread injection: perception noise costs money
Corrupt card reads (rank or suit swaps) at probability p, re-decide at r=0.5:
| p | Action flip rate | Mean EV loss (chips) |
|---|---|---|
| 0.00 | 0.025 | 2.19 |
| 0.05 | 0.042 | 3.86 |
| 0.10 | 0.075 | 8.75 |
| 0.20 | 0.083 | 13.12 |
| 0.30 | 0.167 | 34.26 |
A 30% misread rate costs ~15× more EV than the clean-read baseline — the quantitative bridge between the perception stack (ThreeSixNine/poker-table-perception-eval, detector in ThreeSixNine/yolo11n-poker-table-cards) and decision quality.
Limitations (v0, by design)
Uniform random opponent model (no reads/ranges); single-street decisions (no
future-street planning, no ICM); heuristic EV used only for policy comparison;
preflop is pure equity MC (no charts). See LIMITATIONS in decision_engine.py.
Usage
from decision_engine import RiskEngine, TableState
eng = RiskEngine(n_sims=1500)
st = TableState(hero=["AS", "KD"], board=["AH", "7S", "2D"], pot=160,
stack=1000, to_call=40, n_players=3, position="BTN",
street="flop")
print(eng.decide(st, r=0.7)) # {"action": "raise", "amount": ...}
Reproduce: python eval_knobs.py --n-scenarios 120 --sims 1500