01-28-2026, 05:49 AM
(This post was last modified: 01-28-2026, 05:50 AM by 1micha.elok.)
SIMPLE SOKOBAN
How to Play:
-Use arrow keys to move the player
-Push crates (blue boxes) onto targets (yellow boxes)
-All crates must be on targets to win
-Press R to restart the level
-Press ESC to quit
Reference :
move one tile at a time by Marcus
https://www.naalaa.com/forum/thread-355-...ml#pid2359
How to Play:
-Use arrow keys to move the player
-Push crates (blue boxes) onto targets (yellow boxes)
-All crates must be on targets to win
-Press R to restart the level
-Press ESC to quit
Reference :
move one tile at a time by Marcus
https://www.naalaa.com/forum/thread-355-...ml#pid2359
Code:
'===============================================================
' SIMPLE SOKOBAN
'
' How to Play:
' -Use arrow keys to move the player
' -Push crates (blue boxes) onto targets (yellow boxes)
' -All crates must be on targets to win
' -Press R to restart the level
' -Press ESC to quit
'
' Reference :
' move one tile at a time by Marcus
' https://www.naalaa.com/forum/thread-355-post-2359.html#pid2359
'================================================================
set window "Simple Sokoban", 256, 240, false, 3
set redraw off
' Map legend:
' 0 = empty floor
' 1 = wall
' 2 = player start
' 3 = box/crate
' 4 = target/goal
' 5 = box on target
' 6 = player on target
map = [
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 0, 0, 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1],
[1, 0, 0, 1, 0, 0, 3, 0, 0, 0, 0, 0, 1, 1, 0, 1],
[1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1],
[1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
[1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
[1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 0, 0, 0, 0, 1],
[1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
[1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1],
[1, 0, 1, 0, 3, 0, 0, 0, 0, 4, 1, 0, 0, 0, 0, 1],
[1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1],
[1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1],
[1, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 4, 1, 0, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]
' Backup for restart functionality - using simple copy
mapBackup = []
for y = 0 to sizeof(map) - 1
mapBackup[y] = copy(map[y])
next
' Width and height of map
mapHeight = sizeof(map)
mapWidth = sizeof(map[0])
' Find player starting position
playerX = unset
playerY = unset
for y = 0 to mapHeight - 1
for x = 0 to mapWidth - 1
if map[y][x] = 2
playerY = y
playerX = x
map[y][x] = 0
break
endif
next
next
' Count targets for win condition
targetCount = 0
for y = 0 to mapHeight - 1
for x = 0 to mapWidth - 1
if map[y][x] = 4 or map[y][x] = 5
targetCount = targetCount + 1
endif
next
next
' Game state
gameWon = false
showWinMessage = 0
' Movement animation state
playerScreenX = playerX * 16
playerScreenY = playerY * 16
playerDX = 0
playerDY = 0
playerSteps = 0
boxMoveX = 0
boxMoveY = 0
boxSteps = 0
boxStartX = 0
boxStartY = 0
boxDestX = 0
boxDestY = 0
' Main game loop
while not keydown(KEY_ESCAPE, true)
' Handle restart
if keydown(KEY_R, true)
' Restore map from backup using simple copy
for y = 0 to mapHeight - 1
map[y] = copy(mapBackup[y])
next
gameWon = false
showWinMessage = 0
' Reset player position
for y = 0 to mapHeight - 1
for x = 0 to mapWidth - 1
if map[y][x] = 2
playerY = y
playerX = x
map[y][x] = 0
break
endif
next
next
playerScreenX = playerX * 16
playerScreenY = playerY * 16
playerSteps = 0
boxSteps = 0
endif
' Only accept input when no animation is playing
if playerSteps = 0 and boxSteps = 0 and not gameWon
dx = 0
dy = 0
' Check for arrow keys
if keydown(KEY_LEFT) then dx = -1
elseif keydown(KEY_RIGHT) then dx = 1
elseif keydown(KEY_UP) then dy = -1
elseif keydown(KEY_DOWN) then dy = 1
if dx or dy
' Calculate next positions
nextX = playerX + dx
nextY = playerY + dy
beyondX = playerX + dx * 2
beyondY = playerY + dy * 2
' Check bounds
if nextX >= 0 and nextX < mapWidth and nextY >= 0 and nextY < mapHeight
' What's in the next cell?
nextCell = map[nextY][nextX]
' Can walk onto empty floor or target
if nextCell = 0 or nextCell = 4
playerDX = dx * 16
playerDY = dy * 16
playerSteps = 16
' Can push a box if space beyond is empty/target
elseif nextCell = 3 or nextCell = 5
if beyondX >= 0 and beyondX < mapWidth and beyondY >= 0 and beyondY < mapHeight
beyondCell = map[beyondY][beyondX]
if beyondCell = 0 or beyondCell = 4
' Start player movement
playerDX = dx * 16
playerDY = dy * 16
playerSteps = 16
' Start box movement
boxMoveX = nextX * 16
boxMoveY = nextY * 16
boxStartX = nextX
boxStartY = nextY
boxDestX = beyondX
boxDestY = beyondY
boxSteps = 16
' Update map: remove box from current position
if nextCell = 3 then map[nextY][nextX] = 0
elseif nextCell = 5 then map[nextY][nextX] = 4
endif
endif
endif
endif
endif
endif
' Animate player
if playerSteps > 0
playerSteps = playerSteps - 1
playerScreenX = playerScreenX + playerDX / 16
playerScreenY = playerScreenY + playerDY / 16
if playerSteps = 0
' Snap to grid and update logical position
playerX = playerScreenX / 16
playerY = playerScreenY / 16
' Handle player standing on target
if map[playerY][playerX] = 4
map[playerY][playerX] = 6 ' Player on target
endif
endif
endif
' Animate box
if boxSteps > 0
boxSteps = boxSteps - 1
boxMoveX = boxMoveX + playerDX / 16
boxMoveY = boxMoveY + playerDY / 16
if boxSteps = 0
' Place box in new position
if map[boxDestY][boxDestX] = 4
map[boxDestY][boxDestX] = 5 ' Box on target
else
map[boxDestY][boxDestX] = 3 ' Box on floor
endif
' Check win condition
boxesOnTarget = 0
for y = 0 to mapHeight - 1
for x = 0 to mapWidth - 1
if map[y][x] = 5 then boxesOnTarget = boxesOnTarget + 1
next
next
if boxesOnTarget = targetCount
gameWon = true
showWinMessage = 120 ' Show for 2 seconds (120 frames at 60fps)
endif
endif
endif
' Drawing
set color 20, 20, 30 ' Dark background
cls
' Draw targets (empty goals)
set color 255, 220, 0
for y = 0 to mapHeight - 1
for x = 0 to mapWidth - 1
cell = map[y][x]
if cell = 4 or cell = 5 or cell = 6
draw rect x*16, y*16, 16, 16
endif
next
next
' Draw walls
set color 96, 64, 32
for y = 0 to mapHeight - 1
for x = 0 to mapWidth - 1
if map[y][x] = 1
draw rect x*16, y*16, 16, 16, true
endif
next
next
' Draw boxes
set color 0, 0, 255
for y = 0 to mapHeight - 1
for x = 0 to mapWidth - 1
if map[y][x] = 3 or map[y][x] = 5
draw rect x*16 + 2, y*16 + 2, 12, 12, true
endif
next
next
' Draw moving box during animation
if boxSteps > 0
set color 160, 100, 60
draw rect boxMoveX + 2, boxMoveY + 2, 12, 12, true
set color 130, 70, 40
draw rect boxMoveX + 4, boxMoveY + 4, 8, 8, false
endif
' Draw player
set color 32, 200, 64
draw rect playerScreenX + 2, playerScreenY + 2, 12, 12, true
' Draw win message
if gameWon
set color 0, 0, 0, 180
draw rect 40, 90, 176, 60, true
set color 255, 255, 100
set caret 128, 100
center "LEVEL COMPLETE!"
set color 200, 200, 200
set caret 128, 120
center "Press R to restart"
if showWinMessage > 0
showWinMessage = showWinMessage - 1
endif
endif
redraw
fwait 60
wend
