A downloadable game

Instructions:

You are a warehouse worker im a warehouse. You need to push the crates onto their final positions as indicated by the dots.

You can only push crates, not pull them. You can only push one crate at a time. This version has 4 levels.


If you have managed to solve a level then try to do it in the minimum number of moves possible and if you have done that, then try to solve it in the minimum number of pushes possible instead.

Keys:

Cursor keys

Copy (note that the Copy key is mapped to the End key in JSBeeb) to restart the current level.

Variables used:

A% - current level. A% is used as it is not cleared when the program is rerun. Also, as a cheat, if you get stuck on a level, pressing Escape and then rerunning the program will put you onto the next level.

m - one less than the number of rows in the level

l - one less than the number in columns in the level

g(m,l) - the level data array

a,b,r - general purpose variables

x,y - x and y coordinates of worker

z - number of moves made

w - number of pushes made

c - number of crates not on dots (the level has been completed when this is zero)

k - key pressed

p - set when a move has been made. -1 = moving into a blank space, 3 = pushing a crate, 0 = not a valid move

Level data:

0 - blank space

1 - dot

2 - crate

3 - crate on dot

4 - worker

5 - worker on dot

6 - wall

The level data is stored in lines 80 to 100 (lines 800 to 1000 in the expanded version). As the 7 "building blocks" as listed above only require 3 bits to store them (i.e. 000 to 110), 2 "building blocks" are stored in each character.

Program structure (referring to the expanded version):

lines 100 to 310 initialisation

lines 311 to 703 main game loop

lines 704 to 705 level completed, go to next level

line 706 colour data and graphics data

line 800 level data (start address of data for each level and the number of rows and columns for each level)

lines 801 to 1000 level data

Expanded listing with comments:
level = 1 to 4
100A%=(A%AND3)+1
get a (start address), l (number of rows) and m (number of columns) for current level
101FORi=1TOA%
102READa,l,m
103NEXT
104DIMg(m,l)
define graphics characters
105FORi=&C04TO&C37
106?i=(i?&F82-32)*3
107NEXT
108MODE1
disable cursor
109VDU23,1,0;0;0;0;
disable cursor keys for editing
110*FX4,1
define top half of blank space character
200!&C00=0
set print width to 5
201@%=5
read/decode the level data and display the level
202b=0
203c=0
204FORj=0TOm
205FORi=0TOl
206r=(?a-32)DIV8^b MOD8
207g(j,i)=r
VDU17 sets the colour
208VDU17,r?&1B7F-48,224+r
set x and y coordinates of worker
209IF(r AND6)=4THENx=i:y=j
set number of crates not on dots
300c=c-(r=2)
301a=a+b
skip to next line if level data is split across 2 lines
302a=a-(?a=13)*5
303b=1-b
304NEXT
305PRINT
306NEXT
307COLOUR3
display level number, number of moves (0) and number of pushes (0)
308PRINTA%,0,0
set number of moves and number of pushes to zero
309z=0
310w=0
311REPEAT
312k=GET-135
if key press was invalid then try again
313IFk<0ORk>4THENUNTIL0
400r=ASC(MID$("DCEGA",k+1,1))-64
401b=r DIV3-1
402a=r MOD3-1
look at what lies in the direction that we are going
403r=g(y+b,x+a)AND6
404p=(r=0)
if it's a blank space/dot or a crate with a blank space/dot on the other side of it then it's a valid move
405IFr=2THENIF(g(y+b*2,x+a*2)AND6)=0THENp=3
if not a valid move then try again unless Copy key was pressed in which case restart current level
500IFp=0THENUNTILk=0:A%=A%-1:RUN
valid move so increment move count
501z=z+1
also increment push count if a push was made
502w=w-(p=3)
make move
move worker off current position
503g(y,x)=g(y,x)AND1
504x=x+a
505y=y+b
increment c if crate was pushed off a dot
506c=c-(g(y,x)=p)
move worker to new position
507g(y,x)=g(y,x)AND1OR4
also move crate to new position if pushing one
600g(y+b,x+a)=g(y+b,x+a)ORr
decrement c if crate was pushed onto a dot
601c=c+(g(y+b,x+a)=p)
redisplay "local" blocks affected by move
602FORr=-1TO1
603VDU31,x+a*r,y+b*r,17,g(y+b*r,x+a*r)?&1B7F-48,224+g(y+b*r,x+a*r)
700NEXT
701COLOUR3
display level number, number of moves and number of pushes
702PRINTTAB(0,m+1),A%,z,w
703UNTILc=0
level completed, go to next level after a key press
704k=GET
705RUN
1st 7 characters after the REM are the colours of the blocks. Rest of line is the graphics data
706REM2323221       ((   uKSWWSKuuKS__SKu4JiuuaJ44JiuuaJ4mmm JJJ 
start address, number of rows and number of columns for each level
800DATA&1BF2,13,09,&1C3D,11,10,&1C7F,14,11,&1CDE,10,10
level data
801REMVVVVVV .!P  PV.!P0 "P.!PRV&P.! @P&P.!PP "VVVVP60P &"000P & P  
900REMP VVVVVVVVV V&.!PPFV.!PV P.!  2P.!PP0P.QVP0PVV0P"P P R0P P0 "P P V P PVVVVPVVV    &P VV& V &P)QVP R .) &&"6")!PP R
1000REM .)(&& &RVVVV6   00PV &0"& &VVV V2T   &  P&  PVVV&   VVPVVV@&&  "PP 0V0&VR)QP &*) &PP!QP&& &6PP"0  &&PVVVPV&   

Download

Download
SOKOBAN.txt 1 kB
Download
SOKOBAN120.txt 1 kB
Download
Sokoban (instructions).txt 5 kB

Install instructions

The emulator that I use is an online one - JSBeeb. https://bbc.godbolt.org/

Simply copy and paste the program into it and type RUN.

The program assumes that PAGE (the start of the program) is set to &1900 which is the default in JSBeeb.

Leave a comment

Log in with itch.io to leave a comment.