FAILURE MAP
← Case archive

FA-83941 / Sports scoring and tiebreakers / Open access

Serve alternates instead of following the rally winner · case 01

After a side-out the wrong player is shown serving.

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

ROOT CAUSE

The server is never updated from the rally winner.

THE FAILURE

The server is never updated from the rally winner.

Unsuccessful approach: Alternating the serve after every rally copies table-tennis style service and is still wrong.

Case contract

One badminton singles game. rallies is a string of rally winners (A/B). A game is won at 21 points with a two-point lead, or by the first player to 30 points (29-29 next point wins). The rally winner serves next. The server serves from the right court when the server's own score is even and from the left court when odd. Return [a, b, winner, None, None] when finished (later rallies ignored) or [a, b, None, next server, "right"/"left"].

Why this case matters

Umpire scoring pads show the service court and server after each rally.

1 / The failure

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

N = 1
observations = []
def solve(rallies, first_server):
    a = b = 0
    server = first_server
    for r in rallies:
        if r == 'A':
            a += 1
        else:
            b += 1
        if (max(a, b) >= 21 and abs(a - b) >= 2) or max(a, b) == 30:
            return [a, b, r, None, None]
    own = a if server == 'A' else b
    return [a, b, None, server, 'right' if own % 2 == 0 else 'left']
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
def run(args):
    try:
        return solve(*args)
    except Exception as exc:
        return 'raised ' + type(exc).__name__
