FAILURE MAP
← Case archive

FA-82181 / Poker hand evaluation / Open access

Wheel announced as an ace-high straight · case 01

A-2-3-4-5 is announced "Straight, Ace high" and the steel wheel as a royal flush.

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

ROOT CAUSE

The announced top card is the numerically highest card even for the wheel.

THE FAILURE

The announced top card is the numerically highest card even for the wheel.

Unsuccessful approach: Taking the lowest card announces the wheel as "Two high".

Case contract

Input: five distinct cards. Return the showdown announcement: "Royal Flush", "Straight Flush, <top> high", "Four <plural>", "Full House, <trips plural> full of <pair plural>", "Flush, <top> high", "Straight, <top> high" (wheel is Five high), "Three <plural>", "Two Pair, <higher plural> and <lower plural>", "Pair of <plural>", "High Card, <top>". Rank names Two..Ace; plurals add "s" except Deuces and Sixes.

Why this case matters

Dealer announcements and hand histories must name the same hand the evaluator paid.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import collections
N = 1
observations = []
def solve(x):
    R='23456789TJQKA'
    NAME={2:'Two',3:'Three',4:'Four',5:'Five',6:'Six',7:'Seven',8:'Eight',9:'Nine',10:'Ten',11:'Jack',12:'Queen',13:'King',14:'Ace'}
    def pl(v): return {2:'Deuces',6:'Sixes'}.get(v, NAME[v]+'s')
    vals=sorted((R.index(c[0])+2 for c in x), reverse=True)
    cnt=collections.Counter(vals)
    groups=sorted(cnt, key=lambda v:(cnt[v],v), reverse=True)
    shape=sorted(cnt.values(), reverse=True)
    flush=len({c[1] for c in x})==1
    wheel=vals==[14,5,4,3,2]
    straight=len(cnt)==5 and (vals[0]-vals[4]==4 or wheel)
    top=vals[0]
    if straight and flush: return 'Royal Flush' if top==14 else 'Straight Flush, %s high' % NAME[top]
    if shape==[4,1]: return 'Four %s' % pl(groups[0])
    if shape==[3,2]: return 'Full House, %s full of %s' % (pl(groups[0]), pl(groups[1]))
    if flush: return 'Flush, %s high' % NAME[vals[0]]
    if straight: return 'Straight, %s high' % NAME[top]
    if shape==[3,1,1]: return 'Three %s' % pl(groups[0])
    if shape==[2,2,1]: return 'Two Pair, %s and %s' % (pl(groups[0]), pl(groups[1]))
    if shape==[2,1,1,1]: return 'Pair of %s' % pl(groups[0])
    return 'High Card, %s' % NAME[vals[0]]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('pair of sixes', ['6h', '6d', 'Kc', '9s', '2h'], 'Pair of Sixes'),
  ('pair of deuces', ['2h', '2d', 'Kc', '9s', '5h'], 'Pair of Deuces'),
  ('wheel', ['Ah', '2d', '3c', '4s', '5h'], 'Straight, Five high'),
  ('steel wheel', ['As', '2s', '3s', '4s', '5s'], 'Straight Flush, Five high'),
  ('royal', ['Th', 'Jh', 'Qh', 'Kh', 'Ah'], 'Royal Flush'),
  ('king-high straight flush', ['9d', 'Td', 'Jd', 'Qd', 'Kd'], 'Straight Flush, King high'),
  ('threes full of kings', ['3h', '3d', '3c', 'Ks', 'Kh'], 'Full House, Threes full of Kings'),
  ('kings full of threes', ['Kh', 'Kd', 'Kc', '3s', '3h'], 'Full House, Kings full of Threes')],
 [('wheel', ['Ah', '2d', '3c', '4s', '5h'], 'Straight, Five high'),
  ('steel wheel', ['As', '2s', '3s', '4s', '5s'], 'Straight Flush, Five high'),
  ('king-high straight flush', ['9d', 'Td', 'Jd', 'Qd', 'Kd'], 'Straight Flush, King high'),
  ('threes full of kings', ['3h', '3d', '3c', 'Ks', 'Kh'], 'Full House, Threes full of Kings'),
  ('kings full of threes', ['Kh', 'Kd', 'Kc', '3s', '3h'], 'Full House, Kings full of Threes'),
  ('two pair ace kicker', ['Ah', 'Kd', 'Kc', '7s', '7h'], 'Two Pair, Kings and Sevens'),
  ('two pair low kicker', ['Kh', 'Kd', '7c', '7s', '2h'], 'Two Pair, Kings and Sevens'),
  ('pair below high cards', ['Ah', 'Kd', '5c', '5s', '9h'], 'Pair of Fives')],
 [('wheel', ['Ah', '2d', '3c', '4s', '5h'], 'Straight, Five high'),
  ('steel wheel', ['As', '2s', '3s', '4s', '5s'], 'Straight Flush, Five high'),
  ('two pair ace kicker', ['Ah', 'Kd', 'Kc', '7s', '7h'], 'Two Pair, Kings and Sevens'),
  ('two pair low kicker', ['Kh', 'Kd', '7c', '7s', '2h'], 'Two Pair, Kings and Sevens'),
  ('pair below high cards', ['Ah', 'Kd', '5c', '5s', '9h'], 'Pair of Fives'),
  ('high card', ['Ah', 'Jd', '8c', '5s', '3h'], 'High Card, Ace'),
  ('four nines', ['9h', '9d', '9c', '9s', '2h'], 'Four Nines'),
  ('flush', ['2c', '7c', '9c', 'Jc', 'Qc'], 'Flush, Queen high')],
 [('pair of sixes', ['6h', '6d', 'Kc', '9s', '2h'], 'Pair of Sixes'),
  ('wheel', ['Ah', '2d', '3c', '4s', '5h'], 'Straight, Five high'),
  ('steel wheel', ['As', '2s', '3s', '4s', '5s'], 'Straight Flush, Five high'),
  ('high card', ['Ah', 'Jd', '8c', '5s', '3h'], 'High Card, Ace'),
  ('four nines', ['9h', '9d', '9c', '9s', '2h'], 'Four Nines'),
  ('flush', ['2c', '7c', '9c', 'Jc', 'Qc'], 'Flush, Queen high'),
  ('six-high straight', ['2h', '3d', '4c', '5s', '6h'], 'Straight, Six high'),
  ('three sixes', ['6h', '6d', '6c', 'Ks', '2h'], 'Three Sixes')],
 [('pair of sixes', ['6h', '6d', 'Kc', '9s', '2h'], 'Pair of Sixes'),
  ('pair of deuces', ['2h', '2d', 'Kc', '9s', '5h'], 'Pair of Deuces'),
  ('wheel', ['Ah', '2d', '3c', '4s', '5h'], 'Straight, Five high'),
  ('steel wheel', ['As', '2s', '3s', '4s', '5s'], 'Straight Flush, Five high'),
  ('royal', ['Th', 'Jh', 'Qh', 'Kh', 'Ah'], 'Royal Flush'),
  ('king-high straight flush', ['9d', 'Td', 'Jd', 'Qd', 'Kd'], 'Straight Flush, King high'),
  ('six-high straight', ['2h', '3d', '4c', '5s', '6h'], 'Straight, Six high'),
  ('three sixes', ['6h', '6d', '6c', 'Ks', '2h'], 'Three Sixes')]]
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
pair of sixesPair of SixesPair of SixesPassed
pair of deucesPair of DeucesPair of DeucesPassed
wheelStraight, Ace highStraight, Five highFailed
steel wheelRoyal FlushStraight Flush, Five highFailed
royalRoyal FlushRoyal FlushPassed
king-high straight flushStraight Flush, King highStraight Flush, King highPassed
threes full of kingsFull House, Threes full of KingsFull House, Threes full of KingsPassed
kings full of threesFull House, Kings full of ThreesFull House, Kings full of ThreesPassed

