FA-82311 / Poker hand evaluation / Open access
Paired badugi counted as four cards · case 01
A-A-3-4 in four suits beats a genuine king-high badugi.
ROOT CAUSE
The subset test only requires distinct suits, so a paired rank survives.
VERIFIED REPAIR
Require distinct ranks and distinct suits.
Unsuccessful approach: Allowing one repeated rank still keeps the paired four-card subset.
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[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),
('paired rank different suits', [['Ac', 'Ad', '3h', '4s'], ['5c', '6d', '7h', 'Ks']], -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),
('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),
('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),
('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)],
[('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)]]
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 | 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 / 83f9dc4b0458a6472a6c4082445c967606a5a92f00c7e58f5a47eff157ac0b16
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-1 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),
('paired rank different suits', [['Ac', 'Ad', '3h', '4s'], ['5c', '6d', '7h', 'Ks']], -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),
('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),
('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),
('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)],
[('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)]]
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 | 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 / 2ad3ef22f1aa68361cfbb0564665549026b121b5720784cd1ef22e2ecac076c9
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),
('paired rank different suits', [['Ac', 'Ad', '3h', '4s'], ['5c', '6d', '7h', 'Ks']], -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),
('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),
('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),
('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)],
[('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)]]
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 / cb2261beb75fc7a782a361f2e7db68aa4d721642b2ffc42750a9ec36b32eb4a8
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.819916+00:00.
Case digest / c2e1057c2fa7bf4c1c1c876ba69980431f9631d67f1549779185c0ab68b68a1c