FAILURE MAP
← Case archive

FA-11666 / Game simulation rules / Open access

A full winning board is classified as a draw · case 01

A full winning board is classified as a draw.

Verified by executionVariant 1 · 7 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

Full-board detection runs before win detection.

VERIFIED REPAIR

Evaluate all eight winning lines before deciding draw.

Unsuccessful approach: Checking only rows misses column and diagonal wins.

Case contract

Return X or O for the sole winner on a 3x3 board of X/O/dot; otherwise draw if full, playing if not. Inputs never have both winners.

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(board):
    if all('.' not in row for row in board): return 'draw'
    lines=list(board)+[''.join(board[r][c] for r in range(3)) for c in range(3)]+[''.join(board[i][i] for i in range(3)),''.join(board[i][2-i] for i in range(3))]
    return next((s[0] for s in lines if s in ('XXX','OOO')),'playing')
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
p='X' if N%2 else 'O'
check('last square completes row',solve(['XXX','OOX','OXO']),'X')
check('column winner',solve([p+'..',p+'..',p+'..']),p)
check('main diagonal',solve(['X..','.X.','..X']),'X')
check('other diagonal',solve(['..O','.O.','O..']),'O')
check('draw',solve(['XOX','XOO','OXX']),'draw')
check('empty',solve(['...','...','...']),'playing')
check('unfinished',solve(['X..','...','...']),'playing')
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 fixtureActualExpectedOutcome
last square completes rowdrawXFailed
column winnerXXPassed
main diagonalXXPassed
other diagonalOOPassed
drawdrawdrawPassed
emptyplayingplayingPassed
unfinishedplayingplayingPassed

SHA-256 / ac73c701beed8d046c6d5fd14bb1481217f4e923d36310de5b23baf82d0e526a

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(board):
    for s in board:
     if s in ('XXX','OOO'): return s[0]
    return 'draw' if all('.' not in row for row in board) else 'playing'
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
p='X' if N%2 else 'O'
check('last square completes row',solve(['XXX','OOX','OXO']),'X')
check('column winner',solve([p+'..',p+'..',p+'..']),p)
check('main diagonal',solve(['X..','.X.','..X']),'X')
check('other diagonal',solve(['..O','.O.','O..']),'O')
check('draw',solve(['XOX','XOO','OXX']),'draw')
check('empty',solve(['...','...','...']),'playing')
check('unfinished',solve(['X..','...','...']),'playing')
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 fixtureActualExpectedOutcome
last square completes rowXXPassed
column winnerplayingXFailed
main diagonalplayingXFailed
other diagonalplayingOFailed
drawdrawdrawPassed
emptyplayingplayingPassed
unfinishedplayingplayingPassed

SHA-256 / fefdf13d20b9e882eca9a3bfdabbdf3df7aa2735ad1ddbb359d751efcf3aa95e

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(board):
    lines=list(board)+[''.join(board[r][c] for r in range(3)) for c in range(3)]+[''.join(board[i][i] for i in range(3)),''.join(board[i][2-i] for i in range(3))]
    for s in lines:
     if s in ('XXX','OOO'): return s[0]
    return 'draw' if all('.' not in row for row in board) else 'playing'
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
p='X' if N%2 else 'O'
check('last square completes row',solve(['XXX','OOX','OXO']),'X')
check('column winner',solve([p+'..',p+'..',p+'..']),p)
check('main diagonal',solve(['X..','.X.','..X']),'X')
check('other diagonal',solve(['..O','.O.','O..']),'O')
check('draw',solve(['XOX','XOO','OXX']),'draw')
check('empty',solve(['...','...','...']),'playing')
check('unfinished',solve(['X..','...','...']),'playing')
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 fixtureActualExpectedOutcome
last square completes rowXXPassed
column winnerXXPassed
main diagonalXXPassed
other diagonalOOPassed
drawdrawdrawPassed
emptyplayingplayingPassed
unfinishedplayingplayingPassed

SHA-256 / da43e52cdf90bec89cb24a2b5cf8ccdfbdbbfce69b8a9730dfe1585070447b0b

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.906202+00:00.

Case digest / 6f26bcdfdc07ff1fbd47a76d11c787d81a03c437947589b444dbdbd6af9507a2