Code Breaker
Level: Intermediate 30–60 minConcepts: AlgorithmsStringsValidationEdge Cases
Solutions: C# | TypeScript | Python
Build the scoring engine for a Mastermind-style code-breaking game. Given a secret code and a guess, return feedback indicating exact matches and partial matches.
Requirements
The secret code and guess are both 4-digit strings using digits 1–6.
Feedback Rules
- Exact match (
+) — correct digit in the correct position - Partial match (
-) — correct digit but in the wrong position - No match — digit not in the secret code
Priority
- Exact matches are evaluated first
- A digit consumed by an exact match cannot also count as a partial match
- Feedback string lists all
+symbols before-symbols
Output
Return a feedback string:
"++"means 2 exact matches"+-"means 1 exact match and 1 partial match""means no matches at all
Test Cases
| Secret | Guess | Feedback | Explanation |
|---|---|---|---|
"1234" | "5678" | "" | No matches |
"1234" | "1578" | "+" | 1 exact (position 1) |
"1234" | "1234" | "++++" | All exact |
"1234" | "4321" | "----" | All partial, none exact |
"1234" | "1243" | "++-" | Wait — see below |
"1234" | "1243" | "++--" | Positions 1,2 exact; 3,4 partial |
"1234" | "2135" | "+--" | Position 2 exact; 1,3 partial |
"1124" | "5167" | "+" | Position 2 exact; only one 1 available |
"1122" | "2211" | "----" | All partial, none in correct position |
"1111" | "1112" | "+++" | 3 exact; 2 is not a 1 |
"1111" | "2111" | "+++" | Positions 2,3,4 exact; 2 not in code |
The Tricky Case
Secret "1124", Guess "5167":
- Position 1: 5 vs 1 → no match
- Position 2: 1 vs 1 → exact match (
+) - Position 3: 6 vs 2 → no match
- Position 4: 7 vs 4 → no match
The 1 in position 1 of the guess might seem like a partial match, but the secret’s 1 at position 2 is already consumed by the exact match. Result: "+"
Bonus
- Support configurable code length (4, 5, or 6 digits)
- Support configurable digit range (1–6, 1–8, etc.)
- Build a full game loop: generate random secret, accept guesses, track attempt count
- Add a
isWon()check when feedback is all+
Hint
Process exact matches first in a separate pass. Mark matched positions as “consumed” in both the secret and guess. Then do a second pass for partial matches, only considering unconsumed positions. This two-pass approach handles all the tricky duplicate-digit cases cleanly.
Reference Walkthrough
Reference implementations in C#, TypeScript, and Python live at tddbuddy-reference-katas/code-breaker. This is an F2 (light builder) kata: two primary entities (Secret, Guess) each get a small test-folder builder so four-peg codes read as a single fluent line, a typed Peg enum closes the 1–6 domain at compile time, and Feedback carries both the structured counts (exactMatches, colorMatches) and the canonical "+"/"-" string.
Scope note — feedback engine only. The reference is scoped to scoring a guess against a secret. Random secret generation, the full game loop with attempt tracking, configurable code length, and a configurable peg range are all out of scope for this reference and listed as stretch goals in the repo README. Those responsibilities introduce a SecretGenerator collaborator and a Game aggregate — F3 territory, not F2.
- C# (.NET 8, xUnit, FluentAssertions 6.12.0) — walkthrough
- TypeScript (Node 20, Vitest 1.6, TS 5 strict) — walkthrough
- Python (3.11, pytest) — walkthrough
This kata ships in Agent Full-Bake mode at middle gear, the F2 (light builder) tier. See the repo’s Gears section for why middle gear is the deliberate choice.