SHA-256 / dec73a6b929c0daa37fbf1681272319427288956a2a69eb125cabc6bad1682ff

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import collections
N = 1
observations = []
def solve(x):
    R='23456789TJQKA'
    NAME={2:'Two',3:'Three',4:'Four',5:'Five',6:'Six',7:'Seven',8:'Eight',9:'Nine',10:'Ten',11:'Jack',12:'Queen',13:'King',14:'Ace'}
    def pl(v): return {2:'Deuces',6:'Sixes'}.get(v, NAME[v]+'s')
    vals=sorted((R.index(c[0])+2 for c in x), reverse=True)
    cnt=collections.Counter(vals)
    groups=sorted(cnt, key=lambda v:(cnt[v],v), reverse=True)
    shape=sorted(cnt.values(), reverse=True)
    flush=len({c[1] for c in x})==1
    wheel=vals==[14,5,4,3,2]
    straight=len(cnt)==5 and (vals[0]-vals[4]==4 or wheel)
    top=vals[-1] if wheel else vals[0]
    if straight and flush: return 'Royal Flush' if top==14 else 'Straight Flush, %s high' % NAME[top]
    if shape==[4,1]: return 'Four %s' % pl(groups[0])
    if shape==[3,2]: return 'Full House, %s full of %s' % (pl(groups[0]), pl(groups[1]))
    if flush: return 'Flush, %s high' % NAME[vals[0]]
    if straight: return 'Straight, %s high' % NAME[top]
    if shape==[3,1,1]: return 'Three %s' % pl(groups[0])
    if shape==[2,2,1]: return 'Two Pair, %s and %s' % (pl(groups[0]), pl(groups[1]))
    if shape==[2,1,1,1]: return 'Pair of %s' % pl(groups[0])
    return 'High Card, %s' % NAME[vals[0]]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('pair of sixes', ['6h', '6d', 'Kc', '9s', '2h'], 'Pair of Sixes'),
  ('pair of deuces', ['2h', '2d', 'Kc', '9s', '5h'], 'Pair of Deuces'),
  ('wheel', ['Ah', '2d', '3c', '4s', '5h'], 'Straight, Five high'),
  ('steel wheel', ['As', '2s', '3s', '4s', '5s'], 'Straight Flush, Five high'),
  ('royal', ['Th', 'Jh', 'Qh', 'Kh', 'Ah'], 'Royal Flush'),
  ('king-high straight flush', ['9d', 'Td', 'Jd', 'Qd', 'Kd'], 'Straight Flush, King high'),
  ('threes full of kings', ['3h', '3d', '3c', 'Ks', 'Kh'], 'Full House, Threes full of Kings'),
  ('kings full of threes', ['Kh', 'Kd', 'Kc', '3s', '3h'], 'Full House, Kings full of Threes')],
 [('wheel', ['Ah', '2d', '3c', '4s', '5h'], 'Straight, Five high'),
  ('steel wheel', ['As', '2s', '3s', '4s', '5s'], 'Straight Flush, Five high'),
  ('king-high straight flush', ['9d', 'Td', 'Jd', 'Qd', 'Kd'], 'Straight Flush, King high'),
  ('threes full of kings', ['3h', '3d', '3c', 'Ks', 'Kh'], 'Full House, Threes full of Kings'),
  ('kings full of threes', ['Kh', 'Kd', 'Kc', '3s', '3h'], 'Full House, Kings full of Threes'),
  ('two pair ace kicker', ['Ah', 'Kd', 'Kc', '7s', '7h'], 'Two Pair, Kings and Sevens'),
  ('two pair low kicker', ['Kh', 'Kd', '7c', '7s', '2h'], 'Two Pair, Kings and Sevens'),
  ('pair below high cards', ['Ah', 'Kd', '5c', '5s', '9h'], 'Pair of Fives')],
 [('wheel', ['Ah', '2d', '3c', '4s', '5h'], 'Straight, Five high'),
  ('steel wheel', ['As', '2s', '3s', '4s', '5s'], 'Straight Flush, Five high'),
  ('two pair ace kicker', ['Ah', 'Kd', 'Kc', '7s', '7h'], 'Two Pair, Kings and Sevens'),
  ('two pair low kicker', ['Kh', 'Kd', '7c', '7s', '2h'], 'Two Pair, Kings and Sevens'),
  ('pair below high cards', ['Ah', 'Kd', '5c', '5s', '9h'], 'Pair of Fives'),
  ('high card', ['Ah', 'Jd', '8c', '5s', '3h'], 'High Card, Ace'),
  ('four nines', ['9h', '9d', '9c', '9s', '2h'], 'Four Nines'),
  ('flush', ['2c', '7c', '9c', 'Jc', 'Qc'], 'Flush, Queen high')],
 [('pair of sixes', ['6h', '6d', 'Kc', '9s', '2h'], 'Pair of Sixes'),
  ('wheel', ['Ah', '2d', '3c', '4s', '5h'], 'Straight, Five high'),
  ('steel wheel', ['As', '2s', '3s', '4s', '5s'], 'Straight Flush, Five high'),
  ('high card', ['Ah', 'Jd', '8c', '5s', '3h'], 'High Card, Ace'),
  ('four nines', ['9h', '9d', '9c', '9s', '2h'], 'Four Nines'),
  ('flush', ['2c', '7c', '9c', 'Jc', 'Qc'], 'Flush, Queen high'),
  ('six-high straight', ['2h', '3d', '4c', '5s', '6h'], 'Straight, Six high'),
  ('three sixes', ['6h', '6d', '6c', 'Ks', '2h'], 'Three Sixes')],
 [('pair of sixes', ['6h', '6d', 'Kc', '9s', '2h'], 'Pair of Sixes'),
  ('pair of deuces', ['2h', '2d', 'Kc', '9s', '5h'], 'Pair of Deuces'),
  ('wheel', ['Ah', '2d', '3c', '4s', '5h'], 'Straight, Five high'),
  ('steel wheel', ['As', '2s', '3s', '4s', '5s'], 'Straight Flush, Five high'),
  ('royal', ['Th', 'Jh', 'Qh', 'Kh', 'Ah'], 'Royal Flush'),
  ('king-high straight flush', ['9d', 'Td', 'Jd', 'Qd', 'Kd'], 'Straight Flush, King high'),
  ('six-high straight', ['2h', '3d', '4c', '5s', '6h'], 'Straight, Six high'),
  ('three sixes', ['6h', '6d', '6c', 'Ks', '2h'], 'Three Sixes')]]
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
pair of sixesPair of SixesPair of SixesPassed
pair of deucesPair of DeucesPair of DeucesPassed
wheelStraight, Two highStraight, Five highFailed
steel wheelStraight Flush, Two highStraight Flush, Five highFailed
royalRoyal FlushRoyal FlushPassed
king-high straight flushStraight Flush, King highStraight Flush, King highPassed
threes full of kingsFull House, Threes full of KingsFull House, Threes full of KingsPassed
kings full of threesFull House, Kings full of ThreesFull House, Kings full of ThreesPassed

SHA-256 / 123006d946e78ed7a355e64520213393681931044935e1df9c52d9546cbcbff2

HELD IN THE MEMBER ARCHIVE

The verified repair and its recorded checks are member-only.

This mechanism has 8 recorded checks per implementation. The open-access tier publishes the failure and the unsuccessful fix; the repaired source that passes every check, and the observations that prove it, are available to members.

Every case sharing this mechanism uses the same contract and the same repair, so this one record is held back for all of them.

Member access is invitation-based. Sign in with your invited account to inspect the repair.

Sign in to the archive ↗

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:09.671738+00:00.

Case digest / 6020ea65191fbf3050b06402d4ff8420fb6a2b4af8e565e526daa03a1b725dda