FAILURE MAP
← Case archive

FA-82281 / Poker hand evaluation / Open access

Dead cards still counted as live outs · case 01

Outs exposed in other players' hands are counted as live.

Verified by executionVariant 1 · 8 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

Only the player's own cards are subtracted from each completing rank.

VERIFIED REPAIR

Subtract every seen card: the player's cards and the dead cards.

Unsuccessful approach: Subtracting a single card when the rank has been seen at all undercounts when two or more copies are dead.

Case contract

Input: {"cards": known hole and board cards (4 to 6, no straight yet), "dead": other seen cards}. Return how many unseen cards would give the player a five-card straight (ace plays high or low): for every rank that completes a straight, count its four cards minus those already seen in cards or dead.

Why this case matters

Out counts feed pot-odds displays and all-in equity shortcuts.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    R='23456789TJQKA'
    known=x['cards']+x.get('dead',[])
    ranks={R.index(c[0])+2 for c in x['cards']}
    def has(rs):
        rs=set(rs)
        if 14 in rs: rs.add(1)
        return any(all(t-i in rs for i in range(5)) for t in range(5,15))
    if has(ranks): return 0
    outs=0
    for r in range(2,15):
        if has(ranks|{r}):
            outs+=4-sum(1 for c in x['cards'] if R.index(c[0])+2==r)
    return outs
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('open ended', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': []}, 8),
  ('gutshot', {'cards': ['8h', '9d', 'Jc', 'Qs', '2h'], 'dead': []}, 4),
  ('ace-low draw', {'cards': ['Ah', '2d', '3c', '4s', 'Kh'], 'dead': []}, 4),
  ('ace-high draw', {'cards': ['Ah', 'Kd', 'Qc', 'Js', '2h'], 'dead': []}, 4),
  ('open ended with dead', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', 'Qd', 'Qs']},
   5),
  ('paired board seen out', {'cards': ['8h', '9d', 'Tc', 'Js', 'Qh'], 'dead': []}, 0),
  ('wheel gutshot with dead', {'cards': ['Ah', '2d', '4c', '5s', 'Jh'], 'dead': ['3h']}, 3),
  ('two dead copies of an out',
   {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', '7d', 'Qd']}, 5)],
 [('ace-high draw', {'cards': ['Ah', 'Kd', 'Qc', 'Js', '2h'], 'dead': []}, 4),
  ('open ended with dead', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', 'Qd', 'Qs']},
   5),
  ('paired board seen out', {'cards': ['8h', '9d', 'Tc', 'Js', 'Qh'], 'dead': []}, 0),
  ('no draw', {'cards': ['2h', '7d', 'Tc', 'Ks', '4h'], 'dead': []}, 0),
  ('double gutshot', {'cards': ['7h', '9d', 'Tc', 'Js', 'Kh', '2c'], 'dead': []}, 8),
  ('wheel gutshot with dead', {'cards': ['Ah', '2d', '4c', '5s', 'Jh'], 'dead': ['3h']}, 3),
  ('three to straight only', {'cards': ['8h', '9d', 'Tc', '2s', '3h'], 'dead': []}, 0),
  ('two dead copies of an out',
   {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', '7d', 'Qd']}, 5)],
 [('open ended', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': []}, 8),
  ('gutshot', {'cards': ['8h', '9d', 'Jc', 'Qs', '2h'], 'dead': []}, 4),
  ('open ended with dead', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', 'Qd', 'Qs']},
   5),
  ('double gutshot', {'cards': ['7h', '9d', 'Tc', 'Js', 'Kh', '2c'], 'dead': []}, 8),
  ('wheel gutshot with dead', {'cards': ['Ah', '2d', '4c', '5s', 'Jh'], 'dead': ['3h']}, 3),
  ('three to straight only', {'cards': ['8h', '9d', 'Tc', '2s', '3h'], 'dead': []}, 0),
  ('two dead copies of an out',
   {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', '7d', 'Qd']}, 5),
  ('open ender with seen nine', {'cards': ['5h', '6d', '7c', '8s', '8h'], 'dead': ['9c', '4d']},
   6)],
 [('open ended', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': []}, 8),
  ('gutshot', {'cards': ['8h', '9d', 'Jc', 'Qs', '2h'], 'dead': []}, 4),
  ('ace-low draw', {'cards': ['Ah', '2d', '3c', '4s', 'Kh'], 'dead': []}, 4),
  ('ace-high draw', {'cards': ['Ah', 'Kd', 'Qc', 'Js', '2h'], 'dead': []}, 4),
  ('open ended with dead', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', 'Qd', 'Qs']},
   5),
  ('wheel gutshot with dead', {'cards': ['Ah', '2d', '4c', '5s', 'Jh'], 'dead': ['3h']}, 3),
  ('two dead copies of an out',
   {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', '7d', 'Qd']}, 5),
  ('open ender with seen nine', {'cards': ['5h', '6d', '7c', '8s', '8h'], 'dead': ['9c', '4d']},
   6)],
 [('open ended', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': []}, 8),
  ('gutshot', {'cards': ['8h', '9d', 'Jc', 'Qs', '2h'], 'dead': []}, 4),
  ('ace-low draw', {'cards': ['Ah', '2d', '3c', '4s', 'Kh'], 'dead': []}, 4),
  ('ace-high draw', {'cards': ['Ah', 'Kd', 'Qc', 'Js', '2h'], 'dead': []}, 4),
  ('open ended with dead', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', 'Qd', 'Qs']},
   5),
  ('paired board seen out', {'cards': ['8h', '9d', 'Tc', 'Js', 'Qh'], 'dead': []}, 0),
  ('wheel gutshot with dead', {'cards': ['Ah', '2d', '4c', '5s', 'Jh'], 'dead': ['3h']}, 3),
  ('two dead copies of an out',
   {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', '7d', 'Qd']}, 5)]]
for label, args, expected in fixtures[N-1]:
    try:
        actual = solve(args)
    except Exception as exc:
        actual = 'error:' + type(exc).__name__
    check(label, actual, expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
open ended88Passed
gutshot44Passed
ace-low draw44Passed
ace-high draw44Passed
open ended with dead85Failed
paired board seen out00Passed
wheel gutshot with dead43Failed
two dead copies of an out85Failed

SHA-256 / e66734082d7bcf38352d86c84d3e8c03ae0f69b7b5214c43bb8971fe25786897

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    R='23456789TJQKA'
    known=x['cards']+x.get('dead',[])
    ranks={R.index(c[0])+2 for c in x['cards']}
    def has(rs):
        rs=set(rs)
        if 14 in rs: rs.add(1)
        return any(all(t-i in rs for i in range(5)) for t in range(5,15))
    if has(ranks): return 0
    outs=0
    for r in range(2,15):
        if has(ranks|{r}):
            outs+=4-(1 if any(R.index(c[0])+2==r for c in known) else 0)
    return outs
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('open ended', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': []}, 8),
  ('gutshot', {'cards': ['8h', '9d', 'Jc', 'Qs', '2h'], 'dead': []}, 4),
  ('ace-low draw', {'cards': ['Ah', '2d', '3c', '4s', 'Kh'], 'dead': []}, 4),
  ('ace-high draw', {'cards': ['Ah', 'Kd', 'Qc', 'Js', '2h'], 'dead': []}, 4),
  ('open ended with dead', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', 'Qd', 'Qs']},
   5),
  ('paired board seen out', {'cards': ['8h', '9d', 'Tc', 'Js', 'Qh'], 'dead': []}, 0),
  ('wheel gutshot with dead', {'cards': ['Ah', '2d', '4c', '5s', 'Jh'], 'dead': ['3h']}, 3),
  ('two dead copies of an out',
   {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', '7d', 'Qd']}, 5)],
 [('ace-high draw', {'cards': ['Ah', 'Kd', 'Qc', 'Js', '2h'], 'dead': []}, 4),
  ('open ended with dead', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', 'Qd', 'Qs']},
   5),
  ('paired board seen out', {'cards': ['8h', '9d', 'Tc', 'Js', 'Qh'], 'dead': []}, 0),
  ('no draw', {'cards': ['2h', '7d', 'Tc', 'Ks', '4h'], 'dead': []}, 0),
  ('double gutshot', {'cards': ['7h', '9d', 'Tc', 'Js', 'Kh', '2c'], 'dead': []}, 8),
  ('wheel gutshot with dead', {'cards': ['Ah', '2d', '4c', '5s', 'Jh'], 'dead': ['3h']}, 3),
  ('three to straight only', {'cards': ['8h', '9d', 'Tc', '2s', '3h'], 'dead': []}, 0),
  ('two dead copies of an out',
   {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', '7d', 'Qd']}, 5)],
 [('open ended', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': []}, 8),
  ('gutshot', {'cards': ['8h', '9d', 'Jc', 'Qs', '2h'], 'dead': []}, 4),
  ('open ended with dead', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', 'Qd', 'Qs']},
   5),
  ('double gutshot', {'cards': ['7h', '9d', 'Tc', 'Js', 'Kh', '2c'], 'dead': []}, 8),
  ('wheel gutshot with dead', {'cards': ['Ah', '2d', '4c', '5s', 'Jh'], 'dead': ['3h']}, 3),
  ('three to straight only', {'cards': ['8h', '9d', 'Tc', '2s', '3h'], 'dead': []}, 0),
  ('two dead copies of an out',
   {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', '7d', 'Qd']}, 5),
  ('open ender with seen nine', {'cards': ['5h', '6d', '7c', '8s', '8h'], 'dead': ['9c', '4d']},
   6)],
 [('open ended', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': []}, 8),
  ('gutshot', {'cards': ['8h', '9d', 'Jc', 'Qs', '2h'], 'dead': []}, 4),
  ('ace-low draw', {'cards': ['Ah', '2d', '3c', '4s', 'Kh'], 'dead': []}, 4),
  ('ace-high draw', {'cards': ['Ah', 'Kd', 'Qc', 'Js', '2h'], 'dead': []}, 4),
  ('open ended with dead', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', 'Qd', 'Qs']},
   5),
  ('wheel gutshot with dead', {'cards': ['Ah', '2d', '4c', '5s', 'Jh'], 'dead': ['3h']}, 3),
  ('two dead copies of an out',
   {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', '7d', 'Qd']}, 5),
  ('open ender with seen nine', {'cards': ['5h', '6d', '7c', '8s', '8h'], 'dead': ['9c', '4d']},
   6)],
 [('open ended', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': []}, 8),
  ('gutshot', {'cards': ['8h', '9d', 'Jc', 'Qs', '2h'], 'dead': []}, 4),
  ('ace-low draw', {'cards': ['Ah', '2d', '3c', '4s', 'Kh'], 'dead': []}, 4),
  ('ace-high draw', {'cards': ['Ah', 'Kd', 'Qc', 'Js', '2h'], 'dead': []}, 4),
  ('open ended with dead', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', 'Qd', 'Qs']},
   5),
  ('paired board seen out', {'cards': ['8h', '9d', 'Tc', 'Js', 'Qh'], 'dead': []}, 0),
  ('wheel gutshot with dead', {'cards': ['Ah', '2d', '4c', '5s', 'Jh'], 'dead': ['3h']}, 3),
  ('two dead copies of an out',
   {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', '7d', 'Qd']}, 5)]]
for label, args, expected in fixtures[N-1]:
    try:
        actual = solve(args)
    except Exception as exc:
        actual = 'error:' + type(exc).__name__
    check(label, actual, expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
open ended88Passed
gutshot44Passed
ace-low draw44Passed
ace-high draw44Passed
open ended with dead65Failed
paired board seen out00Passed
wheel gutshot with dead33Passed
two dead copies of an out65Failed

SHA-256 / 1856ca18bf55cfd8f8e74348ce84c40f21770d35591f2eca36d966c9c346190d

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    R='23456789TJQKA'
    known=x['cards']+x.get('dead',[])
    ranks={R.index(c[0])+2 for c in x['cards']}
    def has(rs):
        rs=set(rs)
        if 14 in rs: rs.add(1)
        return any(all(t-i in rs for i in range(5)) for t in range(5,15))
    if has(ranks): return 0
    outs=0
    for r in range(2,15):
        if has(ranks|{r}):
            outs+=4-sum(1 for c in known if R.index(c[0])+2==r)
    return outs
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('open ended', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': []}, 8),
  ('gutshot', {'cards': ['8h', '9d', 'Jc', 'Qs', '2h'], 'dead': []}, 4),
  ('ace-low draw', {'cards': ['Ah', '2d', '3c', '4s', 'Kh'], 'dead': []}, 4),
  ('ace-high draw', {'cards': ['Ah', 'Kd', 'Qc', 'Js', '2h'], 'dead': []}, 4),
  ('open ended with dead', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', 'Qd', 'Qs']},
   5),
  ('paired board seen out', {'cards': ['8h', '9d', 'Tc', 'Js', 'Qh'], 'dead': []}, 0),
  ('wheel gutshot with dead', {'cards': ['Ah', '2d', '4c', '5s', 'Jh'], 'dead': ['3h']}, 3),
  ('two dead copies of an out',
   {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', '7d', 'Qd']}, 5)],
 [('ace-high draw', {'cards': ['Ah', 'Kd', 'Qc', 'Js', '2h'], 'dead': []}, 4),
  ('open ended with dead', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', 'Qd', 'Qs']},
   5),
  ('paired board seen out', {'cards': ['8h', '9d', 'Tc', 'Js', 'Qh'], 'dead': []}, 0),
  ('no draw', {'cards': ['2h', '7d', 'Tc', 'Ks', '4h'], 'dead': []}, 0),
  ('double gutshot', {'cards': ['7h', '9d', 'Tc', 'Js', 'Kh', '2c'], 'dead': []}, 8),
  ('wheel gutshot with dead', {'cards': ['Ah', '2d', '4c', '5s', 'Jh'], 'dead': ['3h']}, 3),
  ('three to straight only', {'cards': ['8h', '9d', 'Tc', '2s', '3h'], 'dead': []}, 0),
  ('two dead copies of an out',
   {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', '7d', 'Qd']}, 5)],
 [('open ended', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': []}, 8),
  ('gutshot', {'cards': ['8h', '9d', 'Jc', 'Qs', '2h'], 'dead': []}, 4),
  ('open ended with dead', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', 'Qd', 'Qs']},
   5),
  ('double gutshot', {'cards': ['7h', '9d', 'Tc', 'Js', 'Kh', '2c'], 'dead': []}, 8),
  ('wheel gutshot with dead', {'cards': ['Ah', '2d', '4c', '5s', 'Jh'], 'dead': ['3h']}, 3),
  ('three to straight only', {'cards': ['8h', '9d', 'Tc', '2s', '3h'], 'dead': []}, 0),
  ('two dead copies of an out',
   {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', '7d', 'Qd']}, 5),
  ('open ender with seen nine', {'cards': ['5h', '6d', '7c', '8s', '8h'], 'dead': ['9c', '4d']},
   6)],
 [('open ended', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': []}, 8),
  ('gutshot', {'cards': ['8h', '9d', 'Jc', 'Qs', '2h'], 'dead': []}, 4),
  ('ace-low draw', {'cards': ['Ah', '2d', '3c', '4s', 'Kh'], 'dead': []}, 4),
  ('ace-high draw', {'cards': ['Ah', 'Kd', 'Qc', 'Js', '2h'], 'dead': []}, 4),
  ('open ended with dead', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', 'Qd', 'Qs']},
   5),
  ('wheel gutshot with dead', {'cards': ['Ah', '2d', '4c', '5s', 'Jh'], 'dead': ['3h']}, 3),
  ('two dead copies of an out',
   {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', '7d', 'Qd']}, 5),
  ('open ender with seen nine', {'cards': ['5h', '6d', '7c', '8s', '8h'], 'dead': ['9c', '4d']},
   6)],
 [('open ended', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': []}, 8),
  ('gutshot', {'cards': ['8h', '9d', 'Jc', 'Qs', '2h'], 'dead': []}, 4),
  ('ace-low draw', {'cards': ['Ah', '2d', '3c', '4s', 'Kh'], 'dead': []}, 4),
  ('ace-high draw', {'cards': ['Ah', 'Kd', 'Qc', 'Js', '2h'], 'dead': []}, 4),
  ('open ended with dead', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', 'Qd', 'Qs']},
   5),
  ('paired board seen out', {'cards': ['8h', '9d', 'Tc', 'Js', 'Qh'], 'dead': []}, 0),
  ('wheel gutshot with dead', {'cards': ['Ah', '2d', '4c', '5s', 'Jh'], 'dead': ['3h']}, 3),
  ('two dead copies of an out',
   {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', '7d', 'Qd']}, 5)]]
for label, args, expected in fixtures[N-1]:
    try:
        actual = solve(args)
    except Exception as exc:
        actual = 'error:' + type(exc).__name__
    check(label, actual, expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
open ended88Passed
gutshot44Passed
ace-low draw44Passed
ace-high draw44Passed
open ended with dead55Passed
paired board seen out00Passed
wheel gutshot with dead33Passed
two dead copies of an out55Passed

SHA-256 / b5cf8a10f8154533dd76e0333b536ed58aed0451e3ce32ddf7bc6e110003c009

Verification & scope

A deterministic toy model with an explicitly stated contract; card strings are rank+suit (for example "As", "Td"); no claim of conformance to any casino or tournament rulebook. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.

Observations recorded using Python 3.12.14 at 2026-09-29T14:50:10.740232+00:00.

Case digest / 1b606ecb08fe5eeb64568a45317544d2e5642eba34e67f190786529412b0f9c1