feat: straddle support in recorder
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) <noreply@anthropic.com>
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -239,8 +239,25 @@
|
||||
<input class="rec-cards" data-act="board-cards" data-street="${st}" autocapitalize="off" autocomplete="off" spellcheck="false"
|
||||
placeholder="${st === "flop" ? "e.g. 7d 2c 5h" : "e.g. 5h"}" value="${esc(cardsText(s.board[st]))}">
|
||||
</label>`;
|
||||
|
||||
// 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
|
||||
? `<div class="rec-act-add">
|
||||
<select class="rec-sel" data-act="str-pos">
|
||||
<option value="">+ straddle${stradAmt != null ? " (" + stradAmt + ")" : ""}…</option>
|
||||
${stradElig.map((p) => `<option value="${p}">${p}</option>`).join("")}
|
||||
</select>
|
||||
<button class="rec-add-act" data-act="add-straddle">add</button>
|
||||
</div>`
|
||||
: "";
|
||||
|
||||
return `
|
||||
${boardInput}
|
||||
${straddle}
|
||||
<div class="rec-act-add">
|
||||
<select class="rec-sel" data-act="na-pos">
|
||||
<option value="">who</option>
|
||||
@@ -255,7 +272,16 @@
|
||||
</div>
|
||||
<div class="rec-log">
|
||||
${s.board[st] && s.board[st].length && st !== "preflop" ? `<div class="rec-ln brd">${st}: ${cardsText(s.board[st])}</div>` : ""}
|
||||
${s.actions.filter((a) => a.street === st).map((a, i) => `<div class="rec-ln">${a.pos} <b>${a.action}</b>${a.amount != null ? " " + a.amount : ""}${a.action === "post" ? "" : ` <button class="rec-undo" data-act="rm-action" data-street="${st}" data-i="${i}">✕</button>`}</div>`).join("")}
|
||||
${s.actions
|
||||
.filter((a) => a.street === st)
|
||||
.map((a, i) => {
|
||||
const label = a.straddle ? "straddle" : a.action;
|
||||
const amt = a.amount != null ? " " + a.amount : "";
|
||||
const fixed = a.action === "post" && !a.straddle; // blinds aren't removable
|
||||
const rm = fixed ? "" : ` <button class="rec-undo" data-act="rm-action" data-street="${st}" data-i="${i}">✕</button>`;
|
||||
return `<div class="rec-ln">${a.pos} <b>${label}</b>${amt}${rm}</div>`;
|
||||
})
|
||||
.join("")}
|
||||
</div>`;
|
||||
}
|
||||
|
||||
@@ -297,6 +323,15 @@
|
||||
case "add-action":
|
||||
addActionFromControls(ctx);
|
||||
break;
|
||||
case "add-straddle": {
|
||||
const sel = ctx.container.querySelector('[data-act="str-pos"]');
|
||||
const pos = sel && sel.value;
|
||||
if (pos) {
|
||||
const amt = s.blinds.bb != null ? 2 * s.blinds.bb : null;
|
||||
s.actions.push({ street: "preflop", pos, action: "post", amount: amt, straddle: true });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "rm-action":
|
||||
removeAction(s, t.getAttribute("data-street"), parseInt(t.getAttribute("data-i"), 10));
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user