Say who can win each pot in the fewest names that answer it
The pot breakdown listed every eligible player for every pot. Pot eligibility is nested — the main pot is everyone still live and each side pot above it drops whoever was all-in below — so the main pot's line was every name at the table and each side pot repeated it minus one. The lines too long to fit were exactly the ones nobody needed spelled out, and the short ones at the bottom were the side pots a dealer actually announces by name. Measured on an iPhone 14: a single all-in five-handed already clipped the main pot, and twelve-handed the first row wanted 521px of a 254px slot. There was no count and no title, so a dealer reading "Alexandra…" could not tell whether three people or eleven were eligible — the number the showdown turns on. Each line now names whichever of "who is in" and "who is out" is shorter, which nesting guarantees is never more than half the table, and leads with the count because the line is right-aligned and it is the tail that gets cut off. "all 9", "8 in, not Mike from work". On a phone this takes one, two and three all-ins from every main-pot line clipped to nothing clipped at all; twelve-handed goes 6 clipped rows to 5, and even a cut row still opens with "9 in". The wizard's copy of the same announcement wraps instead — it is a dialog that scrolls, and it is what the dealer reads out before anybody shows a hand — so nothing there is ever cut off. The full list is also on the title for anyone with a pointer, which is the extra rather than the answer, since a tooltip is not a mechanism a keyboard reaches. potCalculator.test.js now proves the nesting across 20,000 random tables and asserts on its own generator, so the loop cannot go vacuous. Audit unchanged at 2 failing configurations and 3 offenders, both pre-existing. 787 unit tests pass. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_015bnp7xKUPFFSpwkYNFaPgb
This commit is contained in:
@@ -24,6 +24,7 @@ other in the page, in the load order from `TexasHoldem.cshtml`.
|
||||
| `readingTheShowdown.test.js` | The board, the picker that fills it, and who wins a side pot |
|
||||
| `theRail.test.js` | A phone on its side: which shape the bar is in, what it leaves under the felt, how a name is shortened, how the ring is pulled back onto the table |
|
||||
| `feltShape.test.js` | What shape the felt is at each phone size, resolved through the media queries in source order (see below) |
|
||||
| `potBreakdown.test.js` | How each pot says who can win it, and the nesting property that wording rests on (see below) |
|
||||
| `invariants.test.js` | 1000 randomised hands per property (see below) |
|
||||
|
||||
## The layout audit
|
||||
@@ -184,6 +185,32 @@ twelve are visible. The slit the floor defended against turned out to be unreach
|
||||
it came from forcing the custom property by hand. A test now asserts the floor is
|
||||
*absent*, with the numbers, so it doesn't get re-added by someone reasoning the same way.
|
||||
|
||||
## A property the wording depends on
|
||||
|
||||
`potBreakdown.test.js` covers how the pot breakdown says who can win each pot, and it
|
||||
leans on something `potCalculator.test.js` now proves: **pot eligibility is nested.** The
|
||||
main pot is everyone still live, and each side pot above it drops whoever was all-in
|
||||
below, so every side pot's players are a strict subset of the pot beneath it.
|
||||
|
||||
That makes "who is in" and "who is out" complements, which is what lets the line name
|
||||
whichever of the two is shorter and never spell out more than half the table. Listing
|
||||
every eligible player instead meant the main pot's line was every name at the table and
|
||||
each side pot repeated it minus one — and the lines too long to fit were exactly the ones
|
||||
nobody needed, while the short ones at the bottom were the side pots a dealer actually
|
||||
announces by name.
|
||||
|
||||
The nesting check runs 20,000 random tables, and it asserts on its own generator as well
|
||||
as on the code: if a change to the shapes stopped producing side pots, every assertion in
|
||||
the loop would be vacuous and the test would still pass, so it also requires that more
|
||||
than ten thousand of those tables had one.
|
||||
|
||||
Writing that check is where a comparison against `Set.length` went in — a `Set` has
|
||||
`.size`, so `here.length < below.length` was `2 < undefined`, which is false. As an
|
||||
assertion it failed everything; as a filter in a throwaway script it had passed
|
||||
everything, which is how it survived long enough to be written down. Both readings are
|
||||
silent. Prefer asserting the count you expect over comparing two things whose shapes you
|
||||
have not checked.
|
||||
|
||||
## Why the hand evaluator is tested the way it is
|
||||
|
||||
`handRank.js` is the only module here that can pay the wrong person without anybody
|
||||
|
||||
Reference in New Issue
Block a user