File: natmaze.xml

package info (click to toggle)
enigma 1.30%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 76,132 kB
  • sloc: xml: 162,251; cpp: 67,393; ansic: 28,606; makefile: 1,986; sh: 1,298; yacc: 288; perl: 84; sed: 16
file content (276 lines) | stat: -rw-r--r-- 7,699 bytes parent folder | download | duplicates (5)
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>