Skip to content

Instantly share code, notes, and snippets.

@fielding
Created June 19, 2026 04:10
Show Gist options
  • Select an option

  • Save fielding/ad5deb409d3b39f552e352c9608981d0 to your computer and use it in GitHub Desktop.

Select an option

Save fielding/ad5deb409d3b39f552e352c9608981d0 to your computer and use it in GitHub Desktop.
dev.fun poker — min-raise-war / sliver-shove behavioral spec (PREFLOP + postflop). Bots that fold a priced sliver (e.g. J9o, 100 into 9000 = ~90:1) are farmable. Point choose_action() at your bot; controls keep the fix from making it a calling station.
"""
Min-raise-war / sliver-shove behavioral spec (preflop AND postflop).
Some bots decide a call by comparing HAND STRENGTH (or equity vs the opponent's
perceived value range) to a threshold — WITHOUT re-pricing the bet against the
pot. Attackers farm this: min-raise back and forth to inflate the pot cheaply
(each min-raise is a tiny *additional* call, so naive pot-odds logic keeps
calling), then shove a SLIVER — e.g. 100 into a 9,000 pot.
That sliver lays ~90:1: you need ~1.1% equity to call, which ANY two live cards
clear. A bot that folds "to a raise / all-in" unless its hand is strong FOLDS and
ships the whole pot for a 100-chip bet. Folding is -EV at *every* equity here.
It happens on BOTH streets — including PREFLOP, before a flop is ever dealt
(range-only preflop logic mucks a normal hand like J9o into a 90:1 pot). Both are
covered below.
This file is a behavioral contract, NOT an implementation. Each test states how
the strategy SHOULD act; how you satisfy it is up to you.
Setup:
- Adjust the import below to wherever your choose_action(table, my_seat) lives.
- Tweak the `table()` helper if your table/seat schema differs.
- Run: pytest test_sliver_shove_spec.py -v
The "control" tests at the bottom must stay green: vs NORMAL sizing, folding air
is still correct. The fix is "never fold a priced sliver," NOT "call everything"
— a change that turns the bot into a calling station is over-correcting.
"""
import pytest
# >>> POINT THIS AT YOUR STRATEGY <<<
from poker_bot.strategies.profiled import choose_action
HERO = "hero"
def table(hole, board=(), *, pot, call, bb=10,
available=("fold", "call"), villains=2, profiles=None):
"""Minimal table/seat the strategy can act on. Preflop when board is empty,
else the street implied by the board length; facing an all-in either way."""
street = {0: "Preflop", 3: "Flop", 4: "Turn", 5: "River"}[len(board)]
seats = [{"seatNumber": 1, "agentId": HERO, "holeCards": list(hole), "folded": False}]
for i in range(villains):
seats.append({"seatNumber": 2 + i, "agentId": f"v{i}",
"holeCards": [], "folded": False})
t = {
"street": street,
"boardCards": list(board),
"potChips": pot,
"bigBlindChips": bb,
"seats": seats,
"opponentProfiles": profiles or {},
"allowedActions": {
"availableActions": list(available),
"callAmount": call,
"raiseRange": {"min": call * 2, "max": 5000},
"betRange": {"min": 0, "max": 5000},
},
}
return t, seats[0]
def act(hole, board=(), **kw):
action, _amount, _reason = choose_action(*table(hole, board, **kw))
return action
# ── THE KEY ONE: J9o folded PREFLOP into a 90:1 pot (the exact farmed hand) ────
def test_j9o_does_not_fold_preflop_sliver_shove():
# min-raise war bloats the pot BEFORE the flop, then a sliver shove: 100 into
# 9000 = ~90:1. Folding J9o here ships the whole pot for a 100-chip call.
assert act(["Jh", "9c"], pot=9000, call=100) != "fold"
# ── preflop sliver-shove, more cases ──────────────────────────────────────────
def test_air_does_not_fold_preflop_sliver_90to1():
assert act(["7h", "2d"], pot=9000, call=100) != "fold"
def test_does_not_fold_preflop_sliver_45to1():
assert act(["Th", "4c"], pot=9000, call=200) != "fold"
def test_does_not_fold_preflop_sliver_multiway():
# the real shape: several bots min-raised it up preflop, then a sliver shove
assert act(["9h", "5c"], pot=6000, call=100, villains=3) != "fold"
# ── postflop sliver-shove (same exploit, after the flop) ──────────────────────
R = ("Ks", "Qd", "9c", "4s", "3h")
def test_air_does_not_fold_postflop_sliver_90to1():
assert act(["7h", "2d"], R, pot=9000, call=100) != "fold"
def test_top_pair_does_not_fold_postflop_sliver():
# made hand: folding "to a raise" ships a 9000 pot for 100
assert act(["Jh", "9c"], ("Js", "6d", "3c", "8h", "2s"), pot=9000, call=100) != "fold"
def test_air_does_not_fold_postflop_sliver_30to1():
assert act(["7h", "2d"], R, pot=9000, call=300) != "fold"
# ── controls: vs NORMAL sizing, folding trash is still correct (not a station) ─
def test_junk_still_folds_normal_preflop_open():
assert act(["7h", "2d"], pot=45, call=30) == "fold" # ~3bb open
def test_junk_still_folds_normal_preflop_3bet():
assert act(["8h", "3d"], pot=135, call=90) == "fold" # ~3-bet price
def test_air_still_folds_postflop_half_pot():
assert act(["7h", "2d"], R, pot=600, call=300) == "fold"
def test_air_still_folds_postflop_pot_bet():
assert act(["7h", "2d"], R, pot=600, call=600) == "fold"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment