A crate can cover a target, but the target must still exist when the crate leaves. We need a stored state for both things occupying the same square.
Continue from the floor-only pushing program. We will add 4: crate on target to the world codes.
Trace the two cells
Before changing the source, trace what a push must leave behind and put ahead:
| Crate starts on | Destination underneath | Old cell after push | New cell after push |
|---|---|---|---|
| Floor (3) | Floor (0) | Floor (0) | Crate (3) |
| Floor (3) | Target (2) | Floor (0) | Crate on target (4) |
| Target (4) | Floor (0) | Target (2) | Crate (3) |
| Target (4) | Target (2) | Target (2) | Crate on target (4) |
v remembers the crate’s old state; bv remembers the destination. We read them before changing either cell, so both facts remain available during the update.
Replace line 430.
Add lines 450, 470.
430 IF bv<>0 AND bv<>2 THEN GO TO 700
450 IF v=4 THEN LET g(nr,nc)=2
470 IF bv=2 THEN LET g(br,bc)=4Complete program for this step
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
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
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;" "
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
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 STOPLine 430 now accepts either floor or target. Line 440 still clears the old crate cell to floor, but 450 restores a target when v = 4. Likewise, line 460 places a normal crate, then 470 chooses crate-on-target when bv = 2.
The drawing routine already maps code 4 to appearance 5: the wooden crate in green. The player stands in the old crate square, with its target ring if one was uncovered. No changes to the pixel data are needed.
When a crate moves from one target to another, how many targets does the room contain afterwards?
Show the explanation
The same number as before. The old cell becomes an uncovered target, and the destination becomes a crate on a target. Codes 2 and 4 both contain a target, even though only one shows an empty ring.
Deliver it, then move it again
Run and try I, L, K, L, I, I from the start. The final push now succeeds: the crate reaches (3,5) and changes colour. There is no victory message yet; we are checking target preservation while movement remains available.
To push it off again, continue L, I, I, J, K. You walk round to (2,5) and push down. The crate moves to (4,5), while the player stands on the uncovered target at (3,5). Step right with L and the empty ring becomes visible. Press R to restore the room.
If a target vanishes, check line 450 and the remembered v. If a delivered crate stays yellow, inspect the new cell code and line 470 before changing its colour. Crates and targets must each keep their total count through every push; only their positions and coverage change.
Sources
Steven Vickers, edited by Robin Bradbeer, ZX Spectrum BASIC Programming, second edition (Sinclair Research, 1983), chapters 5 and 12 (conditions and arrays), and 14–16 (character graphics and colour).
Run it here
This unit's program, built for you.
- Program
- step-01.tap
- Machine
- ZX Spectrum 48K (PAL)