Maze generation: Difference between revisions

Content added Content deleted
m (→‎{{header|Icon}} and {{header|Unicon}}: more prep for solver, mark entrance/exit)
(→‎{{header|Icon}} and {{header|Unicon}}: updated in prep for solver, changed start/finish selection)
Line 1,047: Line 1,047:
mz := DisplayMaze(GenerateMaze(mh,mw))
mz := DisplayMaze(GenerateMaze(mh,mw))
WriteImage(mz.filename) # save file
WriteImage(mz.filename) # save file
WAttrib(mz.window,"canvas=normal") # show it
WAttrib(mz.window,"canvas=normal") # show maze in hidden window
Event() & close(mz.window) # done after any event
until Event() == &lpress # wait for left mouse press
close(mz.window)
end
end


$define SEEN 32 # bread crumbs for generator
$define FINISH 64 # exit
$define FOYER 16 # entrance and exit
$define START 32 # entrance
$define PATH 128
$define SEEN 16 # bread crumbs for generator
$define NORTH 8 # sides ...
$define NORTH 8 # sides ...
$define EAST 4
$define EAST 4
Line 1,062: Line 1,065:
static maze,h,w,rd
static maze,h,w,rd
if /maze then { # BEGING - No maze yet
if /maze then { # BEGING - No maze yet
/h := integer(0 < r) | runerr(r,205) # valid size ?
/h := integer(1 < r) | runerr(r,205) # valid size 2x2 or better
/w := integer(0 < c) | runerr(r,205)
/w := integer(1 < c) | runerr(r,205)
every !(maze := list(h)) := list(w,EMPTY) # shinny new empty maze
every !(maze := list(h)) := list(w,EMPTY) # shinny new empty maze
every 1 to 2 do { # two random openings ...
start := [?h,?w,?4-1,START] # random [r,c] start & finish
finish := [?h,?w,(start[3]+2)%4,FINISH] # w/ opposite side exponent
r := ?h # ... row,
c := ?w # ... col,
every x := start | finish do {
case 2 ^(?4 - 1) of { # ... side
case x[3] := 2 ^ x[3] of { # get side from exponent and
NORTH : maze[r := 1,c] +:= NORTH + FOYER
NORTH : x[1] := 1 # project r,c to selected edge
EAST : maze[r, c := w] +:= EAST + FOYER
EAST : x[2] := w
SOUTH : maze[r := h,c] +:= SOUTH + FOYER
SOUTH : x[1] := h
WEST : maze[r,c := 1] +:= WEST + FOYER
WEST : x[2] := 1
}
}
maze[x[1],x[2]] +:= x[3] + x[4] # transcribe s/f to maze
}
}
rd := [NORTH, EAST, SOUTH, WEST] # initial list of all directions
rd := [NORTH, EAST, SOUTH, WEST] # initial list of directions
GenerateMaze(r,c) # recurse through maze
GenerateMaze(start[1],start[2]) # recurse through maze
return 1(.maze,maze := &null) # return maze and reset for next
return 1(.maze,maze := &null) # return maze, reset for next
}
}
else { # ----------------------- recursed to clear insize of maze
else { # ----------------------- recursed to clear insize of maze
if iand(maze[r,c],SEEN) = 0 then { # in bounds and not SEEN yet ?
if iand(maze[r,c],SEEN) = 0 then { # in bounds and not SEEN yet?
maze[r,c] +:= SEEN # Mark the current cell as visited
maze[r,c] +:= SEEN # Mark current cell as visited
every !rd :=: ?rd # randomize list of directions
every !rd :=: ?rd # randomize list of directions
every d := !rd do
every d := !rd do
case d of { # try all, clearing wall on success
case d of { # try all, succeed & clear wall
NORTH : maze[r,c] +:= ( GenerateMaze(r-1,c), d)
NORTH : maze[r,c] +:= ( GenerateMaze(r-1,c), NORTH)
EAST : maze[r,c] +:= ( GenerateMaze(r,c+1), d)
EAST : maze[r,c] +:= ( GenerateMaze(r,c+1), EAST)
SOUTH : maze[r,c] +:= ( GenerateMaze(r+1,c), d)
SOUTH : maze[r,c] +:= ( GenerateMaze(r+1,c), SOUTH)
WEST : maze[r,c] +:= ( GenerateMaze(r,c-1), d)
WEST : maze[r,c] +:= ( GenerateMaze(r,c-1), WEST)
}
}
return # signal success to caller
return # signal success to caller
}
}
}
}
Line 1,129: Line 1,133:
return mazeinfo(&window,maze,sprintf("maze-%dx%d-%d.gif",r,c,&now))
return mazeinfo(&window,maze,sprintf("maze-%dx%d-%d.gif",r,c,&now))
end</lang>
end</lang>

Note: The underlying maze structure (matrix) is uni-directional from the start


{{libheader|Icon Programming Library}}
{{libheader|Icon Programming Library}}