A correct digit earns an EXACT match only in the correct position. Use the visible practice code 1122 so we can predict every result before the program reports it.
Replace lines 200, 220, 410, 1020.
Add lines 420, 470, 1030, 1040, 3000, 3010, 3020, 3120, 4000, 4010, 4020, 4030.
200 DIM c(4): LET c(1)=1: LET c(2)=1: LET c(3)=2: LET c(4)=2
220 LET t=1: LET g$="": GO SUB 1000
410 GO SUB 3000
420 GO SUB 4000: PRINT AT 18,2;" "
470 GO TO 230
1020 PRINT AT 2,1; INK 7;"Practice code: 1122"
1030 PRINT AT 4,1; INK 5;"TRY";AT 4,7;"CODE";AT 4,19;"EXACT"
1040 PRINT AT 5,1; INK 1;"-";AT 5,7;". . . .";AT 5,21;"."
3000 DIM g(4): LET bulls=0
3010 FOR i=1 TO 4: LET g(i)=VAL g$(i): IF g(i)=c(i) THEN LET bulls=bulls+1
3020 NEXT i
3120 RETURN
4000 PRINT AT 4 +t,1; INK 7;t
4010 FOR i=1 TO 4: PRINT AT 4 +t,5 +2 *i; PAPER 1; INK 7;g$(i): NEXT i
4020 PRINT AT 4 +t,21; INK 4;bulls
4030 RETURNRUN the changed program.
Complete source at this checkpoint
10 BORDER 0: PAPER 0: INK 7: BRIGHT 1: CLS
200 DIM c(4): LET c(1)=1: LET c(2)=1: LET c(3)=2: LET c(4)=2
220 LET t=1: 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 GO SUB 3000
420 GO SUB 4000: PRINT AT 18,2;" "
470 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;"Practice code: 1122"
1030 PRINT AT 4,1; INK 5;"TRY";AT 4,7;"CODE";AT 4,19;"EXACT"
1040 PRINT AT 5,1; INK 1;"-";AT 5,7;". . . .";AT 5,21;"."
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
3000 DIM g(4): LET bulls=0
3010 FOR i=1 TO 4: LET g(i)=VAL g$(i): IF g(i)=c(i) THEN LET bulls=bulls+1
3020 NEXT i
3120 RETURN
4000 PRINT AT 4 +t,1; INK 7;t
4010 FOR i=1 TO 4: PRINT AT 4 +t,5 +2 *i; PAPER 1; INK 7;g$(i): NEXT i
4020 PRINT AT 4 +t,21; INK 4;bulls
4030 RETURN
8000 PAPER 0: INK 7: BRIGHT 0: PRINT AT 21,1;"LOCKSMITH finished. ": STOP
9000 IF INKEY$<>"" THEN GO TO 9000
9010 RETURNEnter 1111 and press Enter. The result row should show 2 EXACT. The same guess remains in the editor; erase and replace it to try another. This checkpoint replaces one result row on every submission.
Four places in memory
DIM c(4) creates four numeric elements, addressed as c(1) through c(4). The LET statements put 1, 1, 2 and 2 into those places. Their order is part of the answer. The caption tells us the practice code, but the scorer reads c, never the caption.
The scoring routine creates a second four-element array, g. A character such as "2" and the number 2 are different kinds of value. VAL g$(i) converts one typed digit into a number so it can be stored in g(i) and compared with c(i). Our editor already restricts each character to 1–6.
bulls is the program’s name for the EXACT count. It begins at zero on every submission. FOR visits positions 1 through 4; IF adds one only when g(i) equals c(i). NEXT sits on a separate line, so it runs whether that comparison succeeds or fails.
Compare positions, not totals
With 1111, positions 1 and 2 match. Positions 3 and 4 do not. With 1212, positions 1 and 4 match. Both guesses earn 2 EXACT, although their matching places differ.
The clue reports a count. It does not mark the individual digits that earned it. Green makes the count easy to find, while the EXACT heading explains what it means.
Against 1122, what EXACT counts should 2211 and 1122 receive? Does 2211 contain the wrong digits?
Show the explanation
2211 receives 0: every position differs. It contains the right collection of digits, but that is a different question. 1122 receives 4 because all four positions agree. The next lesson will count digits that are present elsewhere.
The result routine prints on row 4 + t. With t still equal to 1, every submission uses row 5. The editor remains on row 17. Keeping these two places separate lets you inspect the submitted guess while preparing a change.
Try 1111, 1212 and 1122: expect 2, 2 and 4. Submit the same guess twice; the count must stay the same. If it grows, check that line 3000 resets bulls before the loop. If you see a type error, check VAL on line 3010.
Sources
Steven Vickers, edited by Robin Bradbeer, ZX Spectrum BASIC Programming, second edition (Sinclair Research, 1983), chapter 9, chapter 4, chapter 12. VAL converts the digit characters, while numeric arrays and FOR loops let the program compare corresponding positions.
Run it here
This unit's program, built for you.
- Program
- locksmith.tap
- Machine
- ZX Spectrum 48K (PAL)