cases = [[('control opening serve', ('', 'B'), [0, 0, None, 'B', 'right']),
  ('control server wins odd point', ('A', 'A'), [1, 0, None, 'A', 'left']),
  ('boundary receiver wins rally', ('AB', 'A'), [1, 1, None, 'B', 'left']),
  ('boundary game at 21-19',
   ('AAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBAA', 'A'),
   [21, 19, 'A', None, None]),
  ('boundary cap at 30',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABB', 'A'),
   [29, 30, 'B', None, None]),
  ('control 20-all continues',
   ('ABABABABABABABABABABABABABABABABABABABAB', 'A'),
   [20, 20, None, 'B', 'right']),
  ('regression: serve follows rally', ('BBBBAABAABABBBBAA', 'A'), [7, 10, None, 'A', 'left']),
  ('regression: serve follows rally',
   ('ABABABABABABABABABABABABABABABABABABAB', 'A'),
   [19, 19, None, 'B', 'left']),
  ('variant scenario 1',
   ('BABBAAABBBAABBBABBABABAABABAABAAAAAAAA', 'A'),
   [21, 16, 'A', None, None]),
  ('variant scenario 2',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABBB', 'B'),
   [28, 30, 'B', None, None])],
 [('control opening serve', ('', 'B'), [0, 0, None, 'B', 'right']),
  ('control server wins odd point', ('A', 'A'), [1, 0, None, 'A', 'left']),
  ('boundary receiver wins rally', ('AB', 'A'), [1, 1, None, 'B', 'left']),
  ('boundary game at 21-19',
   ('AAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBAA', 'A'),
   [21, 19, 'A', None, None]),
  ('boundary cap at 30',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABB', 'A'),
   [29, 30, 'B', None, None]),
  ('control 20-all continues',
   ('ABABABABABABABABABABABABABABABABABABABAB', 'A'),
   [20, 20, None, 'B', 'right']),
  ('regression: serve follows rally',
   ('AAAABAAABABBBAAABABBAABBBBAABBAB', 'A'),
   [17, 15, None, 'B', 'left']),
  ('variant scenario 1', ('BAABBAABAAABAAAAAAAABBAAAABBBBBBAABB', 'B'), [21, 13, 'A', None, None]),
  ('variant scenario 2', ('BBBAAABABABBABABAAB', 'B'), [9, 10, None, 'B', 'right'])],
 [('control opening serve', ('', 'B'), [0, 0, None, 'B', 'right']),
  ('control server wins odd point', ('A', 'A'), [1, 0, None, 'A', 'left']),
  ('boundary receiver wins rally', ('AB', 'A'), [1, 1, None, 'B', 'left']),
  ('boundary game at 21-19',
   ('AAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBAA', 'A'),
   [21, 19, 'A', None, None]),
  ('boundary cap at 30',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABB', 'A'),
   [29, 30, 'B', None, None]),
  ('control 20-all continues',
   ('ABABABABABABABABABABABABABABABABABABABAB', 'A'),
   [20, 20, None, 'B', 'right']),
  ('regression: serve follows rally', ('AAABAAABBBBA', 'B'), [7, 5, None, 'A', 'left']),
  ('variant scenario 1',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABBAA', 'A'),
   [29, 30, 'B', None, None]),
  ('variant scenario 2',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABBAA', 'B'),
   [28, 27, None, 'A', 'right'])],
 [('control opening serve', ('', 'B'), [0, 0, None, 'B', 'right']),
  ('control server wins odd point', ('A', 'A'), [1, 0, None, 'A', 'left']),
  ('boundary receiver wins rally', ('AB', 'A'), [1, 1, None, 'B', 'left']),
  ('boundary game at 21-19',
   ('AAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBAA', 'A'),
   [21, 19, 'A', None, None]),
  ('boundary cap at 30',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABB', 'A'),
   [29, 30, 'B', None, None]),
  ('control 20-all continues',
   ('ABABABABABABABABABABABABABABABABABABABAB', 'A'),
   [20, 20, None, 'B', 'right']),
  ('regression: serve follows rally',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABAB', 'A'),
   [26, 26, None, 'B', 'right']),
  ('variant scenario 1',
   ('BBBBBABABBBBBAABBABABABBAAAABAAAABABABABAABBBBBAAABABABABBBBBA', 'B'),
   [17, 21, 'B', None, None]),
  ('variant scenario 2',
   ('ABABABABABABABABABABABABABABABABABABABABAB', 'B'),
   [21, 21, None, 'B', 'left'])],
 [('control opening serve', ('', 'B'), [0, 0, None, 'B', 'right']),
  ('control server wins odd point', ('A', 'A'), [1, 0, None, 'A', 'left']),
  ('boundary receiver wins rally', ('AB', 'A'), [1, 1, None, 'B', 'left']),
  ('boundary game at 21-19',
   ('AAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBAA', 'A'),
   [21, 19, 'A', None, None]),
  ('boundary cap at 30',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABB', 'A'),
   [29, 30, 'B', None, None]),
  ('control 20-all continues',
   ('ABABABABABABABABABABABABABABABABABABABAB', 'A'),
   [20, 20, None, 'B', 'right']),
  ('regression: serve follows rally',
   ('ABABABABABABABABABABABABABABABABABABABABABABABBAA', 'B'),
   [25, 24, None, 'A', 'left']),
  ('regression: serve follows rally',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABAB', 'A'),
   [27, 27, None, 'B', 'left']),
  ('variant scenario 1',
   ('ABABABABABABABABABABABABABABABABABABABAA', 'B'),
   [21, 19, 'A', None, None]),
  ('variant scenario 2',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABA', 'B'),
   [26, 25, None, 'A', 'right'])]]
