FA-83446 / Card game rule engines / Open access
Overtricks score no points · case 01
Made contracts with overtricks score only the bid value.
ROOT CAUSE
Overtricks are added to bags but not to the score.
VERIFIED REPAIR
Each overtrick scores one point and one bag.
Unsuccessful approach: Scoring ten per overtrick rewards sandbagging like bid tricks.
Case contract
Input [[bid1, bid2], [tricks1, tricks2], bags_before]. Nil (0) bids score +100 if the player took no tricks, else -100 and their tricks become bags. Other bids combine into a contract made by the non-nil players tricks: made -> 10*bid + 1 per overtrick (overtricks are bags); set -> -10*bid. Every 10 accumulated bags costs 100 and removes 10 bags. Return [score_delta, bags].
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):
bids, tricks, bags = x
score = 0
contract = 0
made = 0
for b, t in zip(bids, tricks):
if b == 0:
if t == 0:
score += 100
else:
score -= 100
bags += t
else:
contract += b
made += t
if made >= contract:
score += 10 * contract
over = made - contract
bags += over
else:
score -= 10 * contract
while bags >= 10:
score -= 100
bags -= 10
return [score, bags]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[[6, 4], [13, 0], 7], [3, 0]], [[[0, 2], [12, 1], 4], [-220, 6]], [[[3, 5], [1, 12], 3], [85, 8]], [[[5, 5], [12, 1], 1], [103, 4]], [[[0, 4], [3, 10], 5], [-154, 4]], [[[3, 6], [3, 8], 9], [-8, 1]], [[[5, 5], [12, 0], 5], [102, 7]], [[[1, 4], [6, 4], 5], [-45, 0]]], [[[[4, 5], [12, 1], 9], [-6, 3]], [[[4, 0], [1, 8], 8], [-240, 6]], [[[1, 0], [9, 2], 4], [-182, 4]], [[[5, 1], [6, 7], 3], [-33, 0]], [[[1, 4], [3, 8], 0], [56, 6]], [[[1, 6], [2, 0], 5], [-70, 5]], [[[4, 5], [9, 4], 4], [94, 8]], [[[2, 3], [8, 3], 4], [-44, 0]]], [[[[5, 5], [12, 1], 1], [103, 4]], [[[1, 5], [7, 0], 2], [61, 3]], [[[3, 4], [11, 1], 1], [75, 6]], [[[3, 1], [12, 0], 9], [-52, 7]], [[[5, 6], [7, 3], 6], [-110, 6]], [[[6, 0], [8, 3], 7], [-138, 2]], [[[2, 5], [13, 0], 1], [76, 7]], [[[1, 5], [10, 2], 7], [-34, 3]]], [[[[5, 5], [12, 0], 5], [102, 7]], [[[1, 5], [10, 2], 7], [-34, 3]], [[[0, 4], [1, 4], 9], [-160, 0]], [[[6, 2], [3, 4], 8], [-80, 8]], [[[3, 2], [8, 2], 6], [-45, 1]], [[[3, 4], [7, 2], 9], [-28, 1]], [[[3, 5], [7, 3], 2], [82, 4]], [[[5, 3], [7, 2], 7], [81, 8]]], [[[[5, 1], [6, 7], 3], [-33, 0]], [[[5, 3], [7, 2], 7], [81, 8]], [[[3, 5], [9, 2], 5], [83, 8]], [[[5, 3], [7, 5], 2], [84, 6]], [[[6, 2], [8, 0], 9], [80, 9]], [[[3, 0], [2, 0], 9], [70, 9]], [[[6, 4], [1, 10], 5], [101, 6]], [[[2, 3], [13, 0], 3], [-42, 1]]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
check("team score 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 |
|---|---|---|---|
| team score case 0 | [0, 0] | [3, 0] | Failed |
| team score case 1 | [-220, 6] | [-220, 6] | Passed |
| team score case 2 | [80, 8] | [85, 8] | Failed |
| team score case 3 | [100, 4] | [103, 4] | Failed |
| team score case 4 | [-160, 4] | [-154, 4] | Failed |
| team score case 5 | [-10, 1] | [-8, 1] | Failed |
| team score case 6 | [100, 7] | [102, 7] | Failed |
| team score case 7 | [-50, 0] | [-45, 0] | Failed |
SHA-256 / af2bfbe198a082175524bc3bd26b7b968f9595e4e53007addc754b8d2330b49e
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
bids, tricks, bags = x
score = 0
contract = 0
made = 0
for b, t in zip(bids, tricks):
if b == 0:
if t == 0:
score += 100
else:
score -= 100
bags += t
else:
contract += b
made += t
if made >= contract:
score += 10 * contract
over = made - contract
score += 10 * over
bags += over
else:
score -= 10 * contract
while bags >= 10:
score -= 100
bags -= 10
return [score, bags]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[[6, 4], [13, 0], 7], [3, 0]], [[[0, 2], [12, 1], 4], [-220, 6]], [[[3, 5], [1, 12], 3], [85, 8]], [[[5, 5], [12, 1], 1], [103, 4]], [[[0, 4], [3, 10], 5], [-154, 4]], [[[3, 6], [3, 8], 9], [-8, 1]], [[[5, 5], [12, 0], 5], [102, 7]], [[[1, 4], [6, 4], 5], [-45, 0]]], [[[[4, 5], [12, 1], 9], [-6, 3]], [[[4, 0], [1, 8], 8], [-240, 6]], [[[1, 0], [9, 2], 4], [-182, 4]], [[[5, 1], [6, 7], 3], [-33, 0]], [[[1, 4], [3, 8], 0], [56, 6]], [[[1, 6], [2, 0], 5], [-70, 5]], [[[4, 5], [9, 4], 4], [94, 8]], [[[2, 3], [8, 3], 4], [-44, 0]]], [[[[5, 5], [12, 1], 1], [103, 4]], [[[1, 5], [7, 0], 2], [61, 3]], [[[3, 4], [11, 1], 1], [75, 6]], [[[3, 1], [12, 0], 9], [-52, 7]], [[[5, 6], [7, 3], 6], [-110, 6]], [[[6, 0], [8, 3], 7], [-138, 2]], [[[2, 5], [13, 0], 1], [76, 7]], [[[1, 5], [10, 2], 7], [-34, 3]]], [[[[5, 5], [12, 0], 5], [102, 7]], [[[1, 5], [10, 2], 7], [-34, 3]], [[[0, 4], [1, 4], 9], [-160, 0]], [[[6, 2], [3, 4], 8], [-80, 8]], [[[3, 2], [8, 2], 6], [-45, 1]], [[[3, 4], [7, 2], 9], [-28, 1]], [[[3, 5], [7, 3], 2], [82, 4]], [[[5, 3], [7, 2], 7], [81, 8]]], [[[[5, 1], [6, 7], 3], [-33, 0]], [[[5, 3], [7, 2], 7], [81, 8]], [[[3, 5], [9, 2], 5], [83, 8]], [[[5, 3], [7, 5], 2], [84, 6]], [[[6, 2], [8, 0], 9], [80, 9]], [[[3, 0], [2, 0], 9], [70, 9]], [[[6, 4], [1, 10], 5], [101, 6]], [[[2, 3], [13, 0], 3], [-42, 1]]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
check("team score 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 |
|---|---|---|---|
| team score case 0 | [30, 0] | [3, 0] | Failed |
| team score case 1 | [-220, 6] | [-220, 6] | Passed |
| team score case 2 | [130, 8] | [85, 8] | Failed |
| team score case 3 | [130, 4] | [103, 4] | Failed |
| team score case 4 | [-100, 4] | [-154, 4] | Failed |
| team score case 5 | [10, 1] | [-8, 1] | Failed |
| team score case 6 | [120, 7] | [102, 7] | Failed |
| team score case 7 | [0, 0] | [-45, 0] | Failed |
SHA-256 / e6ed734782a63bf0276a330cbacbe521f747e8e35e7d4c62627dda36dd8850ef
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
bids, tricks, bags = x
score = 0
contract = 0
made = 0
for b, t in zip(bids, tricks):
if b == 0:
if t == 0:
score += 100
else:
score -= 100
bags += t
else:
contract += b
made += t
if made >= contract:
score += 10 * contract
over = made - contract
score += over
bags += over
else:
score -= 10 * contract
while bags >= 10:
score -= 100
bags -= 10
return [score, bags]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[[6, 4], [13, 0], 7], [3, 0]], [[[0, 2], [12, 1], 4], [-220, 6]], [[[3, 5], [1, 12], 3], [85, 8]], [[[5, 5], [12, 1], 1], [103, 4]], [[[0, 4], [3, 10], 5], [-154, 4]], [[[3, 6], [3, 8], 9], [-8, 1]], [[[5, 5], [12, 0], 5], [102, 7]], [[[1, 4], [6, 4], 5], [-45, 0]]], [[[[4, 5], [12, 1], 9], [-6, 3]], [[[4, 0], [1, 8], 8], [-240, 6]], [[[1, 0], [9, 2], 4], [-182, 4]], [[[5, 1], [6, 7], 3], [-33, 0]], [[[1, 4], [3, 8], 0], [56, 6]], [[[1, 6], [2, 0], 5], [-70, 5]], [[[4, 5], [9, 4], 4], [94, 8]], [[[2, 3], [8, 3], 4], [-44, 0]]], [[[[5, 5], [12, 1], 1], [103, 4]], [[[1, 5], [7, 0], 2], [61, 3]], [[[3, 4], [11, 1], 1], [75, 6]], [[[3, 1], [12, 0], 9], [-52, 7]], [[[5, 6], [7, 3], 6], [-110, 6]], [[[6, 0], [8, 3], 7], [-138, 2]], [[[2, 5], [13, 0], 1], [76, 7]], [[[1, 5], [10, 2], 7], [-34, 3]]], [[[[5, 5], [12, 0], 5], [102, 7]], [[[1, 5], [10, 2], 7], [-34, 3]], [[[0, 4], [1, 4], 9], [-160, 0]], [[[6, 2], [3, 4], 8], [-80, 8]], [[[3, 2], [8, 2], 6], [-45, 1]], [[[3, 4], [7, 2], 9], [-28, 1]], [[[3, 5], [7, 3], 2], [82, 4]], [[[5, 3], [7, 2], 7], [81, 8]]], [[[[5, 1], [6, 7], 3], [-33, 0]], [[[5, 3], [7, 2], 7], [81, 8]], [[[3, 5], [9, 2], 5], [83, 8]], [[[5, 3], [7, 5], 2], [84, 6]], [[[6, 2], [8, 0], 9], [80, 9]], [[[3, 0], [2, 0], 9], [70, 9]], [[[6, 4], [1, 10], 5], [101, 6]], [[[2, 3], [13, 0], 3], [-42, 1]]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
check("team score 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 |
|---|---|---|---|
| team score case 0 | [3, 0] | [3, 0] | Passed |
| team score case 1 | [-220, 6] | [-220, 6] | Passed |
| team score case 2 | [85, 8] | [85, 8] | Passed |
| team score case 3 | [103, 4] | [103, 4] | Passed |
| team score case 4 | [-154, 4] | [-154, 4] | Passed |
| team score case 5 | [-8, 1] | [-8, 1] | Passed |
| team score case 6 | [102, 7] | [102, 7] | Passed |
| team score case 7 | [-45, 0] | [-45, 0] | Passed |
SHA-256 / e2bdf1afb7f6ee7e0e8179ad179507f7238c797474d453f825ec8273b1571938
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.654600+00:00.
Case digest / 1c5c7494041f181e6ddc6bc738cd46b358ce2f9742709303a67f3bbed534de4f