Skip to content

feat(drills): pot odds, the membership's second kind - #93

Merged
will-lamerton merged 1 commit into
mainfrom
feat/drills-pot-odds
Aug 29, 2026
Merged

feat(drills): pot odds, the membership's second kind#93
will-lamerton merged 1 commit into
mainfrom
feat/drills-pot-odds

Conversation

@pip-robot

@pip-robot pip-robot Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

The second of the three paid drill kinds, and the next piece of part B (technology#55). The same turn spot as "count your outs" with a price on it: they have bet, both hands are face up, one card is to come, and the only question is whether the pot is laying you enough.

Exact, not estimated

The spec had this kind graded by estimateEquity. It does not have to be, and it should not be: one card to come against a hand you can see is 44 showdowns, so the equity is counted and the price is a fraction. Nothing in this kind can mark a correct call wrong, which is the property the free kind and the counting kind both hold and which does not become optional because a kind is paid for.

The ambiguous reject reason the contract has been describing since part A arrives with this kind: a spot whose two numbers sit within 4 points is thrown away, because a player who reads it the other way is not wrong. The two rules that were attached to it (seed estimateEquity from the drill's seed, push iterations up) do not arrive, because there is no rng here at all. That is noted in types.ts rather than quietly dropped.

One definition of a price

What the pot is charging comes from requiredEquity in config/potOdds - the same function /learn/pot-odds prints its table from. A member who reads the guide and then plays the drill is taught and graded by one definition. A test puts the two whole numbers of chips on the screen back through it.

Half calls, half folds, by construction

A spot survives only if some bet this pot could carry would make it a call and some other bet would make it a fold; then a coin picks which one this spot is. Two things fall out: answering "fold" to everything scores what a coin scores, and every spot is one the price actually decides. Priced at random instead, four accepted spots in five are folds - honest about the population of poker hands and useless as a drill, because the rating would be reading who had spotted the habit rather than who can count. A test holds the split at 45-55%.

The gate

membersOnly: true is on the kind in the same commit that registers it, and a test asserts it by name. A paid kind that ships without the flag is free forever under rule #8 and no later commit takes it back.

What is in it

  • src/lib/drills/potOdds.ts - the generator, the filter and the sentence.
  • src/lib/drills/turnSpot.ts - the deal and the face-up hands, now shared with "count your outs" rather than copied, so a change to the turn deal has to be a change to both kinds or to neither.
  • rating.ts / standing.ts - a third shape vocabulary (clear-price, close-price, thin-price, banded off the measured gap distribution) and its ladder.
  • types.ts - DrillStakes on the contract, plus spoken so a screen reader reads "6 cards" and "Call" rather than "Call cards".
  • DrillRunner.tsx - the pot and the price above the board, c and f on the keyboard, two-wide buttons for a two-answer kind.
  • tests/drillsPotOdds.test.ts - 15 tests, including one that re-derives every answer from the cards on the screen with code that shares nothing with the generator.

Verified

pnpm test:all green (518 tests, up from 492) and pnpm build green, with /game/drills/pot-odds prerendered. The UI half is unverified: this ran in a runner with no browser and no device, so the stakes line, the two-button layout and the reveal have not been looked at on a screen. That needs a human, and so does the play-test the issue asks for: the 4-point margin is a judgement about which questions are fair, and nobody has yet disagreed with a grade.

Closes nothing. Part B still has per-kind progress, "hand strength" and the spot trainer left in it.

🤖 Generated with Claude Code

The same turn spot as "count your outs" with a price on it: they have bet,
both hands are face up, one card is to come, and the only question is
whether the pot is laying you enough.

Graded by enumeration rather than by simulation. The spec had this kind
grading against `estimateEquity`, which would have made the first
equity-graded thing in the app the thing people pay for. One card to come
against a hand you can see is 44 showdowns, so it does not have to be: the
equity is counted and the price is a fraction, and nothing here can mark a
correct call wrong. The `ambiguous` reject reason the contract has been
describing since part A arrives with it; the two rules attached to it about
seeding `estimateEquity` do not, because there is no rng in this kind.

The price comes from `requiredEquity` in config/potOdds, the same function
/learn/pot-odds prints its table from, so a member is taught and graded by
one definition of a price.

Half the spots are calls and half are folds, by construction: a spot is
only accepted if some bet this pot could carry would make it a call and
some other bet would make it a fold, and then a coin picks which. Priced at
random instead, four accepted spots in five are folds, and the rating would
be reading who had noticed that rather than who can count.

`membersOnly` is on the kind in the commit that registers it, and a test
asserts it by name: a paid kind that ships without the flag is free forever
under rule #8 (technology#55).
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying pip-web with  Cloudflare Pages  Cloudflare Pages

Latest commit: 2c80bac
Status: ✅  Deploy successful!
Preview URL: https://20491b57.pip-web-9oj.pages.dev
Branch Preview URL: https://feat-drills-pot-odds.pip-web-9oj.pages.dev

View logs

@will-lamerton
will-lamerton merged commit 72b9a8f into main Aug 29, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant