Skip to content

Finish one room

Count uncovered targets, then give the room a beginning and ending.

  • Sinclair ZX Spectrum
  • BASIC

The player can deliver the crate. Now the program needs to recognise that delivery. We will first display a count, then use it to finish the room.

Count what is left

Add lines 85, 475, 476, 2505, 6000, 6010, 6015, 6020.

step-01-edits.bas
  85 GO SUB 6000
 475 IF v=4 THEN LET left=left+1
 476 IF bv=2 THEN LET left=left-1
2505 PRINT AT 1,18; INK 5;"GOALS ";total-left;"/";total
6000 LET left=0: LET total=0: FOR r=1 TO 8: FOR c=1 TO 8
6010 IF g(r,c)=2 THEN LET left=left+1
6015 IF g(r,c)=2 OR g(r,c)=4 THEN LET total=total+1
6020 NEXT c: NEXT r: RETURN
Complete program for this step
step-01.bas
  10 GO SUB 7000: LET h$=""
  15 LET room=1
  20 DIM g(8,8)
  30 FOR r=1 TO 8: FOR c=1 TO 8
  40 IF r=1 OR r=8 OR c=1 OR c=8 THEN LET g(r,c)=1
  50 NEXT c: NEXT r
  60 LET g(3,4)=1: LET g(4,4)=1
  70 LET g(3,5)=2: LET g(5,4)=3
  80 LET pr=6: LET pc=3: LET moves=0: LET won=0
  85 GO SUB 6000
 100 GO SUB 1000
 110 GO SUB 3000
 120 IF k$="q" OR k$="Q" THEN GO TO 9000
 130 IF k$="r" OR k$="R" THEN GO TO 20
 150 LET dr=0: LET dc=0
 160 IF k$="i" OR k$="I" THEN LET dr=-1
 170 IF k$="k" OR k$="K" THEN LET dr=1
 180 IF k$="j" OR k$="J" THEN LET dc=-1
 190 IF k$="l" OR k$="L" THEN LET dc=1
 200 IF dr=0 AND dc=0 THEN GO TO 110
 210 LET nr=pr+dr: LET nc=pc+dc
 220 IF nr<1 OR nr>8 OR nc<1 OR nc>8 THEN GO TO 700
 230 LET v=g(nr,nc)
 240 IF v=1 THEN GO TO 700
 250 IF v=3 OR v=4 THEN GO TO 400
 260 GO TO 500
 400 LET br=nr+dr: LET bc=nc+dc
 410 IF br<1 OR br>8 OR bc<1 OR bc>8 THEN GO TO 700
 420 LET bv=g(br,bc)
 430 IF bv<>0 AND bv<>2 THEN GO TO 700
 440 LET g(nr,nc)=0
 450 IF v=4 THEN LET g(nr,nc)=2
 460 LET g(br,bc)=3
 470 IF bv=2 THEN LET g(br,bc)=4
 475 IF v=4 THEN LET left=left+1
 476 IF bv=2 THEN LET left=left-1
 480 LET r=br: LET c=bc: GO SUB 2000
 500 LET oldr=pr: LET oldc=pc
 510 LET pr=nr: LET pc=nc: LET moves=moves+1
 520 LET r=oldr: LET c=oldc: GO SUB 2000
 530 LET r=pr: LET c=pc: GO SUB 2000
 600 GO SUB 2500
 610 GO TO 110
 700 GO TO 110
