1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276
|
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<el:level xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://enigma-game.org/schema/level/1 level.xsd" xmlns:el="http://enigma-game.org/schema/level/1">
<el:protected>
<el:info el:type="library">
<el:identity el:title="" el:id="lib/natmaze"/>
<el:version el:score="1" el:release="1" el:revision="1" el:status="released"/>
<el:author el:name="Nat Pryce" el:email="" el:homepage=""/>
<el:copyright>Copyright © 2002 Nat Pryce</el:copyright>
<el:license el:type="GPL v2.0 or above" el:open="true"/>
<el:compatibility el:enigma="0.92">
</el:compatibility>
<el:modes el:easy="false" el:single="false" el:network="false"/>
<el:comments>
<el:code>Lua 5.1 and XML converted by Leveladministrators</el:code>
</el:comments>
<el:score el:easy="-" el:difficult="-"/>
</el:info>
<el:luamain><![CDATA[
-- Maze module: maze generator and renderer for Enigma
--
function remove_random_element( tab )
return table.remove(tab, random(1, #tab))
end
function random_element( tab )
return tab[random(1, #tab)]
end
-------------------------------------------------------------------------------
-- Maze objects
-- These constants conflict with those defined in init.lua; commented
-- them out for now (dh).
-- NORTH = 1
-- SOUTH = 2
-- WEST = 3
-- EAST = 4
function maze_coords_to_cell( maze, x, y )
return y*maze.width + x
end
function maze_can_go_south( maze, x, y )
return y < (maze.height-1) and maze.linky[maze_coords_to_cell(maze,x,y)]
end
function maze_can_go_north( maze, x, y )
return y > 0 and maze_can_go_south(maze,x,y-1)
end
function maze_can_go_east( maze, x, y )
return x < (maze.width-1) and maze.linkx[maze_coords_to_cell(maze,x,y)]
end
function maze_can_go_west( maze, x, y )
return x > 0 and maze_can_go_east( maze, x-1, y )
end
function maze_link_south( maze, x, y )
assert( maze_contains_cell( maze, x, y+1 ) )
maze.linky[maze_coords_to_cell(maze,x,y)] = 1
end
function maze_link_north( maze, x, y )
assert( maze_contains_cell( maze, x, y-1 ) )
maze_link_south( maze, x, y-1 )
end
function maze_link_east( maze, x, y )
assert( maze_contains_cell( maze, x+1, y ) )
maze.linkx[maze_coords_to_cell(maze,x,y)] = 1
end
function maze_link_west( maze, x, y )
assert( maze_contains_cell( maze, x-1, y ) )
maze_link_east( maze, x-1, y )
end
function maze_contains_cell( maze, x, y )
return x >= 0 and x < maze.width and y >= 0 and y < maze.height
end
function new_maze( width, height )
local maze = {}
maze.width = width
maze.height = height
maze.linkx = {}
maze.linky = {}
maze.contains_cell = maze_contains_cell
maze.coords_to_cell = maze_coords_to_cell
maze.can_go_north = maze_can_go_north
maze.can_go_south = maze_can_go_south
maze.can_go_west = maze_can_go_west
maze.can_go_east = maze_can_go_east
maze.link_north = maze_link_north
maze.link_south = maze_link_south
maze.link_west = maze_link_west
maze.link_east = maze_link_east
return maze
end
-------------------------------------------------------------------------------
-- Maze generator based on Kruskal's minimum spanning tree algorithm
function new_kruskal_maze( width, height )
local maze = new_maze(width,height)
local walls = maze_walls( maze )
local zones = {}
local zone_count = width*height
while zone_count > 1 do
wall = remove_random_element( walls )
local x1 = wall.cellx
local y1 = wall.celly
local x2, y2
if wall.side == SOUTH then
x2 = wall.cellx
y2 = wall.celly+1
else -- wall.side == EAST
x2 = wall.cellx+1
y2 = wall.celly
end
cell1 = maze:coords_to_cell(x1,y1)
cell2 = maze:coords_to_cell(x2,y2)
zone1 = find_zone( zones, cell1 )
zone2 = find_zone( zones, cell2 )
if zone1 ~= zone2 then
if wall.side == SOUTH then
maze:link_south( x1, y1 )
else -- wall.side == EAST
maze:link_east( x1, y1 )
end
union_zones( zones, cell1, cell2 )
zone_count = zone_count - 1
end
end
return maze
end
function maze_walls( maze )
walls = {}
for y = 0, maze.height-1 do
for x = 0, maze.width-1 do
if y < maze.height-1 then
table.insert( walls, {cellx=x,celly=y,side=SOUTH} )
end
if x < maze.width-1 then
table.insert( walls, {cellx=x,celly=y,side=EAST} )
end
end
end
return walls
end
-- Union-find algorithm for merging "zones" of the maze. Each zone is
-- a tree of cells identified by the cell at the root of the tree. A root
-- cell is represented by a nil reference in the zones table indexed by the
-- cell number.
function find_zone( zones, cell )
if zones[cell] == nil then
return cell
else
zones[cell] = find_zone( zones, zones[cell] )
return zones[cell]
end
end
function union_zones( zones, cell1, cell2 )
zones[find_zone(zones,cell2)] = find_zone(zones,cell1)
end
-------------------------------------------------------------------------------
-- Maze renderers
function render_maze( maze, cell_renderer )
for cellx = 0, maze.width-1 do
for celly = 0, maze.height-1 do
cell_renderer( maze, cellx, celly )
end
end
end
function tight_maze( maze, maze_floor, wall_floor, wall_stone )
local originx = 1
local originy = 1
function cell_to_level( cellx, celly )
return originx + cellx * 2, originy + celly * 2
end
function draw_maze_border( maze, stone )
width = maze.width*2
height = maze.height*2
draw_stones( stone, {0,0}, {1,0}, width )
draw_stones( stone, {0,height-1},{1,0}, width )
draw_stones( stone, {0,0}, {0,1}, height )
draw_stones( stone, {width-1,0},{0,1}, height )
end
function render_cell( maze, cellx, celly )
local x, y = cell_to_level( cellx, celly )
if wall_stone then
set_stone( wall_stone, x+1, y+1 )
end
if maze_floor then
set_floor( maze_floor, x, y )
end
if maze:can_go_south(cellx,celly) then
if maze_floor then
set_floor( maze_floor, x, y+1 )
end
else
if wall_stone then
set_stone( wall_stone, x, y+1 )
end
end
if maze:can_go_east(cellx,celly) then
if maze_floor then
set_floor( maze_floor, x+1, y )
end
else
if wall_stone then
set_stone( wall_stone, x+1, y )
end
end
end
create_world( maze.width*2 + 1, maze.height*2 + 1 )
if wall_stone then
draw_border( wall_stone )
end
if wall_floor then
fill_floor( wall_floor)
else
fill_floor( maze_floor)
end
render_maze( maze, render_cell )
oxyd(1,0)
oxyd(2*maze.width-1,2*maze.height)
oxyd(1,2*maze.height)
oxyd(2*maze.width-1,0)
local actorx, actory = cell_to_level( random(maze.width)-1,
random(maze.height)-1 )
set_actor( "ac-blackball", actorx + 0.5, actory + 0.5,
{ player=0 } )
end
]]></el:luamain>
<el:i18n>
</el:i18n>
</el:protected>
</el:level>
|