FA-83341 / Card game rule engines / Open access
Trick winner seat runs past the last seat · case 01
When the leader is late in the rotation the winner is reported as seat 4, 5 or 6.
ROOT CAUSE
The leader offset is added to the play index without reducing modulo the number of seats.
VERIFIED REPAIR
Return (leader + index) % seats.
Unsuccessful approach: Reducing modulo a hard-coded four breaks three- and five-handed games.
Case contract
Input [cards_in_play_order, leader_seat, trump_or_None, seats]. The highest trump wins; with no trump played the highest card of the led suit wins (A high). Off-suit non-trump cards never win. Return the winning seat, counting clockwise from the leader.
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):
cards, leader, trump, seats = x
order = '23456789TJQKA'
best = 0
for i in range(1, len(cards)):
card, top = cards[i], cards[best]
if card[1] == top[1]:
if order.index(card[0]) > order.index(top[0]):
best = i
elif card[1] == trump:
best = i
return leader + best
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[['JS', 'AC', 'TS', '3S'], 3, 'C', 4], 0], [[['KC', 'AC', '8H', '8D'], 2, None, 4], 3], [[['3H', '9S', 'QD', '5H'], 3, 'D', 4], 1], [[['KD', '2H', '9D', '2D', '6C'], 4, None, 5], 4], [[['QH', '4D', 'TS', '5D', '2S'], 4, None, 5], 4], [[['8H', 'TS', '7D', 'JS'], 2, None, 4], 2], [[['8S', 'AD', 'KC'], 0, None, 3], 0], [[['6D', '2H', '4D', '5S', '7S'], 4, 'H', 5], 0]], [[[['8C', '2C', '9D', '7C'], 1, None, 4], 1], [[['9C', '7D', '8D', '2S', 'TD'], 4, 'D', 5], 3], [[['JD', '2H', 'KD', '5D', 'QS'], 0, None, 5], 2], [[['2D', 'QC', '3S', '3H'], 3, 'S', 4], 1], [[['5C', '6H', '3C', 'AC'], 2, 'D', 4], 1], [[['4D', '6S', 'TH'], 2, 'D', 3], 2], [[['9H', 'KS', '7S', '9C'], 0, 'D', 4], 0], [[['6D', 'AS', 'AD'], 1, 'H', 3], 0]], [[[['7H', '8D', 'AH', '5S', '6S'], 4, 'C', 5], 1], [[['5D', 'AD', '8H'], 1, None, 3], 2], [[['TD', '5D', 'QS', 'AC', 'KS'], 1, None, 5], 1], [[['8H', 'QC', 'JS'], 2, 'C', 3], 0], [[['KC', '6C', '4S'], 0, 'D', 3], 0], [[['3S', '6C', 'QS'], 0, 'S', 3], 2], [[['JH', '5H', 'JS'], 2, None, 3], 2], [[['JD', 'TD', '8D', '3C', '5D'], 4, 'S', 5], 4]], [[[['8S', '5S', 'KS'], 2, 'H', 3], 1], [[['3D', 'QD', '8S', '6D', 'TS'], 2, None, 5], 3], [[['6D', '2H', '4D', '5S', '7S'], 4, 'H', 5], 0], [[['8C', '5H', '6H', '9C'], 2, None, 4], 1], [[['AH', 'TD', '4H', '3S', 'KD'], 1, None, 5], 1], [[['6H', 'AS', '7H', 'JD'], 2, 'D', 4], 1], [[['7H', '3C', '6D', '5C'], 3, 'H', 4], 3], [[['2D', '2S', 'TD'], 1, None, 3], 0]], [[[['7S', '4S', '8D'], 1, 'S', 3], 1], [[['3S', 'JS', 'TC', '5D', '3H'], 2, 'D', 5], 0], [[['9H', '6H', '3D'], 1, 'S', 3], 1], [[['3H', '8D', '3C'], 0, 'H', 3], 0], [[['AD', 'JH', '8D', '5D'], 1, 'H', 4], 2], [[['8C', '8S', 'AC'], 1, None, 3], 0], [[['KH', '7H', '7S', '3D'], 0, 'S', 4], 2], [[['2C', '9C', '6S', '7S', 'KC'], 2, 'S', 5], 0]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
check("trick 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 |
|---|---|---|---|
| trick case 0 | 4 | 0 | Failed |
| trick case 1 | 3 | 3 | Passed |
| trick case 2 | 5 | 1 | Failed |
| trick case 3 | 4 | 4 | Passed |
| trick case 4 | 4 | 4 | Passed |
| trick case 5 | 2 | 2 | Passed |
| trick case 6 | 0 | 0 | Passed |
| trick case 7 | 5 | 0 | Failed |
SHA-256 / 26b37527bf0d8347e2469790b0bb19b47466549c78c3b7877cf8c3bc83b36f7f
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
cards, leader, trump, seats = x
order = '23456789TJQKA'
best = 0
for i in range(1, len(cards)):
card, top = cards[i], cards[best]
if card[1] == top[1]:
if order.index(card[0]) > order.index(top[0]):
best = i
elif card[1] == trump:
best = i
return (leader + best) % 4
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[['JS', 'AC', 'TS', '3S'], 3, 'C', 4], 0], [[['KC', 'AC', '8H', '8D'], 2, None, 4], 3], [[['3H', '9S', 'QD', '5H'], 3, 'D', 4], 1], [[['KD', '2H', '9D', '2D', '6C'], 4, None, 5], 4], [[['QH', '4D', 'TS', '5D', '2S'], 4, None, 5], 4], [[['8H', 'TS', '7D', 'JS'], 2, None, 4], 2], [[['8S', 'AD', 'KC'], 0, None, 3], 0], [[['6D', '2H', '4D', '5S', '7S'], 4, 'H', 5], 0]], [[[['8C', '2C', '9D', '7C'], 1, None, 4], 1], [[['9C', '7D', '8D', '2S', 'TD'], 4, 'D', 5], 3], [[['JD', '2H', 'KD', '5D', 'QS'], 0, None, 5], 2], [[['2D', 'QC', '3S', '3H'], 3, 'S', 4], 1], [[['5C', '6H', '3C', 'AC'], 2, 'D', 4], 1], [[['4D', '6S', 'TH'], 2, 'D', 3], 2], [[['9H', 'KS', '7S', '9C'], 0, 'D', 4], 0], [[['6D', 'AS', 'AD'], 1, 'H', 3], 0]], [[[['7H', '8D', 'AH', '5S', '6S'], 4, 'C', 5], 1], [[['5D', 'AD', '8H'], 1, None, 3], 2], [[['TD', '5D', 'QS', 'AC', 'KS'], 1, None, 5], 1], [[['8H', 'QC', 'JS'], 2, 'C', 3], 0], [[['KC', '6C', '4S'], 0, 'D', 3], 0], [[['3S', '6C', 'QS'], 0, 'S', 3], 2], [[['JH', '5H', 'JS'], 2, None, 3], 2], [[['JD', 'TD', '8D', '3C', '5D'], 4, 'S', 5], 4]], [[[['8S', '5S', 'KS'], 2, 'H', 3], 1], [[['3D', 'QD', '8S', '6D', 'TS'], 2, None, 5], 3], [[['6D', '2H', '4D', '5S', '7S'], 4, 'H', 5], 0], [[['8C', '5H', '6H', '9C'], 2, None, 4], 1], [[['AH', 'TD', '4H', '3S', 'KD'], 1, None, 5], 1], [[['6H', 'AS', '7H', 'JD'], 2, 'D', 4], 1], [[['7H', '3C', '6D', '5C'], 3, 'H', 4], 3], [[['2D', '2S', 'TD'], 1, None, 3], 0]], [[[['7S', '4S', '8D'], 1, 'S', 3], 1], [[['3S', 'JS', 'TC', '5D', '3H'], 2, 'D', 5], 0], [[['9H', '6H', '3D'], 1, 'S', 3], 1], [[['3H', '8D', '3C'], 0, 'H', 3], 0], [[['AD', 'JH', '8D', '5D'], 1, 'H', 4], 2], [[['8C', '8S', 'AC'], 1, None, 3], 0], [[['KH', '7H', '7S', '3D'], 0, 'S', 4], 2], [[['2C', '9C', '6S', '7S', 'KC'], 2, 'S', 5], 0]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
check("trick 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 |
|---|---|---|---|
| trick case 0 | 0 | 0 | Passed |
| trick case 1 | 3 | 3 | Passed |
| trick case 2 | 1 | 1 | Passed |
| trick case 3 | 0 | 4 | Failed |
| trick case 4 | 0 | 4 | Failed |
| trick case 5 | 2 | 2 | Passed |
| trick case 6 | 0 | 0 | Passed |
| trick case 7 | 1 | 0 | Failed |
SHA-256 / 5aaa95a57a58fcd995c120c727dd4629051f5d51a8fb66aa476d3fa03136f850
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
cards, leader, trump, seats = x
order = '23456789TJQKA'
best = 0
for i in range(1, len(cards)):
card, top = cards[i], cards[best]
if card[1] == top[1]:
if order.index(card[0]) > order.index(top[0]):
best = i
elif card[1] == trump:
best = i
return (leader + best) % seats
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[['JS', 'AC', 'TS', '3S'], 3, 'C', 4], 0], [[['KC', 'AC', '8H', '8D'], 2, None, 4], 3], [[['3H', '9S', 'QD', '5H'], 3, 'D', 4], 1], [[['KD', '2H', '9D', '2D', '6C'], 4, None, 5], 4], [[['QH', '4D', 'TS', '5D', '2S'], 4, None, 5], 4], [[['8H', 'TS', '7D', 'JS'], 2, None, 4], 2], [[['8S', 'AD', 'KC'], 0, None, 3], 0], [[['6D', '2H', '4D', '5S', '7S'], 4, 'H', 5], 0]], [[[['8C', '2C', '9D', '7C'], 1, None, 4], 1], [[['9C', '7D', '8D', '2S', 'TD'], 4, 'D', 5], 3], [[['JD', '2H', 'KD', '5D', 'QS'], 0, None, 5], 2], [[['2D', 'QC', '3S', '3H'], 3, 'S', 4], 1], [[['5C', '6H', '3C', 'AC'], 2, 'D', 4], 1], [[['4D', '6S', 'TH'], 2, 'D', 3], 2], [[['9H', 'KS', '7S', '9C'], 0, 'D', 4], 0], [[['6D', 'AS', 'AD'], 1, 'H', 3], 0]], [[[['7H', '8D', 'AH', '5S', '6S'], 4, 'C', 5], 1], [[['5D', 'AD', '8H'], 1, None, 3], 2], [[['TD', '5D', 'QS', 'AC', 'KS'], 1, None, 5], 1], [[['8H', 'QC', 'JS'], 2, 'C', 3], 0], [[['KC', '6C', '4S'], 0, 'D', 3], 0], [[['3S', '6C', 'QS'], 0, 'S', 3], 2], [[['JH', '5H', 'JS'], 2, None, 3], 2], [[['JD', 'TD', '8D', '3C', '5D'], 4, 'S', 5], 4]], [[[['8S', '5S', 'KS'], 2, 'H', 3], 1], [[['3D', 'QD', '8S', '6D', 'TS'], 2, None, 5], 3], [[['6D', '2H', '4D', '5S', '7S'], 4, 'H', 5], 0], [[['8C', '5H', '6H', '9C'], 2, None, 4], 1], [[['AH', 'TD', '4H', '3S', 'KD'], 1, None, 5], 1], [[['6H', 'AS', '7H', 'JD'], 2, 'D', 4], 1], [[['7H', '3C', '6D', '5C'], 3, 'H', 4], 3], [[['2D', '2S', 'TD'], 1, None, 3], 0]], [[[['7S', '4S', '8D'], 1, 'S', 3], 1], [[['3S', 'JS', 'TC', '5D', '3H'], 2, 'D', 5], 0], [[['9H', '6H', '3D'], 1, 'S', 3], 1], [[['3H', '8D', '3C'], 0, 'H', 3], 0], [[['AD', 'JH', '8D', '5D'], 1, 'H', 4], 2], [[['8C', '8S', 'AC'], 1, None, 3], 0], [[['KH', '7H', '7S', '3D'], 0, 'S', 4], 2], [[['2C', '9C', '6S', '7S', 'KC'], 2, 'S', 5], 0]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
check("trick 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 |
|---|---|---|---|
| trick case 0 | 0 | 0 | Passed |
| trick case 1 | 3 | 3 | Passed |
| trick case 2 | 1 | 1 | Passed |
| trick case 3 | 4 | 4 | Passed |
| trick case 4 | 4 | 4 | Passed |
| trick case 5 | 2 | 2 | Passed |
| trick case 6 | 0 | 0 | Passed |
| trick case 7 | 0 | 0 | Passed |
SHA-256 / 8be29126d55ad0adb5b4308390a6e567ba1f2b6c189d17f92d798c4f05ca4746
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:20.665443+00:00.
Case digest / 835a3f6a2a03e7676ec424455839d99ee5f432ed3c3ff0738cbbc422894ed295