Inspiration

In Heads Up, every bot plays every other bot in duplicate format: the same cards, with seats swapped. That cancels out luck, so the only way to win is to play the same cards better than the opponent and keep adapting to each one.

What it does

RangeReader plays heads-up Short Deck 5-card Pot-Limit Omaha. For each decision, it estimates how likely it is to win against the opponent's likely hands, not random ones, then picks the action with the highest expected value. The whole time, it learns that opponent's habits: how often they bet, raise and fold, and whether their showdown hands back up their bets.

How we built it

  • A fast evaluator. A NumPy hand evaluator built on prime-number lookup tables runs about 300 simulated runouts in under a millisecond. We verified it against the official evaluator on 50,000 hands with zero mismatches.
  • A preflop table. We precomputed equity for all 376,992 possible starting hands.
  • Range reading. We sample possible opponent hands and keep the top fraction that fits that opponent's betting habits. A maniac's raise barely narrows its range; a careful bot's raise narrows it a lot.
  • Anti-exploitation. It mixes randomly between near-equal plays, varies bet sizes so they don't reveal hand strength, and lets older observations fade so it catches bots that switch styles. Against aggressive bettors, it sometimes checks strong hands to set a trap.
  • Safety. All logic is wrapped so the bot can never crash. A feedback controller manages its time, so on a slow tournament machine it thinks less instead of running out of its time bank.

Challenges we ran into

  • Our bot beat every test bot we wrote, then lost to real rival bots from public GitHub forks. Breaking down where it lost chips showed it was calling preflop raises and then folding later. Tightening its play fixed most of that.
  • A subtle bug meant it never counted the opponent folding to its bets, because the hand ends immediately after a fold. Writing exploiter bots exposed it. One bluffs whenever we fold too much, and another reads our bet sizes.

Accomplishments that we're proud of

  • Over 1,000-deal duplicate matches, it beat all 25 opponent types we built, including all-in bots, maniacs, trappers, exploiters and a game-theory-style bot
  • Zero errors and only about 1 second of thinking time per half

What we learned

Testing against real opponents matters more than testing against imagined ones. And in duplicate scoring, your own randomness doesn't cancel out, so use it sparingly.

What's next

A pre-solved, game-theory-based preflop strategy to compete with the strongest bots.

Built With

Share this project:

Updates

Submission history