FA-83686 / Card game rule engines / Open access
Banker decisions use the player new total instead of the third card · case 01
The tableau is consulted with the wrong number.
ROOT CAUSE
third is set to the player total after drawing.
VERIFIED REPAIR
Use the value of the third card itself.
Unsuccessful approach: Using the player two-card total from before the draw is still not the third card value.
Case contract
Input [player_cards, banker_cards, next_shoe_cards]. Values A=1, 2-9 pip, T/J/Q/K 0; totals mod 10. A natural 8/9 on either side stops the coup. Player draws on 0-5. If player stood, banker draws on 0-5; otherwise banker draws on 0-2, on 3 unless the player third card is 8, on 4 vs 2-7, on 5 vs 4-7, on 6 vs 6-7. Return [player_total, banker_total, winner, cards_drawn].
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, b, shoe = x
def val(c):
r = c[0]
if r == 'A':
return 1
if r in 'TJQK':
return 0
return int(r)
def tot(h):
return sum(val(c) for c in h) % 10
p = list(p)
b = list(b)
k = 0
pt, bt = tot(p), tot(b)
if pt < 8 and bt < 8:
third = None
if pt <= 5:
p.append(shoe[k])
k += 1
third = tot(p)
if third is None:
draw = bt <= 5
elif bt <= 2:
draw = True
elif bt == 3:
draw = third != 8
elif bt == 4:
draw = 2 <= third <= 7
elif bt == 5:
draw = 4 <= third <= 7
elif bt == 6:
draw = 6 <= third <= 7
else:
draw = False
if draw:
b.append(shoe[k])
k += 1
pt, bt = tot(p), tot(b)
winner = 'player' if pt > bt else 'banker' if bt > pt else 'tie'
return [pt, bt, winner, k]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[['6C', '8D'], ['3H', 'TS'], ['9D', 'QS']], [3, 3, 'tie', 2]], [[['JD', '4H'], ['QC', '8D'], ['TS', '7H']], [4, 8, 'banker', 0]], [[['2H', '8C'], ['7C', 'JS'], ['2C', '7D']], [2, 7, 'banker', 1]], [[['2C', '9D'], ['7C', 'JH'], ['2S', '8H']], [3, 7, 'banker', 1]], [[['5C', '3C'], ['TC', '5H'], ['AC', 'TH']], [8, 5, 'player', 0]], [[['7C', '2C'], ['6H', '3S'], ['AH', '5S']], [9, 9, 'tie', 0]], [[['3H', 'TD'], ['QS', '5C'], ['5D', 'AD']], [8, 6, 'player', 2]], [[['4S', '9H'], ['TS', '4H'], ['KH', '9S']], [3, 4, 'banker', 1]]], [[[['6S', 'QD'], ['6C', '7D'], ['7S', '4D']], [6, 0, 'player', 1]], [[['7H', '3D'], ['JS', 'JH'], ['6H', 'AC']], [6, 1, 'player', 2]], [[['2S', '2C'], ['AS', '7D'], ['2H', '9H']], [4, 8, 'banker', 0]], [[['KC', '6H'], ['9D', 'QS'], ['2C', 'KD']], [6, 9, 'banker', 0]], [[['5S', '6C'], ['6S', '3S'], ['KC', 'KH']], [1, 9, 'banker', 0]], [[['9C', '2H'], ['JC', 'JS'], ['TH', 'QC']], [1, 0, 'player', 2]], [[['AH', 'TS'], ['3D', '2D'], ['7C', 'KC']], [8, 5, 'player', 2]], [[['QC', '5S'], ['QS', '5H'], ['8S', 'JC']], [3, 5, 'banker', 1]]], [[[['4C', '5S'], ['6S', '4H'], ['QC', '3C']], [9, 0, 'player', 0]], [[['5H', '2C'], ['TD', '6C'], ['7S', 'KC']], [7, 6, 'player', 0]], [[['2C', '4D'], ['8D', '3H'], ['KS', '6C']], [6, 1, 'player', 1]], [[['6S', 'QD'], ['8H', '9D'], ['3S', 'TD']], [6, 7, 'banker', 0]], [[['3H', 'TD'], ['QS', '5C'], ['5D', 'AD']], [8, 6, 'player', 2]], [[['6S', 'JS'], ['4D', '6D'], ['2C', 'KD']], [6, 2, 'player', 1]], [[['5D', 'JS'], ['9H', '6D'], ['QH', 'QS']], [5, 5, 'tie', 1]], [[['7D', '6C'], ['8C', '8D'], ['6S', '7S']], [9, 3, 'player', 2]]], [[[['8D', 'TH'], ['QS', '9S'], ['3S', '9H']], [8, 9, 'banker', 0]], [[['AS', '5H'], ['5D', '9D'], ['7S', '5S']], [6, 1, 'player', 1]], [[['7C', 'JD'], ['2H', 'KC'], ['JS', 'AS']], [7, 2, 'player', 1]], [[['TH', '8C'], ['2C', '7H'], ['JH', '4D']], [8, 9, 'banker', 0]], [[['TC', '5D'], ['JC', '7S'], ['7C', '4C']], [2, 7, 'banker', 1]], [[['AS', '5H'], ['6C', '8C'], ['7D', '9S']], [6, 1, 'player', 1]], [[['4H', 'AH'], ['8S', '6C'], ['9D', '7S']], [4, 4, 'tie', 1]], [[['2S', '3H'], ['4C', '2D'], ['6C', '5S']], [1, 1, 'tie', 2]]], [[[['5S', 'JS'], ['KH', 'TC'], ['4C', '9S']], [9, 9, 'tie', 2]], [[['9H', '9S'], ['TS', '4S'], ['TD', 'TC']], [8, 4, 'player', 0]], [[['9D', '9S'], ['2S', '6D'], ['6S', '4C']], [8, 8, 'tie', 0]], [[['2S', '9H'], ['7H', 'AS'], ['AH', '5H']], [1, 8, 'banker', 0]], [[['2C', '6H'], ['3D', 'TH'], ['QD', 'KS']], [8, 3, 'player', 0]], [[['2S', '2H'], ['3C', '9D'], ['KH', '6C']], [4, 8, 'banker', 2]], [[['4H', '8C'], ['3D', 'AS'], ['QH', 'QS']], [2, 4, 'banker', 1]], [[['5S', 'TS'], ['8D', '8C'], ['2H', 'QS']], [7, 6, 'player', 1]]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
check("coup 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 |
|---|---|---|---|
| coup case 0 | [3, 3, 'tie', 2] | [3, 3, 'tie', 2] | Passed |
| coup case 1 | [4, 8, 'banker', 0] | [4, 8, 'banker', 0] | Passed |
| coup case 2 | [2, 7, 'banker', 1] | [2, 7, 'banker', 1] | Passed |
| coup case 3 | [3, 7, 'banker', 1] | [3, 7, 'banker', 1] | Passed |
| coup case 4 | [8, 5, 'player', 0] | [8, 5, 'player', 0] | Passed |
| coup case 5 | [9, 9, 'tie', 0] | [9, 9, 'tie', 0] | Passed |
| coup case 6 | [8, 5, 'player', 1] | [8, 6, 'player', 2] | Failed |
| coup case 7 | [3, 3, 'tie', 2] | [3, 4, 'banker', 1] | Failed |
SHA-256 / fd447c73ee8879dca7cac5cdc1ba8587e965ca1c811bd62b6e4cbefa5f2df7a2
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
p, b, shoe = x
def val(c):
r = c[0]
if r == 'A':
return 1
if r in 'TJQK':
return 0
return int(r)
def tot(h):
return sum(val(c) for c in h) % 10
p = list(p)
b = list(b)
k = 0
pt, bt = tot(p), tot(b)
if pt < 8 and bt < 8:
third = None
if pt <= 5:
p.append(shoe[k])
k += 1
third = tot(p[:-1])
if third is None:
draw = bt <= 5
elif bt <= 2:
draw = True
elif bt == 3:
draw = third != 8
elif bt == 4:
draw = 2 <= third <= 7
elif bt == 5:
draw = 4 <= third <= 7
elif bt == 6:
draw = 6 <= third <= 7
else:
draw = False
if draw:
b.append(shoe[k])
k += 1
pt, bt = tot(p), tot(b)
winner = 'player' if pt > bt else 'banker' if bt > pt else 'tie'
return [pt, bt, winner, k]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[['6C', '8D'], ['3H', 'TS'], ['9D', 'QS']], [3, 3, 'tie', 2]], [[['JD', '4H'], ['QC', '8D'], ['TS', '7H']], [4, 8, 'banker', 0]], [[['2H', '8C'], ['7C', 'JS'], ['2C', '7D']], [2, 7, 'banker', 1]], [[['2C', '9D'], ['7C', 'JH'], ['2S', '8H']], [3, 7, 'banker', 1]], [[['5C', '3C'], ['TC', '5H'], ['AC', 'TH']], [8, 5, 'player', 0]], [[['7C', '2C'], ['6H', '3S'], ['AH', '5S']], [9, 9, 'tie', 0]], [[['3H', 'TD'], ['QS', '5C'], ['5D', 'AD']], [8, 6, 'player', 2]], [[['4S', '9H'], ['TS', '4H'], ['KH', '9S']], [3, 4, 'banker', 1]]], [[[['6S', 'QD'], ['6C', '7D'], ['7S', '4D']], [6, 0, 'player', 1]], [[['7H', '3D'], ['JS', 'JH'], ['6H', 'AC']], [6, 1, 'player', 2]], [[['2S', '2C'], ['AS', '7D'], ['2H', '9H']], [4, 8, 'banker', 0]], [[['KC', '6H'], ['9D', 'QS'], ['2C', 'KD']], [6, 9, 'banker', 0]], [[['5S', '6C'], ['6S', '3S'], ['KC', 'KH']], [1, 9, 'banker', 0]], [[['9C', '2H'], ['JC', 'JS'], ['TH', 'QC']], [1, 0, 'player', 2]], [[['AH', 'TS'], ['3D', '2D'], ['7C', 'KC']], [8, 5, 'player', 2]], [[['QC', '5S'], ['QS', '5H'], ['8S', 'JC']], [3, 5, 'banker', 1]]], [[[['4C', '5S'], ['6S', '4H'], ['QC', '3C']], [9, 0, 'player', 0]], [[['5H', '2C'], ['TD', '6C'], ['7S', 'KC']], [7, 6, 'player', 0]], [[['2C', '4D'], ['8D', '3H'], ['KS', '6C']], [6, 1, 'player', 1]], [[['6S', 'QD'], ['8H', '9D'], ['3S', 'TD']], [6, 7, 'banker', 0]], [[['3H', 'TD'], ['QS', '5C'], ['5D', 'AD']], [8, 6, 'player', 2]], [[['6S', 'JS'], ['4D', '6D'], ['2C', 'KD']], [6, 2, 'player', 1]], [[['5D', 'JS'], ['9H', '6D'], ['QH', 'QS']], [5, 5, 'tie', 1]], [[['7D', '6C'], ['8C', '8D'], ['6S', '7S']], [9, 3, 'player', 2]]], [[[['8D', 'TH'], ['QS', '9S'], ['3S', '9H']], [8, 9, 'banker', 0]], [[['AS', '5H'], ['5D', '9D'], ['7S', '5S']], [6, 1, 'player', 1]], [[['7C', 'JD'], ['2H', 'KC'], ['JS', 'AS']], [7, 2, 'player', 1]], [[['TH', '8C'], ['2C', '7H'], ['JH', '4D']], [8, 9, 'banker', 0]], [[['TC', '5D'], ['JC', '7S'], ['7C', '4C']], [2, 7, 'banker', 1]], [[['AS', '5H'], ['6C', '8C'], ['7D', '9S']], [6, 1, 'player', 1]], [[['4H', 'AH'], ['8S', '6C'], ['9D', '7S']], [4, 4, 'tie', 1]], [[['2S', '3H'], ['4C', '2D'], ['6C', '5S']], [1, 1, 'tie', 2]]], [[[['5S', 'JS'], ['KH', 'TC'], ['4C', '9S']], [9, 9, 'tie', 2]], [[['9H', '9S'], ['TS', '4S'], ['TD', 'TC']], [8, 4, 'player', 0]], [[['9D', '9S'], ['2S', '6D'], ['6S', '4C']], [8, 8, 'tie', 0]], [[['2S', '9H'], ['7H', 'AS'], ['AH', '5H']], [1, 8, 'banker', 0]], [[['2C', '6H'], ['3D', 'TH'], ['QD', 'KS']], [8, 3, 'player', 0]], [[['2S', '2H'], ['3C', '9D'], ['KH', '6C']], [4, 8, 'banker', 2]], [[['4H', '8C'], ['3D', 'AS'], ['QH', 'QS']], [2, 4, 'banker', 1]], [[['5S', 'TS'], ['8D', '8C'], ['2H', 'QS']], [7, 6, 'player', 1]]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
check("coup 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 |
|---|---|---|---|
| coup case 0 | [3, 3, 'tie', 2] | [3, 3, 'tie', 2] | Passed |
| coup case 1 | [4, 8, 'banker', 0] | [4, 8, 'banker', 0] | Passed |
| coup case 2 | [2, 7, 'banker', 1] | [2, 7, 'banker', 1] | Passed |
| coup case 3 | [3, 7, 'banker', 1] | [3, 7, 'banker', 1] | Passed |
| coup case 4 | [8, 5, 'player', 0] | [8, 5, 'player', 0] | Passed |
| coup case 5 | [9, 9, 'tie', 0] | [9, 9, 'tie', 0] | Passed |
| coup case 6 | [8, 5, 'player', 1] | [8, 6, 'player', 2] | Failed |
| coup case 7 | [3, 3, 'tie', 2] | [3, 4, 'banker', 1] | Failed |
SHA-256 / 6818fd0447f642482d411230edcdc21e652771cebf13bb333938cffae429fc64
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
p, b, shoe = x
def val(c):
r = c[0]
if r == 'A':
return 1
if r in 'TJQK':
return 0
return int(r)
def tot(h):
return sum(val(c) for c in h) % 10
p = list(p)
b = list(b)
k = 0
pt, bt = tot(p), tot(b)
if pt < 8 and bt < 8:
third = None
if pt <= 5:
p.append(shoe[k])
k += 1
third = val(p[-1])
if third is None:
draw = bt <= 5
elif bt <= 2:
draw = True
elif bt == 3:
draw = third != 8
elif bt == 4:
draw = 2 <= third <= 7
elif bt == 5:
draw = 4 <= third <= 7
elif bt == 6:
draw = 6 <= third <= 7
else:
draw = False
if draw:
b.append(shoe[k])
k += 1
pt, bt = tot(p), tot(b)
winner = 'player' if pt > bt else 'banker' if bt > pt else 'tie'
return [pt, bt, winner, k]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[['6C', '8D'], ['3H', 'TS'], ['9D', 'QS']], [3, 3, 'tie', 2]], [[['JD', '4H'], ['QC', '8D'], ['TS', '7H']], [4, 8, 'banker', 0]], [[['2H', '8C'], ['7C', 'JS'], ['2C', '7D']], [2, 7, 'banker', 1]], [[['2C', '9D'], ['7C', 'JH'], ['2S', '8H']], [3, 7, 'banker', 1]], [[['5C', '3C'], ['TC', '5H'], ['AC', 'TH']], [8, 5, 'player', 0]], [[['7C', '2C'], ['6H', '3S'], ['AH', '5S']], [9, 9, 'tie', 0]], [[['3H', 'TD'], ['QS', '5C'], ['5D', 'AD']], [8, 6, 'player', 2]], [[['4S', '9H'], ['TS', '4H'], ['KH', '9S']], [3, 4, 'banker', 1]]], [[[['6S', 'QD'], ['6C', '7D'], ['7S', '4D']], [6, 0, 'player', 1]], [[['7H', '3D'], ['JS', 'JH'], ['6H', 'AC']], [6, 1, 'player', 2]], [[['2S', '2C'], ['AS', '7D'], ['2H', '9H']], [4, 8, 'banker', 0]], [[['KC', '6H'], ['9D', 'QS'], ['2C', 'KD']], [6, 9, 'banker', 0]], [[['5S', '6C'], ['6S', '3S'], ['KC', 'KH']], [1, 9, 'banker', 0]], [[['9C', '2H'], ['JC', 'JS'], ['TH', 'QC']], [1, 0, 'player', 2]], [[['AH', 'TS'], ['3D', '2D'], ['7C', 'KC']], [8, 5, 'player', 2]], [[['QC', '5S'], ['QS', '5H'], ['8S', 'JC']], [3, 5, 'banker', 1]]], [[[['4C', '5S'], ['6S', '4H'], ['QC', '3C']], [9, 0, 'player', 0]], [[['5H', '2C'], ['TD', '6C'], ['7S', 'KC']], [7, 6, 'player', 0]], [[['2C', '4D'], ['8D', '3H'], ['KS', '6C']], [6, 1, 'player', 1]], [[['6S', 'QD'], ['8H', '9D'], ['3S', 'TD']], [6, 7, 'banker', 0]], [[['3H', 'TD'], ['QS', '5C'], ['5D', 'AD']], [8, 6, 'player', 2]], [[['6S', 'JS'], ['4D', '6D'], ['2C', 'KD']], [6, 2, 'player', 1]], [[['5D', 'JS'], ['9H', '6D'], ['QH', 'QS']], [5, 5, 'tie', 1]], [[['7D', '6C'], ['8C', '8D'], ['6S', '7S']], [9, 3, 'player', 2]]], [[[['8D', 'TH'], ['QS', '9S'], ['3S', '9H']], [8, 9, 'banker', 0]], [[['AS', '5H'], ['5D', '9D'], ['7S', '5S']], [6, 1, 'player', 1]], [[['7C', 'JD'], ['2H', 'KC'], ['JS', 'AS']], [7, 2, 'player', 1]], [[['TH', '8C'], ['2C', '7H'], ['JH', '4D']], [8, 9, 'banker', 0]], [[['TC', '5D'], ['JC', '7S'], ['7C', '4C']], [2, 7, 'banker', 1]], [[['AS', '5H'], ['6C', '8C'], ['7D', '9S']], [6, 1, 'player', 1]], [[['4H', 'AH'], ['8S', '6C'], ['9D', '7S']], [4, 4, 'tie', 1]], [[['2S', '3H'], ['4C', '2D'], ['6C', '5S']], [1, 1, 'tie', 2]]], [[[['5S', 'JS'], ['KH', 'TC'], ['4C', '9S']], [9, 9, 'tie', 2]], [[['9H', '9S'], ['TS', '4S'], ['TD', 'TC']], [8, 4, 'player', 0]], [[['9D', '9S'], ['2S', '6D'], ['6S', '4C']], [8, 8, 'tie', 0]], [[['2S', '9H'], ['7H', 'AS'], ['AH', '5H']], [1, 8, 'banker', 0]], [[['2C', '6H'], ['3D', 'TH'], ['QD', 'KS']], [8, 3, 'player', 0]], [[['2S', '2H'], ['3C', '9D'], ['KH', '6C']], [4, 8, 'banker', 2]], [[['4H', '8C'], ['3D', 'AS'], ['QH', 'QS']], [2, 4, 'banker', 1]], [[['5S', 'TS'], ['8D', '8C'], ['2H', 'QS']], [7, 6, 'player', 1]]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
check("coup 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 |
|---|---|---|---|
| coup case 0 | [3, 3, 'tie', 2] | [3, 3, 'tie', 2] | Passed |
| coup case 1 | [4, 8, 'banker', 0] | [4, 8, 'banker', 0] | Passed |
| coup case 2 | [2, 7, 'banker', 1] | [2, 7, 'banker', 1] | Passed |
| coup case 3 | [3, 7, 'banker', 1] | [3, 7, 'banker', 1] | Passed |
| coup case 4 | [8, 5, 'player', 0] | [8, 5, 'player', 0] | Passed |
| coup case 5 | [9, 9, 'tie', 0] | [9, 9, 'tie', 0] | Passed |
| coup case 6 | [8, 6, 'player', 2] | [8, 6, 'player', 2] | Passed |
| coup case 7 | [3, 4, 'banker', 1] | [3, 4, 'banker', 1] | Passed |
SHA-256 / 542da4cc3871e9675026123a56cac1a9072634f984e1e398a6bf43e6a4b28e5b
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:23.930313+00:00.
Case digest / 3d42735a4262b5d85f4e49f454a78c67f04ddd923cbcc604e2f74419d60b2236