Inspiration
Winning more hands does not necessarily mean winning at poker. A bot can collect small pots and lose everything through a few expensive mistakes.
We built Starfish to make profitable decisions against different playing styles while operating within a strict computational budget.
What it does
Starfish plays heads-up Short Deck 5-card Pot-Limit Omaha. It estimates hand equity, adapts to observed opponent behavior, and chooses between folding, checking/calling, half-pot raises, and pot raises.
It combines value betting with selective semi-bluffs and blocker-based bluffs. Opponent behavior matters: a selective player's raise should suggest a different range of hands from a habitual aggressor's raise.
Every decision uses only information available at that moment.
How we built it
We built a Python strategy around the official TAMU Datathon Heads Up starter engine.
Monte Carlo simulations estimate equity by sampling opponent holdings and future community cards. Range weighting and smoothed opponent statistics inform decisions alongside pot odds, position, and legal bet sizes.
The bot runs through FastAPI and Uvicorn. Cached calculations, bounded simulation work, and HTTP parsing optimizations reduce runtime overhead. Legal-action checks and observable fault counters support reliability.
We tested changes against a frozen champion using the official judge, matched deals, fixed opponent versions, and fresh processes between match halves.
We also explored a learned preflop estimator. It did not establish a practical match-performance improvement, so the released bot retains simulation and explicit decision rules.
Challenges we ran into
The eight-second time bank applies across an entire half, making accumulated overhead important. We investigated simulation cost, HTTP overhead, and differences between Windows and Linux timing.
Separating improvements from statistical noise was another challenge. We used development opponents for tuning and reserved previously untouched opponent configurations and new seeds for final evaluation.
Accomplishments that we're proud of
Our frozen release completed a final benchmark of 36 matches across 12 opponent configurations from six strategy families:
- 36 wins, earning 36/36 official-judge match points.
- Average profit of +3.625 big blinds per paired deal.
- 72,000 played hands.
- Zero observed errors, internal faults, exception fallbacks, forfeits, or exhausted time banks.
- Maximum charged time of 3.729 seconds per half in the measured Linux environment.
- 127 passing tests and successful official Docker checks.
These are results from our validation benchmark, not an official tournament ranking or a guarantee against other teams.
What we learned
A more complicated model is useful only when it improves match outcomes within the runtime budget. Prediction accuracy and bluff frequency cannot replace profit, official match points, uncertainty, and reliability.
What's next for Starfish
We want to evaluate against independently designed opponents, improve action-conditioned range calibration, and revisit learned equity estimation only when it demonstrates a measurable competitive benefit.
Attribution
Starfish builds on the official TAMU Datathon Heads Up starter repository: https://github.com/tamu-datathon-org/heads-up-bundle
The organizers provided the game engine, evaluator, and judge. Our work adds the strategy, opponent adaptation, runtime optimizations, reliability checks, and evaluation tooling.