Kuhn poker is three cards, one bet, and the first game in this series where you cannot see the position. That single change breaks something most game code assumes: with hidden information there is no best move, only a best distribution.
Play it: https://dev48.infy.uk/game/day74-kuhn-poker.html
The optimal strategy is a segment, not a point
The first player's optimal set is a one-parameter family. Bluff the Jack at any rate α in [0, 1/3], provided you bet the King at exactly 3α and call with the Queen at exactly 1/3 + α.
Every member of that family is worth exactly −1/18 a hand, and every one is exactly unexploitable. Not "to within tolerance" — the page certifies it in BigInt rationals.
// value of the game, exactly, for any alpha in [0, 1/3]
// bet K at 3a, bluff J at a, call Q at 1/3 + a -> -1/18 for player 1
Now find it the way anyone would
Sweep a grid over the strategy space. Reasonable, and it fails in an interesting way:
A grid of step 1/q contains exactly q/3 + 1 unexploitable strategies when 3 divides q, and exactly zero otherwise.
Not "few". Zero. Every payoff on a rational grid of step 1/q is a multiple of 1/6q, and the game value is not. So the answer your search returns is decided by arithmetic, not by resolution — refining from q = 100 to q = 101 takes you from many exact solutions to none at all, and the search reports its nearest miss with no indication that it stopped being exact.
| grid step | 3 divides q? | unexploitable strategies found |
|---|---|---|
| 1/99 | yes | 34 |
| 1/100 | no | 0 |
| 1/101 | no | 0 |
| 1/102 | yes | 35 |
Why this generalises
Any solver that discretises a continuous strategy space inherits the arithmetic of its grid. If the quantity you are solving for is not representable on that grid, a finer grid does not help — it just moves the miss around. The fix is not more resolution; it is solving in the field where the answer lives.
Verified against an independently written implementation, 0 failures. Vanilla JavaScript, one file, no build step.
Top comments (0)