FA-11641 / Game simulation rules / Open access
Combining attacks bypasses per-hit armor · case 01
Combining attacks bypasses per-hit armor.
ROOT CAUSE
Armor is subtracted from the combined turn damage.
VERIFIED REPAIR
Reduce each hit separately and clamp each result at zero.
Unsuccessful approach: Clamping only the final sum lets weak hits cancel strong hits.
Case contract
Nonnegative integer hits and armor: return sum of max(0, hit-armor) for each hit.
Why this case matters
A deterministic game-rule model isolates this rule interaction for regression testing.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(hits, armor):
return max(0, sum(hits)-armor)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('two blocked hits',solve([N,N],N),0)
check('mixed hit cannot heal',solve([0,N+3],N),3)
check('one hit',solve([N+4],N),4)
check('no attacks',solve([],N),0)
check('unarmored',solve([N,2],0),N+2)
check('all hits blocked',solve([0,N-1],N),0)
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 |
|---|---|---|---|
| two blocked hits | 1 | 0 | Failed |
| mixed hit cannot heal | 3 | 3 | Passed |
| one hit | 4 | 4 | Passed |
| no attacks | 0 | 0 | Passed |
| unarmored | 3 | 3 | Passed |
| all hits blocked | 0 | 0 | Passed |
SHA-256 / 5556471321b6dbc044d0ef6af12f2d88de03405b65f79ad29ede70921783b59d
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(hits, armor):
return max(0, sum(h-armor for h in hits))
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('two blocked hits',solve([N,N],N),0)
check('mixed hit cannot heal',solve([0,N+3],N),3)
check('one hit',solve([N+4],N),4)
check('no attacks',solve([],N),0)
check('unarmored',solve([N,2],0),N+2)
check('all hits blocked',solve([0,N-1],N),0)
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 |
|---|---|---|---|
| two blocked hits | 0 | 0 | Passed |
| mixed hit cannot heal | 2 | 3 | Failed |
| one hit | 4 | 4 | Passed |
| no attacks | 0 | 0 | Passed |
| unarmored | 3 | 3 | Passed |
| all hits blocked | 0 | 0 | Passed |
SHA-256 / ef1ca4e507e1037ff9e43eb6da7cc9d9722e82222971d1a8ef20ab0c0bbb40f9
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(hits, armor):
return sum(max(0,h-armor) for h in hits)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('two blocked hits',solve([N,N],N),0)
check('mixed hit cannot heal',solve([0,N+3],N),3)
check('one hit',solve([N+4],N),4)
check('no attacks',solve([],N),0)
check('unarmored',solve([N,2],0),N+2)
check('all hits blocked',solve([0,N-1],N),0)
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 |
|---|---|---|---|
| two blocked hits | 0 | 0 | Passed |
| mixed hit cannot heal | 3 | 3 | Passed |
| one hit | 4 | 4 | Passed |
| no attacks | 0 | 0 | Passed |
| unarmored | 3 | 3 | Passed |
| all hits blocked | 0 | 0 | Passed |
SHA-256 / 4c36ed8d1e2aa474105b09f83ae45c670ab5475353191509c8cb671e2c73dcea
Verification & scope
Controlled rules-only simulation; not a complete game engine. 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:38:49.742878+00:00.
Case digest / c4b4a462938a244a890d2477a1b2215e0d8775b86eb91cff4efb3bfab330e6d8