This program simulates a combination lock safe-cracking game in which the player must guess three secret numbers between 1 and 50. The screen displays a graphical safe door drawn with PLOT, DRAW, and CIRCLE commands, including concentric filled circles for a dial effect using INK 0 and INVERSE. As the player dials each number, a BEEP sequence plays with pitch values calculated from a parabolic curve centered on the target number, providing an audio hint about proximity. The player starts with 10 security units, losing one for each incorrect guess; reaching zero triggers a flashing security alert and a 50-note alarm loop before halting.
Program Analysis
Program Structure
The program is organized into three distinct phases: screen setup and graphics (lines 5–45), the main game loop across three combinations (lines 50–200), and the endgame resolution (lines 210–220). The outer FOR c=1 TO 3 loop at line 50 controls the three combination stages, with a shared input/validation/feedback cycle inside it.
Screen and Graphics Setup
Lines 5–8 paint a green background and white inner panel, then use PLOT/DRAW to draw a rectangular border at pixel coordinates (64,23) with dimensions 127×128. Lines 15–20 draw the safe dial: a solid ring of concentric circles in INK 1 (blue) for radii 25–45, then a smaller filled circle in INK 0 (black) for radii 56–64 to erase the center, giving a donut appearance. Line 40 draws solid block-graphic borders down the left and right edges using the \:: (█) escape character.
Combination and Pitch Calculation
At line 60, each secret number n is chosen randomly: INT(RND*46+5), giving a range of 5–50. Line 70 populates the 50-element array b() with pitch values using a piecewise linear formula centered on n:
- For
i < n: pitch =25 - (n-1)/2(a constant below target, scaled) - For
i > n: pitch =25 - (i-n)/2(decreasing above target) - For
i = n: pitch is set to-10(a distinct low note marking the exact target)
The Boolean arithmetic (i<n) and (i>n) evaluate to -1 (true) or 0 (false) in Spectrum BASIC, so the expression correctly selects the appropriate branch without an IF statement — a classic Sinclair idiom.
There is a subtle anomaly in the formula: the i < n branch evaluates to 25 - (n-1)/2 regardless of i, making all positions below the target play the same pitch. This means the audio hint is asymmetric: the pitch only changes as the dial passes above the target number.
Dial Animation
Lines 100–120 animate the dial movement. The loop FOR k=x TO d STEP 1-2*(d<x) sweeps from the current position x to the entered number d, stepping +1 or -1 depending on direction. Each step plays BEEP 0.1,b(k), giving an audible sweep across the pitch array. After the sweep, x is updated to d.
Input Validation
Line 90 rejects values outside 1–50 or equal to the current dial position (d=x), displaying a flashing “UNAUTHORIZED ENTRY” message and immediately setting su=0 to trigger the alarm. Line 80 uses INPUT FLASH 1; to present a flashing prompt. The condition d=x prevents re-entering the current number, simulating the requirement to move the dial.
Security Units and Endgame
The player starts with su=10 security units (line 10). Each wrong guess decrements su at line 160. A warning message appears at line 180 when only one unit remains. Reaching zero sends the program to line 210, where a 50-iteration double-beep alarm plays before STOP. Completing all three combinations sends control past line 200’s NEXT c to line 210, where the IF su=0 check is false, so execution falls through to the congratulatory message at line 220.
Notable Techniques
- Boolean expressions used as numeric values in arithmetic (lines 70, 110) — a hallmark Sinclair BASIC optimization avoiding
IFbranches inside tight loops. - Two-digit display padding at line 125: if
d < 10, a leading zero is printed manually by printing0thendat the same position. - Ascending confirmatory beeps on successful unlock (line 140):
FOR i=1 TO c: BEEP 0.5,-5*iplayscdescending-pitch tones, distinguishing first, second, and third unlocks audibly. - The array
b(50)is declared withDIM b(50)at line 10 but indexed 1–50, which is correct for Spectrum BASIC (1-based arrays).
Potential Bugs and Anomalies
- The pitch formula for positions below
nis constant (does not vary withi), so the audio feedback is one-sided. This may be intentional to increase difficulty, but it appears to be a mathematical oversight in the formula. - If
d = non a correct guess, line 115’sNEXT kwill attempt to continue the loop after line 110’sFOR k, which is fine structurally, but theb(n)=-10pitch will play as part of the sweep — the distinctive “click” note occurs at the target number during the sweep itself, which is a nice side effect. - The variable
lused in lines 5 and 7 is reused as a loop variable, but since these loops complete beforelis needed again, there is no conflict.
Content
Source Code
5 PAPER 5: FOR l=1 TO 21: PRINT TAB 31: NEXT l
7 FOR l=3 TO 18: PRINT BRIGHT 1; PAPER 7;AT l,8;" ": NEXT l
8 PLOT 64,23: DRAW 0,128: DRAW 127,0: DRAW 0,-128: DRAW -127,0
10 DIM b(50): LET x=50: LET su=10: LET cx=127: LET cy=87
15 FOR r=25 TO 45: CIRCLE INK 1,cx,cy,r: NEXT r
20 FOR r=56 TO 64: CIRCLE INK 0,cx,cy,r: NEXT r: INVERSE 1
30 PRINT AT 0,0;" CRACK THE COMBINATION "
35 PRINT AT 21,0;" ": INVERSE 0
40 FOR i=1 TO 20: PRINT AT i,0;"\::";AT i,31;"\::": NEXT i
45 PRINT AT 3,15;50
50 FOR c=1 TO 3
60 LET n=INT (RND*46+5)
70 FOR i=1 TO 50: LET b(i)=25-(i<n)*(n-1)/2-(i>n)*(i-n)/2: NEXT i
75 LET b(n)=-10
80 INPUT FLASH 1;"Enter next number:";d
90 LET d=INT d: IF d<1 OR d>50 OR d=x THEN PRINT INK 2; FLASH 1;AT 10,7;"UNAUTHORIZED ENTRY": LET su=0: GO TO 210
100 PRINT PAPER 4; FLASH 1;AT 3,15;"--"
110 FOR k=x TO d STEP 1-2*(d<x): BEEP 0.1,b(k)
115 NEXT k
120 PRINT AT 3,15;d: LET x=d
125 IF d<10 THEN PRINT AT 3,15;0;d
130 IF d<>n THEN GO TO 160
140 FOR i=1 TO c: BEEP 0.5,-5*i: NEXT i
150 PRINT AT 10,7;"Section ";c;" unlocked": GO TO 200
160 LET su=su-1: PRINT AT 20,1;"You have ";su;" security units left."
170 IF su=0 THEN PRINT AT 10,0; INK 2; FLASH 1;"** SECURITY ALERT - INTRUDER **": GO TO 210
180 IF su=1 THEN PRINT AT 15,12; PAPER 2; FLASH 1;"Warning!"
190 GO TO 80
200 NEXT c
210 IF su=0 THEN FOR i=1 TO 50: BEEP 0.5,10: BEEP 0.5,20: NEXT i: STOP
220 PRINT AT 15,0; PAPER 2; INK 7;"Well done! You have opened the safe with ";su;" turns to spare!": STOP
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
