FA-82326 / Poker hand evaluation / Open access
Badugi search settles for one-card subsets · case 01
Every hand evaluates as a one-card hand, so comparisons depend only on the lowest card.
ROOT CAUSE
Subset sizes are searched from smallest to largest and the first hit is returned.
VERIFIED REPAIR
Search from four cards down to one and return the first size that has a valid subset.
Unsuccessful approach: Starting from three never recognizes a complete four-card badugi.
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(1,5):
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),
('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),
('lower badugi wins', [['Ac', '2d', '3h', '8s'], ['Ac', '2d', '4h', '7s']], -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),
('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)],
[('paired rank different suits', [['Ac', 'Ad', '3h', '4s'], ['5c', '6d', '7h', 'Ks']], -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)],
[('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),
('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 | 0 | 1 | Failed |
| paired rank different suits | 1 | -1 | Failed |
| lower badugi wins | 0 | -1 | Failed |
| equal badugis | 0 | 0 | Passed |
| best three-card subset | 1 | 1 | Passed |
| two-card hands | 1 | -1 | Failed |
| one-card hands | 1 | 1 | Passed |
| suit pair plus rank pair | 1 | 1 | Passed |
SHA-256 / 8758a076b36a1622f64ca3130c30af547c1fc324fbb7ff38905d704b3da35968
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(3,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),
('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),
('lower badugi wins', [['Ac', '2d', '3h', '8s'], ['Ac', '2d', '4h', '7s']], -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),
('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)],
[('paired rank different suits', [['Ac', 'Ad', '3h', '4s'], ['5c', '6d', '7h', 'Ks']], -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)],
[('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),
('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 | Failed |
| lower badugi wins | 1 | -1 | Failed |
| equal badugis | 0 | 0 | Passed |
| best three-card subset | 1 | 1 | Passed |
| two-card hands | -1 | -1 | Passed |
| one-card hands | 1 | 1 | Passed |
| suit pair plus rank pair | 1 | 1 | Passed |
SHA-256 / 43d19bbe2ac223e776c996c4360a7a8273fbd4936e4e845b40ab31fc674a7374
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),
('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),
('lower badugi wins', [['Ac', '2d', '3h', '8s'], ['Ac', '2d', '4h', '7s']], -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),
('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)],
[('paired rank different suits', [['Ac', 'Ad', '3h', '4s'], ['5c', '6d', '7h', 'Ks']], -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)],
[('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),
('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 |
| one-card hands | 1 | 1 | Passed |
| suit pair plus rank pair | 1 | 1 | Passed |
SHA-256 / 34587914b1571de09826b47869050b2a58baf9e1dac9b6c433268283ae3443e1
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:11.120119+00:00.
Case digest / dda3961aa0093f3d11beb1cb9b7ce8cd61c785d5205c27060e0da17e89cca9cc