From b6cdf799dc03b41bf18bdc49f19e679fd5e03088 Mon Sep 17 00:00:00 2001 From: serversdown Date: Sat, 27 Jun 2026 04:49:50 +0000 Subject: [PATCH] feat: straddle support in recorder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a straddle from any non-blind seat (default 2×BB) via a preflop control. Recorded as a preflop post (fits the contract — order carries 'acts last'), tagged straddle for the log label + removability; the UI-only flag is dropped from the emitted structured hand. Blinds stay non-removable. Documented in HAND_HISTORY.md. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/HAND_HISTORY.md | 3 +++ lyra/web/static/recorder.js | 37 ++++++++++++++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/docs/HAND_HISTORY.md b/docs/HAND_HISTORY.md index 07e093e..b1e6527 100644 --- a/docs/HAND_HISTORY.md +++ b/docs/HAND_HISTORY.md @@ -53,6 +53,9 @@ DB, no shared UI components. If RTO is down, Lyra skips analysis and nothing bre - **Positions:** `UTG UTG1 UTG2 MP LJ HJ CO BTN SB BB`. - **Actions:** `post fold check call bet raise allin`. `amount` is a plain number (no `$`), null for non-sized actions (fold/check). Street boards appear as `{street, board}` entries. + A **straddle** is recorded as a preflop `post` at a non-blind position (typically 2×BB, + voluntary); preflop action starts left of it and it acts last, but that's reflected by + action *order*, not a distinct verb. - **Streets:** `preflop flop turn river`. `lyra/poker.py:normalize_structured()` is the single function that guarantees this shape. diff --git a/lyra/web/static/recorder.js b/lyra/web/static/recorder.js index c5e3eda..db89c37 100644 --- a/lyra/web/static/recorder.js +++ b/lyra/web/static/recorder.js @@ -239,8 +239,25 @@ `; + + // Straddle: a voluntary preflop blind from any non-blind seat, default 2×BB. + // Action starts left of it and it acts last preflop — order is whatever you enter. + const stradAmt = s.blinds.bb != null ? 2 * s.blinds.bb : null; + const stradElig = players.filter((p) => p !== "SB" && p !== "BB" && !s.actions.some((a) => a.straddle && a.pos === p)); + const straddle = + st === "preflop" && stradElig.length + ? `
+ + +
` + : ""; + return ` ${boardInput} + ${straddle}