Deal the straddle, instead of leaving the dealer to fake it #102

Closed
jheaps wants to merge 1 commits from feat/casino-holdem-straddle into fix/casino-holdem-landscape-ring
Owner

A straddle is a blind raise put out before the cards by the player left of the big blind, for twice it. Home games run them constantly, and the tool had no idea they existed — so a dealer's only way through was to deal the hand and have the straddler "raise" to $4, which gets the money right and the other two rules wrong.

Three rules at once:

  • The amount doubles as it goes left, and re-straddles carry on doubling.
  • First to act is left of the straddler, not left of the big blind — and the straddler keeps the option when it comes back round, even if nobody raised.
  • The minimum raise is twice the straddle. Measured off the big blind underneath it, a $2/$4 game prices the next raise at $6, and every player at the table will argue — correctly.

Tap Straddle on the deal prompt and the tool posts it, puts the right player on the clock and prices the raise. The seat wears an STR badge for the hand, read off what the deal actually posted rather than off the count, so the badge can't outlive the chips it stands for. It's a one-hand decision like posting in, and it clears when the button moves. There's a rulings entry for it too, since the argument it settles is one a dealer gets asked about.

Where the control sits, and what it cost

Its own line cost 44px of felt on every deal prompt, straddle or no straddle — measured at 390x844, and this bar is docked over the seats. So it rides on the deal row, which was already there. Three buttons across a 360px phone then want to wrap, which made the bar 64px taller and put the bottom seat three fifths behind it — this layout deliberately doesn't shrink the felt to suit (see the max-width: none override, where capping was tried and rejected in an earlier round). A 7rem floor on the deal button keeps the row to one line, so arming a straddle costs no felt at all: the bar is 147px with or without, and the bottom seat clears it at every width measured.

Validated

  • A straddled hand played through the UI on a phone: pot $7 off $1/$2/$4, Eve (left of the straddler) first to act owing $4, round to the big blind owing $2, back to Dee with Check / Raise and a raise pad opening at Min $8. Checked it down; pot $24 = 6 x $4.
  • 39 layout audits across 13 viewports x three states (one straddle armed, two armed, dealt): clean, no console errors.
  • Contrast and touch targets run explicitly over the new controls and the badge across 5 viewports x 4 states — 20/20 clean, nothing unmeasured. The STR badge is dark-on-violet at 5.76:1 against the darker stop; proved the check would catch it by washing the colour out on purpose first (1.39:1, flagged).
  • 20 new tests, suite at 438, 0 failures. Each of the three rules was broken on purpose to confirm a test fails: wrong first-to-act (3 fail), minimum measured off the big blind (1 fails), a flat rather than doubling chain (3 fail).

One thing this turned up

LayoutAudit.runAll() does not run the contrast check — it isn't in the list — and touch targets are opt-in behind a flag. So "audit clean" in these rounds has meant nine checks, not eleven, unless the other two were called by hand. Both work when called; they just aren't wired in. That's the next round, not this one.

A straddle is a blind raise put out before the cards by the player left of the big blind, for twice it. Home games run them constantly, and the tool had no idea they existed — so a dealer's only way through was to deal the hand and have the straddler "raise" to $4, which gets the money right and the other two rules wrong. **Three rules at once:** - The amount doubles as it goes left, and re-straddles carry on doubling. - First to act is left of the **straddler**, not left of the big blind — and the straddler keeps the option when it comes back round, even if nobody raised. - The minimum raise is **twice the straddle**. Measured off the big blind underneath it, a $2/$4 game prices the next raise at $6, and every player at the table will argue — correctly. Tap **Straddle** on the deal prompt and the tool posts it, puts the right player on the clock and prices the raise. The seat wears an **STR** badge for the hand, read off what the deal actually posted rather than off the count, so the badge can't outlive the chips it stands for. It's a one-hand decision like posting in, and it clears when the button moves. There's a rulings entry for it too, since the argument it settles is one a dealer gets asked about. ### Where the control sits, and what it cost Its own line cost **44px of felt on every deal prompt**, straddle or no straddle — measured at 390x844, and this bar is docked over the seats. So it rides on the deal row, which was already there. Three buttons across a 360px phone then want to wrap, which made the bar 64px taller and put the bottom seat **three fifths behind it** — this layout deliberately doesn't shrink the felt to suit (see the `max-width: none` override, where capping was tried and rejected in an earlier round). A 7rem floor on the deal button keeps the row to one line, so arming a straddle costs no felt at all: the bar is 147px with or without, and the bottom seat clears it at every width measured. ### Validated - A straddled hand played through the UI on a phone: pot $7 off $1/$2/$4, Eve (left of the straddler) first to act owing $4, round to the big blind owing $2, back to Dee with **Check / Raise** and a raise pad opening at **Min $8**. Checked it down; pot $24 = 6 x $4. - 39 layout audits across 13 viewports x three states (one straddle armed, two armed, dealt): clean, no console errors. - Contrast and touch targets run explicitly over the new controls and the badge across 5 viewports x 4 states — 20/20 clean, nothing unmeasured. The STR badge is dark-on-violet at 5.76:1 against the darker stop; proved the check would catch it by washing the colour out on purpose first (1.39:1, flagged). - 20 new tests, suite at **438, 0 failures**. Each of the three rules was broken on purpose to confirm a test fails: wrong first-to-act (3 fail), minimum measured off the big blind (1 fails), a flat rather than doubling chain (3 fail). ### One thing this turned up `LayoutAudit.runAll()` does not run the contrast check — it isn't in the list — and touch targets are opt-in behind a flag. So "audit clean" in these rounds has meant nine checks, not eleven, unless the other two were called by hand. Both work when called; they just aren't wired in. That's the next round, not this one.
jheaps added 1 commit 2026-09-02 03:32:52 -06:00
A straddle is a blind raise put out before the cards by the player left of the
big blind, for twice it. Home games run them constantly, and the tool had no
idea they existed — so a dealer's only way through was to deal the hand and have
the straddler "raise" to $4, which gets the money right and the other two rules
wrong.

There are three at once:

  - the amount doubles as it goes left, and re-straddles carry on doubling;
  - first to act is left of the *straddler*, not left of the big blind, and the
    straddler keeps the option when it comes back round even if nobody raised;
  - the minimum raise is twice the straddle. Measured off the big blind
    underneath it, a $2/$4 game prices the next raise at $6, and every player at
    the table will argue — correctly.

Tap Straddle on the deal prompt and the tool posts it, puts the right player on
the clock and prices the raise. The seat wears an STR badge for the hand, read
off what the deal actually posted rather than off the count, so the badge can't
outlive the chips it stands for. It's a one-hand decision, like posting in, and
it clears when the button moves.

The control sits on the deal row rather than a line of its own: measured at
390x844, its own line cost 44px of felt on every deal prompt, straddle or no
straddle, and this bar is docked over the seats. Three buttons across a 360px
phone want to wrap, which made the bar 64px taller and put the bottom seat three
fifths behind it — this layout deliberately doesn't shrink the felt to suit, so
the deal button is given a 7rem floor instead, which keeps the row to one line
and the cost to nothing.

20 new tests, checked by breaking each of the three rules on purpose first: the
wrong first-to-act, the minimum measured off the big blind, and a flat rather
than doubling chain each fail a different one.

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_015bnp7xKUPFFSpwkYNFaPgb
jheaps closed this pull request 2026-09-02 09:58:04 -06:00

Pull request closed

Please reopen this pull request to perform a merge.
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: jheaps/JoshHeaps.Net#102