Crack Safe

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

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 IF branches inside tight loops.
  • Two-digit display padding at line 125: if d < 10, a leading zero is printed manually by printing 0 then d at the same position.
  • Ascending confirmatory beeps on successful unlock (line 140): FOR i=1 TO c: BEEP 0.5,-5*i plays c descending-pitch tones, distinguishing first, second, and third unlocks audibly.
  • The array b(50) is declared with DIM 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 n is constant (does not vary with i), 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 = n on a correct guess, line 115’s NEXT k will attempt to continue the loop after line 110’s FOR k, which is fine structurally, but the b(n)=-10 pitch 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 l used in lines 5 and 7 is reused as a loop variable, but since these loops complete before l is needed again, there is no conflict.

Content

Appears On

Related Products

Related Articles

Related Content

Image Gallery

Crack Safe

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.

People

No people associated with this content.

Scroll to Top