1000 BORDER 0: PAPER 0: INK 7: CLS
1010 PRINT AT 0,2; INK 5;"CRATES";AT 0,24; INK 7;"ROOM 0";room
1020 PRINT AT 20,2; INK 7;"I up  J left  K down  L right"
1030 PRINT AT 21,6; INK 5;"R restart     Q quit";
1040 FOR r=1 TO 8: FOR c=1 TO 8
1050 GO SUB 2000
1060 NEXT c: NEXT r
1070 GO SUB 2500
1080 RETURN
2000 LET y=3 +2 *(r-1): LET x=8 +2 *(c-1)
2010 LET z=g(r,c)+1
2020 IF r=pr AND c=pc THEN LET z=6
2025 IF z=6 AND g(r,c)=2 THEN LET z=7
2030 PRINT AT y,x; INK a(z);t$(z,1 TO 2);AT y+1,x;t$(z,3 TO 4)
2040 RETURN
2500 PRINT AT 1,2; INK 7;"STEPS ";moves;"    "
2505 PRINT AT 1,18; INK 5;"GOALS ";total-left;"/";total
2540 RETURN
3000 LET k$=INKEY$
3010 IF k$=h$ THEN GO TO 3000
3020 LET h$=k$
3025 IF k$="" THEN GO TO 3000
3030 RETURN
6000 LET left=0: LET total=0: FOR r=1 TO 8: FOR c=1 TO 8
6010 IF g(r,c)=2 THEN LET left=left+1
6015 IF g(r,c)=2 OR g(r,c)=4 THEN LET total=total+1
6020 NEXT c: NEXT r: RETURN
7000 RESTORE 7200: FOR n=0 TO 159: READ b: POKE USR "a"+n,b: NEXT n
7010 DIM t$(7,4): DIM a(7)
7020 LET t$(1)="    ": LET t$(2)=CHR$ 144 +CHR$ 145 +CHR$ 146 +CHR$ 147
7030 LET t$(3)=CHR$ 148 +CHR$ 149 +CHR$ 150 +CHR$ 151
7040 LET t$(4)=CHR$ 152 +CHR$ 153 +CHR$ 154 +CHR$ 155: LET t$(5)=t$(4)
7050 LET t$(6)=CHR$ 156 +CHR$ 157 +CHR$ 158 +CHR$ 159
7055 LET t$(7)=CHR$ 160 +CHR$ 161 +CHR$ 162 +CHR$ 163
7060 LET a(1)=0: LET a(2)=1: LET a(3)=5: LET a(4)=6: LET a(5)=4: LET a(6)=7: LET a(7)=5: RETURN
7200 DATA 0,254,129,129,129,129,129,0
7210 DATA 0,254,2,2,2,2,2,0
7220 DATA 127,64,64,64,64,64,127,0
7230 DATA 127,129,129,129,129,129,127,0
7240 DATA 0,0,0,3,12,8,16,17
7250 DATA 0,0,0,192,48,16,8,136
7260 DATA 17,16,8,12,3,0,0,0
7270 DATA 136,8,16,48,192,0,0,0
7280 DATA 0,127,64,95,88,84,82,81
7290 DATA 0,254,2,250,26,42,74,138
7300 DATA 81,82,84,88,95,64,127,0
7310 DATA 138,74,42,26,250,2,254,0
7320 DATA 3,7,7,3,1,15,31,27
7330 DATA 192,224,224,192,128,240,248,216
7340 DATA 27,3,3,7,6,6,14,0
7350 DATA 216,192,192,224,96,96,112,0
7360 DATA 3,7,7,3,13,15,31,27
7370 DATA 192,224,224,192,176,240,248,216
7380 DATA 27,19,11,15,7,6,14,0
7390 DATA 216,200,208,240,224,96,112,0
9000 PAPER 0: INK 7
9010 PRINT AT 21,0;"Finished. RUN to try again.     ";
9020 STOP

The routine at 6000 scans the starting room once. left counts cells containing an uncovered target, code 2. total counts all targets, including code 4, a target already covered by a crate. Line 85 calls it whenever the room is rebuilt.

During play we already know the two cells involved in a push. If the crate leaves a target, line 475 adds one to left. If it enters a target, line 476 subtracts one. Walking changes neither. This avoids scanning the whole array after each step.

The GOALS readout prints total - left, the number filled, followed by the total. Room one starts at 0/1 and a delivery makes it 1/1. This gives delivery a textual cue as well as the green crate.

A crate leaves one target and enters another in the same push. What happens to left?

Show the explanation

Leaving adds one uncovered target; entering removes one. The net change is zero. Both tests must run: making the second an alternative to the first would lose half of the update.

Run and deliver with I, L, K, L, I, I. The readout should become 1/1, but movement is still allowed. Push the crate off using the route from the previous lesson and it should return to 0/1. R resets the room and its count.

Make a complete visit

Replace line 10.

Add lines 140, 590, 2510, 5000, 5010, 5020, 5030, 5040, 5050, 5060, 5070, 5080, 5090, 5100, 5110, 5120.

step-02-edits.bas
  10 GO SUB 7000: GO SUB 5000
 140 IF won=1 THEN GO TO 110
 590 IF left=0 THEN LET won=1
2510 IF won=1 THEN PRINT AT 19,2; INK 4;"Delivered! R replay / Q quit"
5000 BORDER 0: PAPER 0: INK 7: CLS : LET h$=""
5010 PRINT AT 2,12; INK 5;"CRATES"
5020 PRINT AT 5,2; INK 7;"A small warehouse puzzle."
5030 PRINT AT 7,1;"I up, J left, K down, L right."
5040 PRINT AT 9,1;"Push crates onto the targets."
5050 PRINT AT 11,1;"You can push, but never pull."
5060 PRINT AT 13,1;"R restarts the room. Q quits."
5070 PRINT AT 15,1;"One step per press. Take time."
5080 PRINT AT 18,1;"S starts. Q quits."
5090 GO SUB 3000
5100 IF k$="q" OR k$="Q" THEN GO TO 9000
5110 IF k$<>"s" AND k$<>"S" THEN GO TO 5090
5120 RETURN
Complete program for this step
step-02.bas
  10 GO SUB 7000: GO SUB 5000
  15 LET room=1
  20 DIM g(8,8)
  30 FOR r=1 TO 8: FOR c=1 TO 8
  40 IF r=1 OR r=8 OR c=1 OR c=8 THEN LET g(r,c)=1
  50 NEXT c: NEXT r
  60 LET g(3,4)=1: LET g(4,4)=1
  70 LET g(3,5)=2: LET g(5,4)=3
  80 LET pr=6: LET pc=3: LET moves=0: LET won=0
  85 GO SUB 6000
 100 GO SUB 1000
 110 GO SUB 3000
 120 IF k$="q" OR k$="Q" THEN GO TO 9000
 130 IF k$="r" OR k$="R" THEN GO TO 20
 140 IF won=1 THEN GO TO 110
 150 LET dr=0: LET dc=0
 160 IF k$="i" OR k$="I" THEN LET dr=-1
 170 IF k$="k" OR k$="K" THEN LET dr=1
 180 IF k$="j" OR k$="J" THEN LET dc=-1
 190 IF k$="l" OR k$="L" THEN LET dc=1
 200 IF dr=0 AND dc=0 THEN GO TO 110
 210 LET nr=pr+dr: LET nc=pc+dc
 220 IF nr<1 OR nr>8 OR nc<1 OR nc>8 THEN GO TO 700
 230 LET v=g(nr,nc)
 240 IF v=1 THEN GO TO 700
 250 IF v=3 OR v=4 THEN GO TO 400
 260 GO TO 500
 400 LET br=nr+dr: LET bc=nc+dc
 410 IF br<1 OR br>8 OR bc<1 OR bc>8 THEN GO TO 700
 420 LET bv=g(br,bc)
 430 IF bv<>0 AND bv<>2 THEN GO TO 700
 440 LET g(nr,nc)=0
 450 IF v=4 THEN LET g(nr,nc)=2
 460 LET g(br,bc)=3
 470 IF bv=2 THEN LET g(br,bc)=4
 475 IF v=4 THEN LET left=left+1
 476 IF bv=2 THEN LET left=left-1
 480 LET r=br: LET c=bc: GO SUB 2000
 500 LET oldr=pr: LET oldc=pc
 510 LET pr=nr: LET pc=nc: LET moves=moves+1
 520 LET r=oldr: LET c=oldc: GO SUB 2000
 530 LET r=pr: LET c=pc: GO SUB 2000
 590 IF left=0 THEN LET won=1
 600 GO SUB 2500
 610 GO TO 110
 700 GO TO 110
