FA-82321 / Poker hand evaluation / Open access
Higher badugi wins the pot · case 01
A-2-3-8 beats A-2-4-7 although the eight-high badugi is the worse hand.
ROOT CAUSE
Equal-size hands are compared with high-hand direction.
VERIFIED REPAIR
Among equal sizes the lexicographically lower descending rank list wins.
Unsuccessful approach: Comparing only the lowest card ignores the top card, which matters most.
Case contract
Input: [hand_a, hand_b], four distinct cards each. A hand's value is its best subset with all ranks distinct and all suits distinct: more cards beat fewer; among equal sizes the lower subset (compared from its highest card down, ace low = 1) wins. Return 1, -1 or 0.
Why this case matters
Badugi uses a unique subset-based evaluator that is easy to get subtly wrong.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import itertools
N = 1
observations = []
def solve(x):
R='A23456789TJQK'
def best(h):
for n in range(4,0,-1):
cands=[]
for sub in itertools.combinations(h,n):
if len({c[0] for c in sub})==n and len({c[1] for c in sub})==n:
cands.append(sorted((R.index(c[0])+1 for c in sub), reverse=True))
if cands: return (n, min(cands))
a,b=best(x[0]),best(x[1])
if a[0]!=b[0]: return 1 if a[0]>b[0] else -1
if a[1]==b[1]: return 0
return 1 if a[1]>b[1] else -1
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('four-card badugi vs three', [['Ac', '2d', '3h', '4s'], ['Ac', '2c', '3h', '4s']], 1),
('paired rank different suits', [['Ac', 'Ad', '3h', '4s'], ['5c', '6d', '7h', 'Ks']], -1),
('lower badugi wins', [['Ac', '2d', '3h', '8s'], ['Ac', '2d', '4h', '7s']], -1),
('equal badugis', [['Ac', '2d', '3h', '4s'], ['Ad', '2c', '3s', '4h']], 0),
('best three-card subset', [['Kc', '2c', '3h', '4s'], ['5c', '6c', '7h', '8s']], 1),
('two-card hands', [['Ac', '2c', '3c', 'Kd'], ['4h', '5h', '6h', '7s']], -1),
('king high badugi vs three', [['Kc', 'Qd', 'Jh', 'Ts'], ['Ac', '2c', '3d', '4h']], 1),
('lowest card trap', [['Ac', '5d', '6h', '7s'], ['2c', '3d', '4h', '8s']], 1)],
[('four-card badugi vs three', [['Ac', '2d', '3h', '4s'], ['Ac', '2c', '3h', '4s']], 1),
('lower badugi wins', [['Ac', '2d', '3h', '8s'], ['Ac', '2d', '4h', '7s']], -1),
('best three-card subset', [['Kc', '2c', '3h', '4s'], ['5c', '6c', '7h', '8s']], 1),
('two-card hands', [['Ac', '2c', '3c', 'Kd'], ['4h', '5h', '6h', '7s']], -1),
('king high badugi vs three', [['Kc', 'Qd', 'Jh', 'Ts'], ['Ac', '2c', '3d', '4h']], 1),
('lowest card trap', [['Ac', '5d', '6h', '7s'], ['2c', '3d', '4h', '8s']], 1),
('one-card hands', [['Ac', '2c', '3c', '4c'], ['5d', '6d', '7d', '8d']], 1),
('suit pair plus rank pair', [['2c', '2d', '5c', '9h'], ['3c', '4c', '6d', 'Th']], 1)],
[('four-card badugi vs three', [['Ac', '2d', '3h', '4s'], ['Ac', '2c', '3h', '4s']], 1),
('paired rank different suits', [['Ac', 'Ad', '3h', '4s'], ['5c', '6d', '7h', 'Ks']], -1),
('equal badugis', [['Ac', '2d', '3h', '4s'], ['Ad', '2c', '3s', '4h']], 0),
('two-card hands', [['Ac', '2c', '3c', 'Kd'], ['4h', '5h', '6h', '7s']], -1),
('king high badugi vs three', [['Kc', 'Qd', 'Jh', 'Ts'], ['Ac', '2c', '3d', '4h']], 1),
('lowest card trap', [['Ac', '5d', '6h', '7s'], ['2c', '3d', '4h', '8s']], 1),
('one-card hands', [['Ac', '2c', '3c', '4c'], ['5d', '6d', '7d', '8d']], 1),
('suit pair plus rank pair', [['2c', '2d', '5c', '9h'], ['3c', '4c', '6d', 'Th']], 1)],
[('four-card badugi vs three', [['Ac', '2d', '3h', '4s'], ['Ac', '2c', '3h', '4s']], 1),
('paired rank different suits', [['Ac', 'Ad', '3h', '4s'], ['5c', '6d', '7h', 'Ks']], -1),
('equal badugis', [['Ac', '2d', '3h', '4s'], ['Ad', '2c', '3s', '4h']], 0),
('two-card hands', [['Ac', '2c', '3c', 'Kd'], ['4h', '5h', '6h', '7s']], -1),
('king high badugi vs three', [['Kc', 'Qd', 'Jh', 'Ts'], ['Ac', '2c', '3d', '4h']], 1),
('lowest card trap', [['Ac', '5d', '6h', '7s'], ['2c', '3d', '4h', '8s']], 1),
('one-card hands', [['Ac', '2c', '3c', '4c'], ['5d', '6d', '7d', '8d']], 1),
('suit pair plus rank pair', [['2c', '2d', '5c', '9h'], ['3c', '4c', '6d', 'Th']], 1)],
[('lower badugi wins', [['Ac', '2d', '3h', '8s'], ['Ac', '2d', '4h', '7s']], -1),
('equal badugis', [['Ac', '2d', '3h', '4s'], ['Ad', '2c', '3s', '4h']], 0),
('best three-card subset', [['Kc', '2c', '3h', '4s'], ['5c', '6c', '7h', '8s']], 1),
('two-card hands', [['Ac', '2c', '3c', 'Kd'], ['4h', '5h', '6h', '7s']], -1),
('king high badugi vs three', [['Kc', 'Qd', 'Jh', 'Ts'], ['Ac', '2c', '3d', '4h']], 1),
('lowest card trap', [['Ac', '5d', '6h', '7s'], ['2c', '3d', '4h', '8s']], 1),
('one-card hands', [['Ac', '2c', '3c', '4c'], ['5d', '6d', '7d', '8d']], 1),
('suit pair plus rank pair', [['2c', '2d', '5c', '9h'], ['3c', '4c', '6d', 'Th']], 1)]]
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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| four-card badugi vs three | 1 | 1 | Passed |
| paired rank different suits | -1 | -1 | Passed |
| lower badugi wins | 1 | -1 | Failed |
| equal badugis | 0 | 0 | Passed |
| best three-card subset | -1 | 1 | Failed |
| two-card hands | 1 | -1 | Failed |
| king high badugi vs three | 1 | 1 | Passed |
| lowest card trap | -1 | 1 | Failed |
SHA-256 / 294d9d38641feb8149057718d5fa5aeb5b2b29160414baadb5a0f7af834c4806
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import itertools
N = 1
observations = []
def solve(x):
R='A23456789TJQK'
def best(h):
for n in range(4,0,-1):
cands=[]
for sub in itertools.combinations(h,n):
if len({c[0] for c in sub})==n and len({c[1] for c in sub})==n:
cands.append(sorted((R.index(c[0])+1 for c in sub), reverse=True))
if cands: return (n, min(cands))
a,b=best(x[0]),best(x[1])
if a[0]!=b[0]: return 1 if a[0]>b[0] else -1
if a[1]==b[1]: return 0
return 1 if a[1][-1]<b[1][-1] else -1
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('four-card badugi vs three', [['Ac', '2d', '3h', '4s'], ['Ac', '2c', '3h', '4s']], 1),
('paired rank different suits', [['Ac', 'Ad', '3h', '4s'], ['5c', '6d', '7h', 'Ks']], -1),
('lower badugi wins', [['Ac', '2d', '3h', '8s'], ['Ac', '2d', '4h', '7s']], -1),
('equal badugis', [['Ac', '2d', '3h', '4s'], ['Ad', '2c', '3s', '4h']], 0),
('best three-card subset', [['Kc', '2c', '3h', '4s'], ['5c', '6c', '7h', '8s']], 1),
('two-card hands', [['Ac', '2c', '3c', 'Kd'], ['4h', '5h', '6h', '7s']], -1),
('king high badugi vs three', [['Kc', 'Qd', 'Jh', 'Ts'], ['Ac', '2c', '3d', '4h']], 1),
('lowest card trap', [['Ac', '5d', '6h', '7s'], ['2c', '3d', '4h', '8s']], 1)],
[('four-card badugi vs three', [['Ac', '2d', '3h', '4s'], ['Ac', '2c', '3h', '4s']], 1),
('lower badugi wins', [['Ac', '2d', '3h', '8s'], ['Ac', '2d', '4h', '7s']], -1),
('best three-card subset', [['Kc', '2c', '3h', '4s'], ['5c', '6c', '7h', '8s']], 1),
('two-card hands', [['Ac', '2c', '3c', 'Kd'], ['4h', '5h', '6h', '7s']], -1),
('king high badugi vs three', [['Kc', 'Qd', 'Jh', 'Ts'], ['Ac', '2c', '3d', '4h']], 1),
('lowest card trap', [['Ac', '5d', '6h', '7s'], ['2c', '3d', '4h', '8s']], 1),
('one-card hands', [['Ac', '2c', '3c', '4c'], ['5d', '6d', '7d', '8d']], 1),
('suit pair plus rank pair', [['2c', '2d', '5c', '9h'], ['3c', '4c', '6d', 'Th']], 1)],
[('four-card badugi vs three', [['Ac', '2d', '3h', '4s'], ['Ac', '2c', '3h', '4s']], 1),
('paired rank different suits', [['Ac', 'Ad', '3h', '4s'], ['5c', '6d', '7h', 'Ks']], -1),
('equal badugis', [['Ac', '2d', '3h', '4s'], ['Ad', '2c', '3s', '4h']], 0),
('two-card hands', [['Ac', '2c', '3c', 'Kd'], ['4h', '5h', '6h', '7s']], -1),
('king high badugi vs three', [['Kc', 'Qd', 'Jh', 'Ts'], ['Ac', '2c', '3d', '4h']], 1),
('lowest card trap', [['Ac', '5d', '6h', '7s'], ['2c', '3d', '4h', '8s']], 1),
('one-card hands', [['Ac', '2c', '3c', '4c'], ['5d', '6d', '7d', '8d']], 1),
('suit pair plus rank pair', [['2c', '2d', '5c', '9h'], ['3c', '4c', '6d', 'Th']], 1)],
[('four-card badugi vs three', [['Ac', '2d', '3h', '4s'], ['Ac', '2c', '3h', '4s']], 1),
('paired rank different suits', [['Ac', 'Ad', '3h', '4s'], ['5c', '6d', '7h', 'Ks']], -1),
('equal badugis', [['Ac', '2d', '3h', '4s'], ['Ad', '2c', '3s', '4h']], 0),
('two-card hands', [['Ac', '2c', '3c', 'Kd'], ['4h', '5h', '6h', '7s']], -1),
('king high badugi vs three', [['Kc', 'Qd', 'Jh', 'Ts'], ['Ac', '2c', '3d', '4h']], 1),
('lowest card trap', [['Ac', '5d', '6h', '7s'], ['2c', '3d', '4h', '8s']], 1),
('one-card hands', [['Ac', '2c', '3c', '4c'], ['5d', '6d', '7d', '8d']], 1),
('suit pair plus rank pair', [['2c', '2d', '5c', '9h'], ['3c', '4c', '6d', 'Th']], 1)],
[('lower badugi wins', [['Ac', '2d', '3h', '8s'], ['Ac', '2d', '4h', '7s']], -1),
('equal badugis', [['Ac', '2d', '3h', '4s'], ['Ad', '2c', '3s', '4h']], 0),
('best three-card subset', [['Kc', '2c', '3h', '4s'], ['5c', '6c', '7h', '8s']], 1),
('two-card hands', [['Ac', '2c', '3c', 'Kd'], ['4h', '5h', '6h', '7s']], -1),
('king high badugi vs three', [['Kc', 'Qd', 'Jh', 'Ts'], ['Ac', '2c', '3d', '4h']], 1),
('lowest card trap', [['Ac', '5d', '6h', '7s'], ['2c', '3d', '4h', '8s']], 1),
('one-card hands', [['Ac', '2c', '3c', '4c'], ['5d', '6d', '7d', '8d']], 1),
('suit pair plus rank pair', [['2c', '2d', '5c', '9h'], ['3c', '4c', '6d', 'Th']], 1)]]
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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| four-card badugi vs three | 1 | 1 | Passed |
| paired rank different suits | -1 | -1 | Passed |
| lower badugi wins | -1 | -1 | Passed |
| equal badugis | 0 | 0 | Passed |
| best three-card subset | 1 | 1 | Passed |
| two-card hands | 1 | -1 | Failed |
| king high badugi vs three | 1 | 1 | Passed |
| lowest card trap | 1 | 1 | Passed |
SHA-256 / e187364847ee41d12742c4c66494e11f5f5a6b259b58e039b867077ba28e80df
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
import itertools
N = 1
observations = []
def solve(x):
R='A23456789TJQK'
def best(h):
for n in range(4,0,-1):
cands=[]
for sub in itertools.combinations(h,n):
if len({c[0] for c in sub})==n and len({c[1] for c in sub})==n:
cands.append(sorted((R.index(c[0])+1 for c in sub), reverse=True))
if cands: return (n, min(cands))
a,b=best(x[0]),best(x[1])
if a[0]!=b[0]: return 1 if a[0]>b[0] else -1
if a[1]==b[1]: return 0
return 1 if a[1]<b[1] else -1
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('four-card badugi vs three', [['Ac', '2d', '3h', '4s'], ['Ac', '2c', '3h', '4s']], 1),
('paired rank different suits', [['Ac', 'Ad', '3h', '4s'], ['5c', '6d', '7h', 'Ks']], -1),
('lower badugi wins', [['Ac', '2d', '3h', '8s'], ['Ac', '2d', '4h', '7s']], -1),
('equal badugis', [['Ac', '2d', '3h', '4s'], ['Ad', '2c', '3s', '4h']], 0),
('best three-card subset', [['Kc', '2c', '3h', '4s'], ['5c', '6c', '7h', '8s']], 1),
('two-card hands', [['Ac', '2c', '3c', 'Kd'], ['4h', '5h', '6h', '7s']], -1),
('king high badugi vs three', [['Kc', 'Qd', 'Jh', 'Ts'], ['Ac', '2c', '3d', '4h']], 1),
('lowest card trap', [['Ac', '5d', '6h', '7s'], ['2c', '3d', '4h', '8s']], 1)],
[('four-card badugi vs three', [['Ac', '2d', '3h', '4s'], ['Ac', '2c', '3h', '4s']], 1),
('lower badugi wins', [['Ac', '2d', '3h', '8s'], ['Ac', '2d', '4h', '7s']], -1),
('best three-card subset', [['Kc', '2c', '3h', '4s'], ['5c', '6c', '7h', '8s']], 1),
('two-card hands', [['Ac', '2c', '3c', 'Kd'], ['4h', '5h', '6h', '7s']], -1),
('king high badugi vs three', [['Kc', 'Qd', 'Jh', 'Ts'], ['Ac', '2c', '3d', '4h']], 1),
('lowest card trap', [['Ac', '5d', '6h', '7s'], ['2c', '3d', '4h', '8s']], 1),
('one-card hands', [['Ac', '2c', '3c', '4c'], ['5d', '6d', '7d', '8d']], 1),
('suit pair plus rank pair', [['2c', '2d', '5c', '9h'], ['3c', '4c', '6d', 'Th']], 1)],
[('four-card badugi vs three', [['Ac', '2d', '3h', '4s'], ['Ac', '2c', '3h', '4s']], 1),
('paired rank different suits', [['Ac', 'Ad', '3h', '4s'], ['5c', '6d', '7h', 'Ks']], -1),
('equal badugis', [['Ac', '2d', '3h', '4s'], ['Ad', '2c', '3s', '4h']], 0),
('two-card hands', [['Ac', '2c', '3c', 'Kd'], ['4h', '5h', '6h', '7s']], -1),
('king high badugi vs three', [['Kc', 'Qd', 'Jh', 'Ts'], ['Ac', '2c', '3d', '4h']], 1),
('lowest card trap', [['Ac', '5d', '6h', '7s'], ['2c', '3d', '4h', '8s']], 1),
('one-card hands', [['Ac', '2c', '3c', '4c'], ['5d', '6d', '7d', '8d']], 1),
('suit pair plus rank pair', [['2c', '2d', '5c', '9h'], ['3c', '4c', '6d', 'Th']], 1)],
[('four-card badugi vs three', [['Ac', '2d', '3h', '4s'], ['Ac', '2c', '3h', '4s']], 1),
('paired rank different suits', [['Ac', 'Ad', '3h', '4s'], ['5c', '6d', '7h', 'Ks']], -1),
('equal badugis', [['Ac', '2d', '3h', '4s'], ['Ad', '2c', '3s', '4h']], 0),
('two-card hands', [['Ac', '2c', '3c', 'Kd'], ['4h', '5h', '6h', '7s']], -1),
('king high badugi vs three', [['Kc', 'Qd', 'Jh', 'Ts'], ['Ac', '2c', '3d', '4h']], 1),
('lowest card trap', [['Ac', '5d', '6h', '7s'], ['2c', '3d', '4h', '8s']], 1),
('one-card hands', [['Ac', '2c', '3c', '4c'], ['5d', '6d', '7d', '8d']], 1),
('suit pair plus rank pair', [['2c', '2d', '5c', '9h'], ['3c', '4c', '6d', 'Th']], 1)],
[('lower badugi wins', [['Ac', '2d', '3h', '8s'], ['Ac', '2d', '4h', '7s']], -1),
('equal badugis', [['Ac', '2d', '3h', '4s'], ['Ad', '2c', '3s', '4h']], 0),
('best three-card subset', [['Kc', '2c', '3h', '4s'], ['5c', '6c', '7h', '8s']], 1),
('two-card hands', [['Ac', '2c', '3c', 'Kd'], ['4h', '5h', '6h', '7s']], -1),
('king high badugi vs three', [['Kc', 'Qd', 'Jh', 'Ts'], ['Ac', '2c', '3d', '4h']], 1),
('lowest card trap', [['Ac', '5d', '6h', '7s'], ['2c', '3d', '4h', '8s']], 1),
('one-card hands', [['Ac', '2c', '3c', '4c'], ['5d', '6d', '7d', '8d']], 1),
('suit pair plus rank pair', [['2c', '2d', '5c', '9h'], ['3c', '4c', '6d', 'Th']], 1)]]
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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| four-card badugi vs three | 1 | 1 | Passed |
| paired rank different suits | -1 | -1 | Passed |
| lower badugi wins | -1 | -1 | Passed |
| equal badugis | 0 | 0 | Passed |
| best three-card subset | 1 | 1 | Passed |
| two-card hands | -1 | -1 | Passed |
| king high badugi vs three | 1 | 1 | Passed |
| lowest card trap | 1 | 1 | Passed |
SHA-256 / 04dfbaeebf5bf0eb9f8e401e6d008f0760b3d78b9e573e7d89358c1e3dc2148b
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.953122+00:00.
Case digest / 5de0bc2ddab76d40fc251c68d302ec2af8775203596730910f0de6e0e76322ab