for label, args, expected in cases[N - 1]:
    check(label, run(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 fixtureActualExpectedOutcome
control opening serve[0, 0, None, 'B', 'right'][0, 0, None, 'B', 'right']Passed
control server wins odd point[1, 0, None, 'A', 'left'][1, 0, None, 'A', 'left']Passed
boundary receiver wins rally[1, 1, None, 'A', 'left'][1, 1, None, 'B', 'left']Failed
boundary game at 21-19[21, 19, 'A', None, None][21, 19, 'A', None, None]Passed
boundary cap at 30[29, 30, 'B', None, None][29, 30, 'B', None, None]Passed
control 20-all continues[20, 20, None, 'A', 'right'][20, 20, None, 'B', 'right']Failed
regression: serve follows rally[7, 10, None, 'A', 'left'][7, 10, None, 'A', 'left']Passed
regression: serve follows rally[19, 19, None, 'A', 'left'][19, 19, None, 'B', 'left']Failed
variant scenario 1[21, 16, 'A', None, None][21, 16, 'A', None, None]Passed
variant scenario 2[28, 30, 'B', None, None][28, 30, 'B', None, None]Passed

SHA-256 / 6d21410558213907366fadbfc5b7f80e69a796a90b05482e2787b1a43fcf4899

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(rallies, first_server):
    a = b = 0
    server = first_server
    for r in rallies:
        if r == 'A':
            a += 1
        else:
            b += 1
        server = 'B' if server == 'A' else 'A'
        if (max(a, b) >= 21 and abs(a - b) >= 2) or max(a, b) == 30:
            return [a, b, r, None, None]
    own = a if server == 'A' else b
    return [a, b, None, server, 'right' if own % 2 == 0 else 'left']
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
def run(args):
    try:
        return solve(*args)
    except Exception as exc:
        return 'raised ' + type(exc).__name__
cases = [[('control opening serve', ('', 'B'), [0, 0, None, 'B', 'right']),
  ('control server wins odd point', ('A', 'A'), [1, 0, None, 'A', 'left']),
  ('boundary receiver wins rally', ('AB', 'A'), [1, 1, None, 'B', 'left']),
  ('boundary game at 21-19',
   ('AAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBAA', 'A'),
   [21, 19, 'A', None, None]),
  ('boundary cap at 30',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABB', 'A'),
   [29, 30, 'B', None, None]),
  ('control 20-all continues',
   ('ABABABABABABABABABABABABABABABABABABABAB', 'A'),
   [20, 20, None, 'B', 'right']),
  ('regression: serve follows rally', ('BBBBAABAABABBBBAA', 'A'), [7, 10, None, 'A', 'left']),
  ('regression: serve follows rally',
   ('ABABABABABABABABABABABABABABABABABABAB', 'A'),
   [19, 19, None, 'B', 'left']),
  ('variant scenario 1',
   ('BABBAAABBBAABBBABBABABAABABAABAAAAAAAA', 'A'),
   [21, 16, 'A', None, None]),
  ('variant scenario 2',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABBB', 'B'),
   [28, 30, 'B', None, None])],
 [('control opening serve', ('', 'B'), [0, 0, None, 'B', 'right']),
  ('control server wins odd point', ('A', 'A'), [1, 0, None, 'A', 'left']),
  ('boundary receiver wins rally', ('AB', 'A'), [1, 1, None, 'B', 'left']),
  ('boundary game at 21-19',
   ('AAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBAA', 'A'),
   [21, 19, 'A', None, None]),
  ('boundary cap at 30',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABB', 'A'),
   [29, 30, 'B', None, None]),
  ('control 20-all continues',
   ('ABABABABABABABABABABABABABABABABABABABAB', 'A'),
   [20, 20, None, 'B', 'right']),
  ('regression: serve follows rally',
   ('AAAABAAABABBBAAABABBAABBBBAABBAB', 'A'),
   [17, 15, None, 'B', 'left']),
  ('variant scenario 1', ('BAABBAABAAABAAAAAAAABBAAAABBBBBBAABB', 'B'), [21, 13, 'A', None, None]),
  ('variant scenario 2', ('BBBAAABABABBABABAAB', 'B'), [9, 10, None, 'B', 'right'])],
 [('control opening serve', ('', 'B'), [0, 0, None, 'B', 'right']),
  ('control server wins odd point', ('A', 'A'), [1, 0, None, 'A', 'left']),
  ('boundary receiver wins rally', ('AB', 'A'), [1, 1, None, 'B', 'left']),
  ('boundary game at 21-19',
   ('AAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBAA', 'A'),
   [21, 19, 'A', None, None]),
  ('boundary cap at 30',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABB', 'A'),
   [29, 30, 'B', None, None]),
  ('control 20-all continues',
   ('ABABABABABABABABABABABABABABABABABABABAB', 'A'),
   [20, 20, None, 'B', 'right']),
  ('regression: serve follows rally', ('AAABAAABBBBA', 'B'), [7, 5, None, 'A', 'left']),
  ('variant scenario 1',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABBAA', 'A'),
   [29, 30, 'B', None, None]),
  ('variant scenario 2',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABBAA', 'B'),
   [28, 27, None, 'A', 'right'])],
 [('control opening serve', ('', 'B'), [0, 0, None, 'B', 'right']),
  ('control server wins odd point', ('A', 'A'), [1, 0, None, 'A', 'left']),
  ('boundary receiver wins rally', ('AB', 'A'), [1, 1, None, 'B', 'left']),
  ('boundary game at 21-19',
   ('AAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBAA', 'A'),
   [21, 19, 'A', None, None]),
  ('boundary cap at 30',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABB', 'A'),
   [29, 30, 'B', None, None]),
  ('control 20-all continues',
   ('ABABABABABABABABABABABABABABABABABABABAB', 'A'),
   [20, 20, None, 'B', 'right']),
  ('regression: serve follows rally',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABAB', 'A'),
   [26, 26, None, 'B', 'right']),
  ('variant scenario 1',
   ('BBBBBABABBBBBAABBABABABBAAAABAAAABABABABAABBBBBAAABABABABBBBBA', 'B'),
   [17, 21, 'B', None, None]),
  ('variant scenario 2',
   ('ABABABABABABABABABABABABABABABABABABABABAB', 'B'),
   [21, 21, None, 'B', 'left'])],
 [('control opening serve', ('', 'B'), [0, 0, None, 'B', 'right']),
  ('control server wins odd point', ('A', 'A'), [1, 0, None, 'A', 'left']),
  ('boundary receiver wins rally', ('AB', 'A'), [1, 1, None, 'B', 'left']),
  ('boundary game at 21-19',
   ('AAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBAA', 'A'),
   [21, 19, 'A', None, None]),
  ('boundary cap at 30',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABB', 'A'),
   [29, 30, 'B', None, None]),
  ('control 20-all continues',
   ('ABABABABABABABABABABABABABABABABABABABAB', 'A'),
   [20, 20, None, 'B', 'right']),
  ('regression: serve follows rally',
   ('ABABABABABABABABABABABABABABABABABABABABABABABBAA', 'B'),
   [25, 24, None, 'A', 'left']),
  ('regression: serve follows rally',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABABAB', 'A'),
   [27, 27, None, 'B', 'left']),
  ('variant scenario 1',
   ('ABABABABABABABABABABABABABABABABABABABAA', 'B'),
   [21, 19, 'A', None, None]),
  ('variant scenario 2',
   ('ABABABABABABABABABABABABABABABABABABABABABABABABABA', 'B'),
   [26, 25, None, 'A', 'right'])]]
for label, args, expected in cases[N - 1]:
    check(label, run(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 fixtureActualExpectedOutcome
control opening serve[0, 0, None, 'B', 'right'][0, 0, None, 'B', 'right']Passed
control server wins odd point[1, 0, None, 'B', 'right'][1, 0, None, 'A', 'left']Failed
boundary receiver wins rally[1, 1, None, 'A', 'left'][1, 1, None, 'B', 'left']Failed
boundary game at 21-19[21, 19, 'A', None, None][21, 19, 'A', None, None]Passed
boundary cap at 30[29, 30, 'B', None, None][29, 30, 'B', None, None]Passed
control 20-all continues[20, 20, None, 'A', 'right'][20, 20, None, 'B', 'right']Failed
regression: serve follows rally[7, 10, None, 'B', 'right'][7, 10, None, 'A', 'left']Failed
regression: serve follows rally[19, 19, None, 'A', 'left'][19, 19, None, 'B', 'left']Failed
variant scenario 1[21, 16, 'A', None, None][21, 16, 'A', None, None]Passed
variant scenario 2[28, 30, 'B', None, None][28, 30, 'B', None, None]Passed

SHA-256 / 95a929465c8497c249f4ac6994e74c4c17de1a4b9a1ecc587c35ab9bd8b19576

HELD IN THE MEMBER ARCHIVE

The verified repair and its recorded checks are member-only.

This mechanism has 10 recorded checks per implementation. The open-access tier publishes the failure and the unsuccessful fix; the repaired source that passes every check, and the observations that prove it, are available to members.

Every case sharing this mechanism uses the same contract and the same repair, so this one record is held back for all of them.

Member access is invitation-based. Sign in with your invited account to inspect the repair.

Sign in to the archive ↗

Verification & scope

Stipulated, bounded toy contract stated in the contract field; not a claim of conformance with any governing body rulebook or operator house 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:26.344738+00:00.

Case digest / 15ba88e4302554bcb59657b3a2d0e1209ca36902b4532c7049fb28d847fa91e7