Skip to content

Make a round

Count distinct mistakes, recognise endings and preserve a paused word.

  • Sinclair ZX Spectrum
  • BASIC

Give a round a consequence: seven distinct missed letters use up the allowance. A repeated hit or miss is free. A completed word wins. Keep the fixed word while we establish these rules; choosing fresh words comes later.

Add lines 210, 355, 360, 370, 380, 390, 450, 460, 600, 610, 620, 630, 640, 650, 660, 670, 680, 690, 700, 710, 740, 750, 760, 770, 780, 790, 2000, 2010, 2020, 2200, 2205, 2210, 2500, 2520, 2580, 2590, 2600.

Replace lines 200, 250, 270, 300, 320, 350, 440.

changes.bas
 200 LET wins=0: LET losses=0: LET round=1
 210 LET w$="BOTTLE"
 250 LET d$="": LET t$="": LET m$="": LET left=7
 270 LET a$="Choose a letter.": GO SUB 2000
 300 GO SUB 2500
 320 IF CODE k$=13 THEN GO TO 600
 350 LET g$=CHR$ (c-32): LET seen=0
 355 IF t$="" THEN GO TO 390
 360 FOR i=1 TO LEN t$: IF t$(i)=g$ THEN LET seen=1
 370 NEXT i
 380 IF seen=1 THEN LET a$=g$+" already tried. No cost.": GO TO 300
 390 LET t$=t$+g$: LET found=0
 440 IF found=0 THEN LET left=left-1: LET m$=m$+g$: LET a$=g$+" is not in the word."
 450 IF d$=w$ THEN LET wins=wins+1: LET a$="Word found!": GO TO 700
 460 IF left=0 THEN LET losses=losses+1: LET a$="No guesses left. Word revealed.": GO TO 700
 600 CLS : PRINT AT 3,10; INK 5; BRIGHT 1;"C I P H E R"
 610 PRINT AT 7,3;"PAUSED - word stays hidden."
 620 PRINT AT 10,3;"C continues this word."
 630 PRINT AT 12,3;"R resets words and scores."
 640 PRINT AT 14,3;"Q quits to BASIC."
 650 GO SUB 8000
 660 IF k$="q" THEN STOP
 670 IF k$="r" THEN GO TO 200
 680 IF k$="c" THEN GO SUB 2000: GO TO 300
 690 GO TO 650
 700 GO SUB 2000
 710 PRINT AT 6,2;w$
 740 PRINT AT 21,1;"SPACE next. R resets. Q quits. "
 750 GO SUB 8000
 760 IF k$="q" THEN STOP
 770 IF k$="r" THEN GO TO 200
 780 IF k$=" " THEN LET round=round+1: GO TO 210
 790 GO TO 750
2000 CLS
2010 PRINT AT 1,2; INK 5; BRIGHT 1;"CIPHER";AT 1,19;"WORD ";round
2020 PRINT AT 3,2;"Won ";wins;"   Lost ";losses
2200 PRINT AT 21,1;"Letter guesses. ENTER pauses."
2205 GO SUB 2500
2210 RETURN
2500 PRINT AT 6,2;d$
2520 PRINT AT 9,2; INK 6;"MISTAKES LEFT: ";left
2580 PRINT AT 17,2;"Misses: ";m$
2590 LET b$=a$+"                              ": PRINT AT 19,1; INK 6;b$( TO 30)
2600 RETURN
Complete source at this checkpoint
cipher.bas
  10 BORDER 0: PAPER 0: INK 7: BRIGHT 0: CLS
 200 LET wins=0: LET losses=0: LET round=1
 210 LET w$="BOTTLE"
 250 LET d$="": LET t$="": LET m$="": LET left=7
 260 FOR i=1 TO LEN w$: LET d$=d$+"_": NEXT i
 270 LET a$="Choose a letter.": GO SUB 2000
 300 GO SUB 2500
 310 GO SUB 8000
 320 IF CODE k$=13 THEN GO TO 600
 330 LET c=CODE k$
 340 IF c<97 OR c>122 THEN GO TO 310
 350 LET g$=CHR$ (c-32): LET seen=0
 355 IF t$="" THEN GO TO 390
 360 FOR i=1 TO LEN t$: IF t$(i)=g$ THEN LET seen=1
 370 NEXT i
 380 IF seen=1 THEN LET a$=g$+" already tried. No cost.": GO TO 300
 390 LET t$=t$+g$: LET found=0
 400 FOR i=1 TO LEN w$
 410 IF w$(i)=g$ THEN LET d$(i TO i)=g$: LET found=found+1
 420 NEXT i
 430 IF found>0 THEN LET a$=g$+" reveals "+STR$ found+" letter(s)."
 440 IF found=0 THEN LET left=left-1: LET m$=m$+g$: LET a$=g$+" is not in the word."
 450 IF d$=w$ THEN LET wins=wins+1: LET a$="Word found!": GO TO 700
 460 IF left=0 THEN LET losses=losses+1: LET a$="No guesses left. Word revealed.": GO TO 700
 470 GO TO 300
 600 CLS : PRINT AT 3,10; INK 5; BRIGHT 1;"C I P H E R"
 610 PRINT AT 7,3;"PAUSED - word stays hidden."
 620 PRINT AT 10,3;"C continues this word."
 630 PRINT AT 12,3;"R resets words and scores."
 640 PRINT AT 14,3;"Q quits to BASIC."
 650 GO SUB 8000
 660 IF k$="q" THEN STOP
 670 IF k$="r" THEN GO TO 200
 680 IF k$="c" THEN GO SUB 2000: GO TO 300
 690 GO TO 650
 700 GO SUB 2000
 710 PRINT AT 6,2;w$
 740 PRINT AT 21,1;"SPACE next. R resets. Q quits. "
 750 GO SUB 8000
 760 IF k$="q" THEN STOP
 770 IF k$="r" THEN GO TO 200
 780 IF k$=" " THEN LET round=round+1: GO TO 210
 790 GO TO 750
