--- title: "Codebreaker" id: 71183 type: "computer_media" slug: "codebreaker" url: "http://localhost/computer_media/codebreaker/" markdown_url: "http://localhost/computer_media/codebreaker.md" published_at: "2026-08-30T22:44:13+00:00" modified_at: "2026-08-30T22:44:13+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2026/08/codebreaker.png" alt: "Codebreaker screen" excerpt: "A color-coded Mastermind clone that challenges you to crack a secret 4-digit code in 10 tries, with satisfying audio and visual feedback for every guess." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "TS 2068" slug: "ts2068" taxonomy: "post_tag" url: "http://localhost/tag/ts2068/" model: - name: "Timex/Sinclair 2068" slug: "ts-2068" taxonomy: "model" url: "http://localhost/model/ts-2068/" genre: - name: "Game" slug: "game" taxonomy: "genre" url: "http://localhost/type/game/" media_type: "Program" download_url: "https://archive.org/download/timex-sinclair-software-archive/Codebreaker%20%28198x%29%28-%29%28TS2068%29%28US%29%28Program%29.zip" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2026/08/codebreaker.png" alt: "Codebreaker screen" media_type_tags: "Game" --- # Codebreaker Codebreaker is a Mastermind-style number-guessing game where the player has 10 attempts to deduce a hidden 4-digit code, each digit ranging from 1 to 6. Each guess is entered one keypress at a time, with digits rendered in their corresponding INK color using block graphic characters. After each guess, the program scores it by printing UDG characters and CHR$ 143/144 indicators for exact matches (black pegs) and color-only matches (white pegs), zeroing out matched positions to avoid double-counting. The UDG at character 144 is defined via DATA at line 360 and POKEd into the UDG memory area at startup, providing a custom symbol for feedback display. *** ### Program Structure The program is organized into a main flow with two short subroutines for scoring feedback: 1. **Lines 10–20:** UDG setup and screen initialization. 2. **Lines 30–50:** Array allocation and secret code generation. 3. **Lines 60–130:** Main input loop — one guess of 4 digits per turn. 4. **Lines 140–220:** Scoring loop — exact matches first, then color-only matches. 5. **Lines 230–250:** Audio feedback and turn counter increment. 6. **Lines 260–310:** Failure/replay handler. 7. **Lines 320–330:** Subroutines for exact-match and color-match scoring. 8. **Line 340:** Win message handler. 9. **Line 360:** UDG DATA for the custom peg graphic. ### Secret Code Generation Line 50 generates the 4-element secret code array `a()` using `INT(RND*6)+1`, producing values 1–6 inclusive, mirroring the six colors of a classic Mastermind set. `RANDOMIZE` at line 40 ensures a different seed each game. ### Input Handling The game reads digits one at a time via `INKEY$` in a tight polling loop (line 80–90), accepting only characters `"1"` through `"6"`. Line 110 implements a key-release wait — it loops while `INKEY$` still returns the same character — preventing a single keypress from being counted multiple times. Each accepted digit is printed immediately using `INK VAL i$`, so digits 1–6 appear in their corresponding spectrum ink colors, using the block graphic `\::` (█) as a filled tile for visual effect. ### Scoring Algorithm Scoring uses the classic two-pass Mastermind algorithm to avoid double-counting: - **Pass 1 (lines 150–170):** Compares `b(j)` (guess) against `c(j)` (copy of secret), calling `GO SUB 320` for exact position matches. Matched elements are zeroed in both arrays. - **Pass 2 (lines 190–210):** Nested loop over all remaining non-zero pairs, calling `GO SUB 330` for color-only matches, again zeroing matched positions to prevent reuse. Note that array `c()` is a working copy of `a()` loaded at line 120 (`LET c(j)=a(j)` inside the input loop), preserving the original secret for subsequent turns. ### Feedback Display and Audio Exact matches print `CHR$ 143` (a block graphic) with a high-pitched short beep (`BEEP .01,50`); color-only matches print `CHR$ 144` (the custom UDG) with a lower beep (`BEEP .01,30`). The variable `p` accumulates the total number of pegs awarded. After scoring, line 230 checks `NOT p` (i.e., `p=0`) to play a failure tone, while line 240 plays a rising sequence of beeps proportional to the peg count, iterating from `p` to `PI` — since `PI`≈3.14159, only integer steps 0–3 are traversed, meaning at most 4 beeps regardless of peg count. ### UDG Definition Line 10 POKEs 8 bytes of DATA into `USR "\a"` (UDG “A”), defining a custom graphic. The DATA at line 360 is `255,129,P,P,P,P,P,255`. The value `P` here is the BASIC keyword token for `PRINT` (decimal 245 / &F5), which in this context is being used as a raw byte value — an unusual but functional trick to embed a specific bit pattern into the UDG data without requiring a decimal literal. ### Win and Loss Conditions If `p=4` after the exact-match pass (line 180), the game jumps to line 340 which prints a flashing `FLASH 1` congratulations message using `AT s*2,9` to position it on the current row. After 10 failed attempts, lines 260–270 reveal the secret code by printing each element with its own `INK a(j)` color. The replay prompt (lines 280–310) checks for lowercase `"p"` or `"x"` only; uppercase input loops back to line 280. ### Notable Idioms and Anomalies - `TAB PI` (lines 60, 270) uses `PI`≈3.14159 as a tab stop, which truncates to column 3 — a compact way to write `TAB 3`. - The `FOR j=p TO PI` loop at line 240 exploits floating-point truncation: the loop body executes for each integer step from `p` up to 3, neatly bounding the beep count without an explicit limit constant. - Line 370 uses `LINE 0` in the `SAVE` command, targeting line 0 which does not exist — a known technique that causes the program to load without auto-running from any specific line on some loaders. - The `PRINT '` at line 220 emits a newline using the print-literal-newline idiom (the apostrophe separator in PRINT). ## Source Code ``` 10 RESTORE :FOR j=0 TO 7:READ p:POKE USR "\a"+j,p:NEXT j 20 BORDER 7:PAPER 7:INK 9:CLS 30 DIM a(4):DIM b(4):DIM c(4) 40 LET s=1:RANDOMIZE 50 FOR j=1 TO 4:LET a(j)= INT (RND*6)+1:NEXT j 60 PRINT s; TAB PI; 70 FOR j=1 TO 4 80 LET i$= INKEY$ 90 IF i$<"1" OR i$>"6" THEN GO TO 80 100 PRINT INK VAL i$;"\:: "; 110 IF i$= INKEY$ THEN GO TO 110 120 LET b(j)= VAL i$:LET c(j)=a(j) 130 NEXT j:PRINT " "; 140 LET p=0 150 FOR j=1 TO 4 160 IF b(j)=c(j) THEN GO SUB 320 170 NEXT j 180 IF p=4 THEN GO TO 340 190 FOR j=1 TO 4:FOR h=1 TO 4 200 IF b(j)>0 AND b(j)=c(h) THEN GO SUB 330 210 NEXT h:NEXT j 220 PRINT ' 230 IF NOT p THEN BEEP .5,2:GO TO 250 240 FOR j=p TO PI:BEEP .1,5:NEXT j 250 LET s=s+1:IF s <=10 THEN GO TO 60 260 PRINT "You have failed to break the code:-" 270 PRINT TAB PI;:FOR j=1 TO 4:PRINT INK a(j);"\:: ";:NEXT j 280 INPUT "P to play again: X to stop ";a$ 290 IF a$="p" THEN RUN 300 IF a$="x" THEN STOP 310 GO TO 280 320 PRINT CHR$ 143; CHR$ 32;:BEEP .01,50:LET b(j)=0:LET c(j)=0:LET p=p+1:RETURN 330 PRINT CHR$ 144; CHR$ 32;:BEEP .01,30:LET b(j)=0:LET c(h)=0:LET p=p+1:RETURN 340 PRINT AT s*2,9; INK 2; FLASH 1;"CORRECT IN ";s 350 GO TO 280 360 DATA 255,129,P,P,P,P,P,255 370 SAVE "B&C" LINE 0 ```