1000 BORDER 0: PAPER 0: INK 7: CLS
1010 PRINT AT 0,2; INK 5;"CRATES";AT 0,24; INK 7;"ROOM 0";room
1020 PRINT AT 20,2; INK 7;"I up  J left  K down  L right"
1030 PRINT AT 21,6; INK 5;"R restart     Q quit";
1040 FOR r=1 TO 8: FOR c=1 TO 8
1050 GO SUB 2000
1060 NEXT c: NEXT r
1070 GO SUB 2500
1080 RETURN
2000 LET y=3 +2 *(r-1): LET x=8 +2 *(c-1)
2010 LET z=g(r,c)+1
2020 IF r=pr AND c=pc THEN LET z=6
2025 IF z=6 AND g(r,c)=2 THEN LET z=7
2030 PRINT AT y,x; INK a(z);t$(z,1 TO 2);AT y+1,x;t$(z,3 TO 4)
2040 RETURN
2500 PRINT AT 1,2; INK 7;"STEPS ";moves;"    "
2505 PRINT AT 1,18; INK 5;"GOALS ";total-left;"/";total
2510 IF won=1 THEN PRINT AT 19,2; INK 4;"Delivered! R replay / Q quit"
2540 RETURN
3000 LET k$=INKEY$
3010 IF k$=h$ THEN GO TO 3000
3020 LET h$=k$
3025 IF k$="" THEN GO TO 3000
3030 RETURN
5000 BORDER 0: PAPER 0: INK 7: CLS : LET h$=""
5010 PRINT AT 2,12; INK 5;"CRATES"
5020 PRINT AT 5,2; INK 7;"A small warehouse puzzle."
5030 PRINT AT 7,1;"I up, J left, K down, L right."
5040 PRINT AT 9,1;"Push crates onto the targets."
5050 PRINT AT 11,1;"You can push, but never pull."
5060 PRINT AT 13,1;"R restarts the room. Q quits."
5070 PRINT AT 15,1;"One step per press. Take time."
5080 PRINT AT 18,1;"S starts. Q quits."
5090 GO SUB 3000
5100 IF k$="q" OR k$="Q" THEN GO TO 9000
5110 IF k$<>"s" AND k$<>"S" THEN GO TO 5090
5120 RETURN
6000 LET left=0: LET total=0: FOR r=1 TO 8: FOR c=1 TO 8
6010 IF g(r,c)=2 THEN LET left=left+1
6015 IF g(r,c)=2 OR g(r,c)=4 THEN LET total=total+1
6020 NEXT c: NEXT r: RETURN
7000 RESTORE 7200: FOR n=0 TO 159: READ b: POKE USR "a"+n,b: NEXT n
7010 DIM t$(7,4): DIM a(7)
7020 LET t$(1)="    ": LET t$(2)=CHR$ 144 +CHR$ 145 +CHR$ 146 +CHR$ 147
7030 LET t$(3)=CHR$ 148 +CHR$ 149 +CHR$ 150 +CHR$ 151
7040 LET t$(4)=CHR$ 152 +CHR$ 153 +CHR$ 154 +CHR$ 155: LET t$(5)=t$(4)
7050 LET t$(6)=CHR$ 156 +CHR$ 157 +CHR$ 158 +CHR$ 159
7055 LET t$(7)=CHR$ 160 +CHR$ 161 +CHR$ 162 +CHR$ 163
7060 LET a(1)=0: LET a(2)=1: LET a(3)=5: LET a(4)=6: LET a(5)=4: LET a(6)=7: LET a(7)=5: RETURN
7200 DATA 0,254,129,129,129,129,129,0
7210 DATA 0,254,2,2,2,2,2,0
7220 DATA 127,64,64,64,64,64,127,0
7230 DATA 127,129,129,129,129,129,127,0
7240 DATA 0,0,0,3,12,8,16,17
7250 DATA 0,0,0,192,48,16,8,136
7260 DATA 17,16,8,12,3,0,0,0
7270 DATA 136,8,16,48,192,0,0,0
7280 DATA 0,127,64,95,88,84,82,81
7290 DATA 0,254,2,250,26,42,74,138
7300 DATA 81,82,84,88,95,64,127,0
7310 DATA 138,74,42,26,250,2,254,0
7320 DATA 3,7,7,3,1,15,31,27
7330 DATA 192,224,224,192,128,240,248,216
7340 DATA 27,3,3,7,6,6,14,0
7350 DATA 216,192,192,224,96,96,112,0
7360 DATA 3,7,7,3,13,15,31,27
7370 DATA 192,224,224,192,176,240,248,216
7380 DATA 27,19,11,15,7,6,14,0
7390 DATA 216,200,208,240,224,96,112,0
9000 PAPER 0: INK 7
9010 PRINT AT 21,0;"Finished. RUN to try again.     ";
9020 STOP

Line 10 now builds the graphics, then calls the instructions at 5000. That routine clears the remembered key, explains the controls and uses the same input routine to wait for S or Q. RETURN begins the room only after S.

After an accepted step, line 590 sets won = 1 when no targets remain uncovered. The status routine prints the delivery message. On later input, Q and R are handled before line 140 prevents further movement. Success therefore stops walking but still permits replay or exit.

won is a flag: zero means the room is active; one means it is complete. Restart already resets it at line 80, along with the player and step count. A held direction cannot act as R or Q, so completing a room cannot dismiss its own ending.

Room one completed with a delivered crate, GOALS 1/1 and a replay or quit message.
All targets are covered. Movement stops; R replays and Q leaves.

Run from the instructions. Try an unrelated key, then S. Solve the room, try another movement key, replay with R, and quit with Q. Also try Q directly from the instructions on another RUN. Each replay should restore the crate, player, zero steps and GOALS 0/1.

If the completion message appears but walking continues, check line 140. If replay leaves GOALS at 1/1, check that the call at 85 follows the room’s reconstruction. You now have a complete one-room game. The next work makes its room easier to describe and extend.

Sources

Steven Vickers, edited by Robin Bradbeer, ZX Spectrum BASIC Programming, second edition (Sinclair Research, 1983), chapters 4–5 (loops and control flow), 12 (arrays), and 18 (keyboard polling).

Run it here

This unit's program, built for you.

Program
step-02.tap
Machine
ZX Spectrum 48K (PAL)

Download step-02.tap