Skip to content

Edit four digits

Read individual keys, limit a guess and erase its last digit.

  • Sinclair ZX Spectrum
  • BASIC

Let the player build a guess one digit at a time. A mistake should be easy to erase, and holding a key should not fill all four spaces.

Replace lines 240, 1060.

Add lines 230, 250, 260, 270, 280, 290, 300, 310, 320, 350, 360, 400, 410, 1070, 2010, 8000, 9000, 9010.

changes.bas
 230 GO SUB 9000
 240 GO SUB 2000
 250 LET k$=INKEY$: IF k$="" THEN GO TO 250
 260 IF k$="q" OR k$="Q" THEN GO TO 8000
 270 IF k$="r" OR k$="R" THEN GO TO 200
 280 IF k$=CHR$ 13 THEN GO TO 400
 290 IF k$="d" OR k$="D" OR k$=CHR$ 12 THEN GO TO 350
 300 IF k$<"1" OR k$>"6" THEN GO TO 230
 310 IF LEN g$=4 THEN GO TO 230
 320 LET g$=g$+k$: GO TO 230
 350 IF LEN g$>0 THEN LET g$=g$( TO LEN g$-1)
 360 GO TO 230
 400 IF LEN g$<>4 THEN PRINT AT 18,2; INK 6;"Enter four digits first.     ": GO TO 230
 410 PRINT AT 18,2; INK 4;"Four digits ready.          ": GO TO 230
1060 PRINT AT 20,1; INK 7;"1-6: digits   D: erase"
1070 PRINT AT 21,1;"ENTER: check  R: clear Q: quit"
2010 FOR i=1 TO LEN g$: PRINT AT 17,5 +2 *i; PAPER 1; INK 7;g$(i): NEXT i
8000 PAPER 0: INK 7: BRIGHT 0: PRINT AT 21,1;"LOCKSMITH finished.           ": STOP
9000 IF INKEY$<>"" THEN GO TO 9000
9010 RETURN

RUN the changed program.

Complete source at this checkpoint
locksmith.bas
  10 BORDER 0: PAPER 0: INK 7: BRIGHT 1: CLS
 200 LET t=1
 220 LET g$="": GO SUB 1000
 230 GO SUB 9000
 240 GO SUB 2000
 250 LET k$=INKEY$: IF k$="" THEN GO TO 250
 260 IF k$="q" OR k$="Q" THEN GO TO 8000
 270 IF k$="r" OR k$="R" THEN GO TO 200
 280 IF k$=CHR$ 13 THEN GO TO 400
 290 IF k$="d" OR k$="D" OR k$=CHR$ 12 THEN GO TO 350
 300 IF k$<"1" OR k$>"6" THEN GO TO 230
 310 IF LEN g$=4 THEN GO TO 230
 320 LET g$=g$+k$: GO TO 230
 350 IF LEN g$>0 THEN LET g$=g$( TO LEN g$-1)
 360 GO TO 230
 400 IF LEN g$<>4 THEN PRINT AT 18,2; INK 6;"Enter four digits first.     ": GO TO 230
 410 PRINT AT 18,2; INK 4;"Four digits ready.          ": GO TO 230
1000 CLS
1010 PRINT AT 0,1; INK 5;"LOCKSMITH";AT 0,21; INK 7;"PRACTICE"
1020 PRINT AT 2,1; INK 7;"Build a four-digit guess."
1050 PRINT AT 16,1; INK 5;"------------------------------"
1060 PRINT AT 20,1; INK 7;"1-6: digits   D: erase"
1070 PRINT AT 21,1;"ENTER: check  R: clear Q: quit"
1080 RETURN
2000 PRINT AT 17,1; INK 5;"TRY ";t;" ";AT 17,7; INK 7;"_ _ _ _"
2010 FOR i=1 TO LEN g$: PRINT AT 17,5 +2 *i; PAPER 1; INK 7;g$(i): NEXT i
2020 RETURN
8000 PAPER 0: INK 7: BRIGHT 0: PRINT AT 21,1;"LOCKSMITH finished.           ": STOP
9000 IF INKEY$<>"" THEN GO TO 9000
9010 RETURN

Press 1, 2, 3 and 4, releasing each key. Enter now reports “Four digits ready.” There is no secret code or scoring yet. D erases the last digit; the Spectrum DELETE key also works. R clears the board and Q quits.

Read, recognise, then change

INKEY$ gives the current key character, or an empty string when no key is recognised. Line 250 waits for a character. The following tests recognise commands before considering digits. OR means either comparison may succeed, so both upper-case and lower-case R work.

CHR$ 13 is the Enter character and CHR$ 12 is DELETE. Comparing these characters lets the editor recognise keys that do not print a digit. At line 300, characters outside "1" through "6" are rejected. The four-character limit at 310 comes next. Only a valid digit with room available reaches LET g$=g$+k$, which joins it onto the end.

LEN counts characters. Enter checks that the length is exactly four before confirming the guess. The <> operator means “not equal”. A short guess stays available to finish; an ignored key does not use a space.

Erase and redraw

Line 350 keeps the slice from the beginning of g$ through its penultimate character. Omitting the start before TO means position 1. With one character left, the slice ends at 0 and becomes empty. The length check prevents trying to shorten an already empty string.

The drawing routine first prints all four underscores. Its FOR loop then visits each entered character, with i starting at 1 and NEXT advancing it. g$(i) selects that character. The column expression 5 +2 *i gives 7, 9, 11 and 13: multiply first, then add. Each digit covers one underscore with white ink on blue paper. Drawing the underscores again removes an erased digit too.

Wait for release

The routine at 9000 waits while INKEY$ is non-empty. The main loop visits it before reading another command. A recognised press therefore changes the guess once, even when held. Release the key before pressing the next one.

You press and release 1, 2, 3, 4, 5 and 6, then press and release D twice. What remains?

Show the explanation

12 remains. The field filled at 1234, so 5 and 6 were ignored. The two separate D presses removed 4 and then 3. Holding D would remove only one character before the release gate waited.

Check an empty Enter press, a three-digit Enter press and an invalid 9. None should produce a complete guess. Try deleting all four characters and once more. If a held key repeats, check the route back to 230 and the release routine; if erased digits remain visible, check that line 2000 still draws the underscores first.

Sources

Steven Vickers, edited by Robin Bradbeer, ZX Spectrum BASIC Programming, second edition (Sinclair Research, 1983), chapter 8, chapter 9, chapter 4, chapter 14, chapter 18. String slices, LEN, loops, character codes and INKEY$ support the editor.

Run it here

This unit's program, built for you.

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

Download locksmith.tap