2000 CLS
2010 PRINT AT 1,2; INK 5; BRIGHT 1;"CIPHER";AT 1,19;"WORD ";round
2020 PRINT AT 3,2;"Won ";wins;"   Lost ";losses
2200 PRINT AT 21,1;"Letter guesses. ENTER pauses."
2205 GO SUB 2500
2210 RETURN
2500 PRINT AT 6,2;d$
2520 PRINT AT 9,2; INK 6;"MISTAKES LEFT: ";left
2580 PRINT AT 17,2;"Misses: ";m$
2590 LET b$=a$+"                              ": PRINT AT 19,1; INK 6;b$( TO 30)
2600 RETURN
8000 LET k$=INKEY$
8010 IF INKEY$<>"" THEN GO TO 8010
8020 LET k$=INKEY$: IF k$="" THEN GO TO 8020
8030 IF CODE k$>=65 AND CODE k$<=90 THEN LET k$=CHR$ (CODE k$+32)
8040 RETURN

RUN and try T, T, Z, Z. The reveal should be __TT__, the remaining count six, and the miss list just Z. Then try B, O, L and E to finish. Space begins another BOTTLE round and keeps the score. R resets the session. This is deliberate repetition while we check the rules.

Remember an attempt once

The string t$ stores every accepted letter. The string m$ stores only misses. Both begin empty. Before searching the answer, lines 350–380 scan t$ and set seen to one if the letter is already there. Line 355 bypasses that scan when there are no earlier attempts. The duplicate branch returns to the display before appending a letter or spending a mistake.

For a new guess, line 390 appends it and clears found. After the answer search, found equal to zero means this new letter missed: decrease left by one and append the letter to m$. A repeated letter in the answer can raise found several times; it is still one guess in the history.

The completion checks happen after revealing and charging. Comparing d$ with w$ asks whether the entire word has been uncovered. The other ending tests left for zero. Each branch updates its score once and enters a separate result loop, so an ignored key cannot score the same round again.

On a fresh BOTTLE round, what remains after A, A, T, then Z?

Show the explanation

Five mistakes remain. A costs one; its repeat costs nothing; T reveals two positions without a cost; Z costs one. The reveal is __TT__, the attempt history is ATZ and the displayed miss list is AZ.

Q and R must remain available as guesses. Enter now pauses instead of quitting. The pause loop accepts C to continue, R to reset words and scores, or Q to STOP in BASIC. Continuing returns to drawing without changing the word, history or allowance. Reset jumps to 200 and discards the current session.

The result loop uses Space for the next round, R for a reset and Q to quit. Going to 210 retains wins and losses; going to 200 clears them. The round counter increases only on Space. With the fixed word, replay tests state handling rather than variety.

Separate drawing from decisions

GO SUB 2000 clears the screen and draws the headings, score and controls. It calls 2500 for changing fields: revealed word, allowance, misses and feedback. Most guesses call only 2500. Neither routine changes the game’s rules; both return to their caller.

A shorter message could leave the end of an older message behind. Line 2590 appends spaces to a$, then prints the first thirty characters of that padded string. b$(TO 30) starts at position one. The blank tail overwrites old text.

Check a loss with A, C, D, F, G, H and I. The seventh distinct miss should reveal BOTTLE and record one loss. Try a held key, pause and continue midway through a word, reset from both menus, and quit. These controls are part of completing the game, not decoration added after the rules.

Sources

Steven Vickers, edited by Robin Bradbeer, ZX Spectrum BASIC Programming, second edition (Sinclair Research, 1983), chapter 3, chapter 4, chapter 5, chapter 8.

Run it here

This unit's program, built for you.

Program
cipher.tap
Machine
ZX Spectrum 48K (PAL)

Download cipher.tap