Skip to content

Make room for a push

Check the space beyond a crate and add a way to restart.

  • Sinclair ZX Spectrum
  • BASIC

Walking needs one destination. Pushing needs two: the crate’s current square and the square beyond it. We must check both before moving anything.

Continue from the walking program. This version pushes onto plain floor only. Targets will become usable destinations once we teach the rule that preserves them.

Check beyond the crate

Replace lines 240, 1030.

Add lines 130, 250, 400, 410, 420, 430, 440, 460, 480.

step-01-edits.bas
 130 IF k$="r" OR k$="R" THEN GO TO 20
 240 IF v=1 THEN GO TO 700
 250 IF v=3 OR v=4 THEN GO TO 400
 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 THEN GO TO 700
 440 LET g(nr,nc)=0
 460 LET g(br,bc)=3
 480 LET r=br: LET c=bc: GO SUB 2000
1030 PRINT AT 21,6; INK 5;"R restart     Q quit";
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
 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 THEN GO TO 700
 440 LET g(nr,nc)=0
 460 LET g(br,bc)=3
 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 STOP

Line 240 now rejects only walls. Line 250 sends a crate to the push routine at 400; ordinary floor and targets still reach the walking code at 500. Code 4 is reserved for a crate on a target, which the next lesson will create.

br = nr + dr and bc = nc + dc step once more in the same direction. Line 410 checks those coordinates before line 420 reads the cell. Line 430 accepts only bv = 0, plain floor. Walls, targets and another crate all reject the push here.

Only then do lines 440 and 460 change the grid: the old crate cell becomes floor and the beyond cell becomes a crate. Line 480 redraws that destination. Execution continues into line 500, where the player moves into the crate’s former square. The existing redraws repair the player’s old cell and draw the player at the new one. One successful push counts as one step.

Why not erase the crate first, then check the square beyond it?

Show the explanation

If that square is blocked, the attempt must leave the crate where it was. Erasing first would create a partial move that we would have to undo. Checking first lets rejection leave every position unchanged.

Give a bad push an escape route

R returns to line 20. DIM recreates the grid, the original assignments fill it, and line 80 resets the player and count. We rebuild the starting room, rather than trying to reverse each move. The tile graphics need no rebuilding because they have not changed.

Run. From the starting position, press I, L, releasing between presses. The second step pushes the crate from (5,4) to (5,5). The player ends at (5,4) and STEPS reads 2. Press R: both return to their starting squares and STEPS returns to zero.

Now try I, L, K, L, I, I. The first upward push moves the crate to (4,5). The last I tries to push it onto the target at (3,5) and is rejected at this stage. The count stays at 5. R restores the room.

A crate against an outer wall can be impossible to recover because we cannot stand outside the warehouse to push it back. Restart makes that mistake recoverable without pretending it was an illegal move. If a rejected push makes a crate disappear, check that every rejection happens before line 440.

Sources

Steven Vickers, edited by Robin Bradbeer, ZX Spectrum BASIC Programming, second edition (Sinclair Research, 1983), chapters 5 (conditions and routines) and 12 (array access); the push and restart rules are choices made for this game.

Run it here

This unit's program, built for you.

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

Download step-01.tap