FA-83411 / Card game rule engines / Open access
Player naturals are paid even money · case 01
A natural on a 10-unit bet pays 10 instead of 15.
ROOT CAUSE
The natural branch returns the bet.
VERIFIED REPAIR
Pay 3:2 on the original bet.
Unsuccessful approach: Paying 6:5 still short-pays under the 3:2 contract.
Case contract
Input [player_cards, dealer_cards, bet, doubled, from_split]. A natural is a two-card 21 not from a split. Player bust loses the stake (2*bet if doubled) first; both naturals push; player natural pays 3:2 on the bet; dealer natural takes only the original bet; dealer bust pays the stake; otherwise compare totals, equal totals push. Return net units.
Why this case matters
Card-game engines, scoring apps and online tables apply this rule automatically on every hand.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
p, d, bet, doubled, split = x
def total(h):
t = 0
a = 0
for c in h:
if c[0] == 'A':
a += 1
t += 1
elif c[0] in 'TJQK':
t += 10
else:
t += int(c[0])
if a and t + 10 <= 21:
t += 10
return t
stake = bet * 2 if doubled else bet
pt = total(p)
dt = total(d)
pn = pt == 21 and len(p) == 2 and not split
dn = dt == 21 and len(d) == 2
if pt > 21:
return -stake
if pn and dn:
return 0
if pn:
return bet
if dn:
return -bet
if dt > 21:
return stake
if pt > dt:
return stake
if pt < dt:
return -stake
return 0
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[['7D', '8C'], ['JC', '7S', 'QD'], 4, False, True], 4], [[['KH', '5D'], ['AD', 'JD'], 4, True, False], -4], [[['9H', '2H', '2D'], ['KC', '3C'], 10, False, False], 0], [[['7S', '6D'], ['4H', 'AC'], 20, False, False], -20], [[['6D', 'JC'], ['9H', '6C'], 4, True, False], 8], [[['7H', 'JS'], ['8S', '2D'], 20, True, False], 40], [[['KS', 'AC'], ['7C', 'QD'], 4, False, False], 6], [[['AS', 'KH'], ['9C', '8D'], 10, False, False], 15]], [[[['JD', 'QC'], ['JC', '2D'], 20, False, False], 20], [[['3C', 'TH'], ['AC', '8C'], 4, False, True], -4], [[['9C', '2D', '5D', '8D'], ['6H', 'KH'], 20, False, False], -20], [[['2D', '6S'], ['6H', 'TC'], 4, False, False], -4], [[['4H', '7S', '2C'], ['JC', '4S'], 20, False, False], -20], [[['9C', '8S'], ['9S', '5H'], 4, False, False], 4], [[['AS', 'QH'], ['2C', '9D'], 10, True, False], 15], [[['AS', 'QH'], ['2C', '9D'], 10, True, False], 15]], [[[['QS', 'QD', '5S'], ['8D', 'QH'], 4, False, False], -4], [[['4D', 'KS'], ['9D', 'JH', '9C'], 20, False, True], 20], [[['5H', '4D'], ['QH', '6D'], 2, False, False], -2], [[['5D', 'TC', '2C', '5S'], ['KD', 'QD'], 10, False, False], -10], [[['TH', '9S', '2H', '3H'], ['AS', 'QD'], 2, False, False], -2], [[['2D', '7C'], ['AC', 'TC'], 2, True, False], -2], [[['KS', 'AC'], ['7C', 'QD'], 4, False, False], 6], [[['AS', 'KH'], ['9C', '8D'], 10, False, False], 15]], [[[['3D', '3S', '3C', 'JC'], ['TC', '9D'], 20, False, False], 0], [[['QS', '5S'], ['7S', '9C', '9S'], 2, False, True], 2], [[['4C', 'KH'], ['7H', 'TS'], 10, True, False], -20], [[['KH', '4D'], ['QD', '7S'], 2, False, False], -2], [[['TH', '3S', '5C', '8D'], ['8S', '6S'], 4, False, False], -4], [[['JC', '7S'], ['9D', 'JH', '6C'], 20, False, False], 20], [[['JD', 'AD'], ['7C', 'AS', 'QD'], 10, False, False], 15], [[['JD', 'AD'], ['7C', 'AS', 'QD'], 10, False, False], 15]], [[[['6D', '7C'], ['JD', '8S'], 2, True, False], -4], [[['7H', 'QH'], ['7S', '4C'], 10, False, False], 10], [[['AC', '7D'], ['4D', '4C'], 20, False, False], 20], [[['AS', '3C'], ['QD', '9C'], 4, False, False], -4], [[['KS', '8H', 'JD'], ['TS', 'AS'], 4, False, True], -4], [[['TD', 'QS', 'TH'], ['8H', 'TS'], 20, False, False], -20], [[['KS', 'AC'], ['7C', 'QD'], 4, False, False], 6], [[['AS', 'KH'], ['9C', '8D'], 10, False, False], 15]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
check("settlement case %d" % i, solve(args), 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 |
|---|---|---|---|
| settlement case 0 | 4 | 4 | Passed |
| settlement case 1 | -4 | -4 | Passed |
| settlement case 2 | 0 | 0 | Passed |
| settlement case 3 | -20 | -20 | Passed |
| settlement case 4 | 8 | 8 | Passed |
| settlement case 5 | 40 | 40 | Passed |
| settlement case 6 | 4 | 6 | Failed |
| settlement case 7 | 10 | 15 | Failed |
SHA-256 / 113a3a18f14663f827d91bc867883a679cc98a47b4fb6f4f2ca42e2e55c3413e
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
p, d, bet, doubled, split = x
def total(h):
t = 0
a = 0
for c in h:
if c[0] == 'A':
a += 1
t += 1
elif c[0] in 'TJQK':
t += 10
else:
t += int(c[0])
if a and t + 10 <= 21:
t += 10
return t
stake = bet * 2 if doubled else bet
pt = total(p)
dt = total(d)
pn = pt == 21 and len(p) == 2 and not split
dn = dt == 21 and len(d) == 2
if pt > 21:
return -stake
if pn and dn:
return 0
if pn:
return bet * 6 // 5
if dn:
return -bet
if dt > 21:
return stake
if pt > dt:
return stake
if pt < dt:
return -stake
return 0
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[['7D', '8C'], ['JC', '7S', 'QD'], 4, False, True], 4], [[['KH', '5D'], ['AD', 'JD'], 4, True, False], -4], [[['9H', '2H', '2D'], ['KC', '3C'], 10, False, False], 0], [[['7S', '6D'], ['4H', 'AC'], 20, False, False], -20], [[['6D', 'JC'], ['9H', '6C'], 4, True, False], 8], [[['7H', 'JS'], ['8S', '2D'], 20, True, False], 40], [[['KS', 'AC'], ['7C', 'QD'], 4, False, False], 6], [[['AS', 'KH'], ['9C', '8D'], 10, False, False], 15]], [[[['JD', 'QC'], ['JC', '2D'], 20, False, False], 20], [[['3C', 'TH'], ['AC', '8C'], 4, False, True], -4], [[['9C', '2D', '5D', '8D'], ['6H', 'KH'], 20, False, False], -20], [[['2D', '6S'], ['6H', 'TC'], 4, False, False], -4], [[['4H', '7S', '2C'], ['JC', '4S'], 20, False, False], -20], [[['9C', '8S'], ['9S', '5H'], 4, False, False], 4], [[['AS', 'QH'], ['2C', '9D'], 10, True, False], 15], [[['AS', 'QH'], ['2C', '9D'], 10, True, False], 15]], [[[['QS', 'QD', '5S'], ['8D', 'QH'], 4, False, False], -4], [[['4D', 'KS'], ['9D', 'JH', '9C'], 20, False, True], 20], [[['5H', '4D'], ['QH', '6D'], 2, False, False], -2], [[['5D', 'TC', '2C', '5S'], ['KD', 'QD'], 10, False, False], -10], [[['TH', '9S', '2H', '3H'], ['AS', 'QD'], 2, False, False], -2], [[['2D', '7C'], ['AC', 'TC'], 2, True, False], -2], [[['KS', 'AC'], ['7C', 'QD'], 4, False, False], 6], [[['AS', 'KH'], ['9C', '8D'], 10, False, False], 15]], [[[['3D', '3S', '3C', 'JC'], ['TC', '9D'], 20, False, False], 0], [[['QS', '5S'], ['7S', '9C', '9S'], 2, False, True], 2], [[['4C', 'KH'], ['7H', 'TS'], 10, True, False], -20], [[['KH', '4D'], ['QD', '7S'], 2, False, False], -2], [[['TH', '3S', '5C', '8D'], ['8S', '6S'], 4, False, False], -4], [[['JC', '7S'], ['9D', 'JH', '6C'], 20, False, False], 20], [[['JD', 'AD'], ['7C', 'AS', 'QD'], 10, False, False], 15], [[['JD', 'AD'], ['7C', 'AS', 'QD'], 10, False, False], 15]], [[[['6D', '7C'], ['JD', '8S'], 2, True, False], -4], [[['7H', 'QH'], ['7S', '4C'], 10, False, False], 10], [[['AC', '7D'], ['4D', '4C'], 20, False, False], 20], [[['AS', '3C'], ['QD', '9C'], 4, False, False], -4], [[['KS', '8H', 'JD'], ['TS', 'AS'], 4, False, True], -4], [[['TD', 'QS', 'TH'], ['8H', 'TS'], 20, False, False], -20], [[['KS', 'AC'], ['7C', 'QD'], 4, False, False], 6], [[['AS', 'KH'], ['9C', '8D'], 10, False, False], 15]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
check("settlement case %d" % i, solve(args), 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 |
|---|---|---|---|
| settlement case 0 | 4 | 4 | Passed |
| settlement case 1 | -4 | -4 | Passed |
| settlement case 2 | 0 | 0 | Passed |
| settlement case 3 | -20 | -20 | Passed |
| settlement case 4 | 8 | 8 | Passed |
| settlement case 5 | 40 | 40 | Passed |
| settlement case 6 | 4 | 6 | Failed |
| settlement case 7 | 12 | 15 | Failed |
SHA-256 / b7bad6e9f98903e5453abd19b316fd3ae1e9fbcaa2481b2af8fd31284e3925ed
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
p, d, bet, doubled, split = x
def total(h):
t = 0
a = 0
for c in h:
if c[0] == 'A':
a += 1
t += 1
elif c[0] in 'TJQK':
t += 10
else:
t += int(c[0])
if a and t + 10 <= 21:
t += 10
return t
stake = bet * 2 if doubled else bet
pt = total(p)
dt = total(d)
pn = pt == 21 and len(p) == 2 and not split
dn = dt == 21 and len(d) == 2
if pt > 21:
return -stake
if pn and dn:
return 0
if pn:
return bet * 3 // 2
if dn:
return -bet
if dt > 21:
return stake
if pt > dt:
return stake
if pt < dt:
return -stake
return 0
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[['7D', '8C'], ['JC', '7S', 'QD'], 4, False, True], 4], [[['KH', '5D'], ['AD', 'JD'], 4, True, False], -4], [[['9H', '2H', '2D'], ['KC', '3C'], 10, False, False], 0], [[['7S', '6D'], ['4H', 'AC'], 20, False, False], -20], [[['6D', 'JC'], ['9H', '6C'], 4, True, False], 8], [[['7H', 'JS'], ['8S', '2D'], 20, True, False], 40], [[['KS', 'AC'], ['7C', 'QD'], 4, False, False], 6], [[['AS', 'KH'], ['9C', '8D'], 10, False, False], 15]], [[[['JD', 'QC'], ['JC', '2D'], 20, False, False], 20], [[['3C', 'TH'], ['AC', '8C'], 4, False, True], -4], [[['9C', '2D', '5D', '8D'], ['6H', 'KH'], 20, False, False], -20], [[['2D', '6S'], ['6H', 'TC'], 4, False, False], -4], [[['4H', '7S', '2C'], ['JC', '4S'], 20, False, False], -20], [[['9C', '8S'], ['9S', '5H'], 4, False, False], 4], [[['AS', 'QH'], ['2C', '9D'], 10, True, False], 15], [[['AS', 'QH'], ['2C', '9D'], 10, True, False], 15]], [[[['QS', 'QD', '5S'], ['8D', 'QH'], 4, False, False], -4], [[['4D', 'KS'], ['9D', 'JH', '9C'], 20, False, True], 20], [[['5H', '4D'], ['QH', '6D'], 2, False, False], -2], [[['5D', 'TC', '2C', '5S'], ['KD', 'QD'], 10, False, False], -10], [[['TH', '9S', '2H', '3H'], ['AS', 'QD'], 2, False, False], -2], [[['2D', '7C'], ['AC', 'TC'], 2, True, False], -2], [[['KS', 'AC'], ['7C', 'QD'], 4, False, False], 6], [[['AS', 'KH'], ['9C', '8D'], 10, False, False], 15]], [[[['3D', '3S', '3C', 'JC'], ['TC', '9D'], 20, False, False], 0], [[['QS', '5S'], ['7S', '9C', '9S'], 2, False, True], 2], [[['4C', 'KH'], ['7H', 'TS'], 10, True, False], -20], [[['KH', '4D'], ['QD', '7S'], 2, False, False], -2], [[['TH', '3S', '5C', '8D'], ['8S', '6S'], 4, False, False], -4], [[['JC', '7S'], ['9D', 'JH', '6C'], 20, False, False], 20], [[['JD', 'AD'], ['7C', 'AS', 'QD'], 10, False, False], 15], [[['JD', 'AD'], ['7C', 'AS', 'QD'], 10, False, False], 15]], [[[['6D', '7C'], ['JD', '8S'], 2, True, False], -4], [[['7H', 'QH'], ['7S', '4C'], 10, False, False], 10], [[['AC', '7D'], ['4D', '4C'], 20, False, False], 20], [[['AS', '3C'], ['QD', '9C'], 4, False, False], -4], [[['KS', '8H', 'JD'], ['TS', 'AS'], 4, False, True], -4], [[['TD', 'QS', 'TH'], ['8H', 'TS'], 20, False, False], -20], [[['KS', 'AC'], ['7C', 'QD'], 4, False, False], 6], [[['AS', 'KH'], ['9C', '8D'], 10, False, False], 15]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
check("settlement case %d" % i, solve(args), 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 |
|---|---|---|---|
| settlement case 0 | 4 | 4 | Passed |
| settlement case 1 | -4 | -4 | Passed |
| settlement case 2 | 0 | 0 | Passed |
| settlement case 3 | -20 | -20 | Passed |
| settlement case 4 | 8 | 8 | Passed |
| settlement case 5 | 40 | 40 | Passed |
| settlement case 6 | 6 | 6 | Passed |
| settlement case 7 | 15 | 15 | Passed |
SHA-256 / ae8c3be72c22a27d9c1d420e679f104a7685331bc80fb55a5e7c6e39046eacb9
Verification & scope
A bounded toy rule contract stated explicitly in the contract field; cards are two-character codes (rank, suit). Not a complete implementation of any published rulebook or casino table rules. 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:21.309535+00:00.
Case digest / b71e7b9a8f7da3044da731c195e8f42340730596df928c29158b4174ab4f891f