'sokoban.bas
'644 lines (566 sloc) 13.7 KB
'
' $Id$
'
option predef grmode 700x500
const bl_w = 25
const bl_h = 25
const bl_x = 45
const bl_y = 45
'
' draw the game boundary
'
sub draw_walls(x, y)
local px = bl_x + (x * bl_w)
local py = bl_y + (y * bl_h)
rect px, py, step bl_w, bl_h, 1 filled
rect px, py, step bl_w, bl_h, 2
end
'
' draw the block target
'
sub draw_target(x, y)
local px = bl_x + (x * bl_w)
local py = bl_y + (y * bl_h)
rect px, py, step bl_w, bl_h, 3 filled
rect px, py, step bl_w, bl_h, 4
end
'
' draw the movable block
'
sub draw_block(x, y)
local px = bl_x + (x * bl_w) + 1
local py = bl_y + (y * bl_h) + 1
rect px, py, step bl_w - 1, bl_h - 1, 5 filled
rect px, py, step bl_w - 2, bl_h - 2, 6
end
'
' draw the empty space within the grid
'
sub draw_space(x, y)
local px = bl_x + (x * bl_w) + 1
local py = bl_y + (y * bl_h) + 1
rect px, py, step bl_w - 1, bl_h - 1, 8 filled
end
'
' draw the sokoban man
'
sub draw_soko(x, y, direction)
local bx = bl_x + (x * bl_w)
local by = bl_y + (y * bl_h)
local dx, dy, PolyArray
dx = bl_w / 5
dy = bl_w / 5
PolyArray = [[3 * dx, 1 * dy], &
[5 * dx, 2 * dy], &
[4 * dx, 2 * dy], &
[4 * dx, 4 * dy], &
[3 * dx, 3 * dy], &
[2 * dx, 4 * dy], &
[2 * dx, 2 * dy], &
[1 * dx, 2 * dy], &
[3 * dx, 1 * dy]]
DrawPoly PolyArray, bx, by Color 9 filled
Circle dx * 3 + bx, by + 5, 3 color 9 filled
end
'
' show the game status
'
sub game_status(byref game)
local help, num_over
' count the number of blocks over the targts
local bl_len = len(game.blocks) - 1
num_over = 0
for i = 0 to bl_len
local block = game.blocks(i)
local x = block(0)
local y = block(1)
if (mid(game.grid(y), x, 1) == ".") then
num_over++
fi
next i
if (num_over == bl_len + 1) then
local y_loc = 5 + txth("T")
for i = 0 to 10
at 10, y_loc
if (i mod 2 == 0) then
? "*** GAME OVER ***"
else
? spc(20)
fi
delay 300
next i
game.game_over = true
fi
color 1,8
help = " [e]=exit, [u]=undo"
at 10, 5: ? cat(1); "Moves: "; game.moves; " Pushes: "; game.pushes; cat(-1); help ; spc(20)
end
'
' whether there is a block at the x/y location
'
func get_block(byref blocks, x, y)
local i
local result = false
local bl_len = len(game.blocks) - 1
for i = 0 to bl_len
local block = game.blocks(i)
if (block(0) = x && block(1) = y) then
result = true
i = bl_len
fi
next i
get_block = result
end
'
' draw the game board
'
sub init_game(grid, byref game)
local row, col, row_len, x, y, ch
dim blocks
' cls
rect 0, 0, xmax, ymax, 8 filled
erase game
y = 0
for row in grid
row_len = len(row)
for x = 1 to row_len
ch = mid(row, x, 1)
select case ch
case "#"' ' border
draw_walls x, y
case "@" ' sokoban man
draw_soko x, y, 1
game.soko_x = x
game.soko_y = y
case "." ' block target
draw_target x, y
case "$" ' moveable block
draw_block x, y
blocks