feat: hand parser uses 'x' blanks instead of guessing suits/cards

Per Brian: never invent. Unknown suit -> 'x' (e.g. "Ax","Kx","4x"); fully
unknown card -> "x". "AA, ace of spades" -> ["As","Ax"]; "AK on A4x" -> board
["Ax","4x","x"]. Each card's suit is independent (a hole 'As' doesn't make a
board ace 'As'). Viewer renders 'x' as a muted unknown card and 'Rx' as the rank
with a neutral suit dot.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-17 23:39:49 +00:00
parent 9491951da0
commit fc06b24528
2 changed files with 15 additions and 5 deletions
+8 -3
View File
@@ -216,7 +216,7 @@ Schema:
"game": "NLH" | "PLO" | ...,
"stakes": "<e.g. 1/3, or null>",
"hero_pos": "<UTG|UTG1|MP|LJ|HJ|CO|BTN|SB|BB, hero's position>",
"hero_cards": ["Rs", ...], // rank+suit; suit one of s h d c; null if unknown
"hero_cards": ["As","Ax", ...], // rank+suit (s/h/d/c); 'x' suit if unknown e.g. "Ax"; "x" for a fully unknown card
"players": [ // every player mentioned, incl. hero
{"pos": "<position>", "stack": <number|null>, "name": <string|null>, "cards": [".."]|null}
],
@@ -230,8 +230,13 @@ Schema:
}
Rules: infer positions and street order sensibly. Amounts are plain numbers (no $). \
Normalize cards like "Ah","Td","9s". Use null/omit for anything not stated. Stay faithful \
to what's described — do not invent action that isn't implied."""
NEVER invent suits or cards. A card is rank+suit where suit is one of s/h/d/c; if the suit \
wasn't stated, use 'x' for the suit (e.g. "Ax","Kx","4x"); if a whole card wasn't stated, \
use "x". Examples: "AA with the ace of spades" -> hero_cards ["As","Ax"]; "AK on an A4x \
board" -> board ["Ax","4x","x"]. Each card is independent: a suit named for one card does \
NOT apply to another — e.g. your hole "ace of spades" is a different card from a board ace \
whose suit is unstated (that board ace is "Ax", not "As"). Use null/omit for non-card \
details not stated. Stay faithful to what's described — do not invent action that isn't implied."""
def _safe_json(s: str) -> dict | None: