Codebreaker

Date: 198x
Type: Program
Platform(s): TS 2068
Tags: Game

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).

Content

Appears On

Related Products

Related Articles

Related Content

Image Gallery

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

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

People

No people associated with this content.

Scroll to Top