Sokoban 120 by David Payne
A downloadable game
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.
Copy (note that the Copy key is mapped to the End key in JSBeeb) to restart the current level.
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
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&
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.