Maze generation: Difference between revisions
Content added Content deleted
Line 1,036: | Line 1,036: | ||
| | | | |
| | | | |
||
+---+---+---+---+---+---+---+---+---+---+---+ |
+---+---+---+---+---+---+---+---+---+---+---+ |
||
=={{header|Icon}} and {{header|Unicon}}== |
|||
<lang Icon>link printf |
|||
procedure main(A) # generate rows x col maze |
|||
/mh := \A[1] | 12 # or take defaults 12 x 16 |
|||
/mw := \A[2] | 16 |
|||
mz := DisplayMaze(GenerateMaze(mh,mw)) |
|||
WriteImage(mz.filename) # save file |
|||
WAttrib(mz.window,"canvas=normal") # show it |
|||
Event() & close(mz.window) # done after any event |
|||
end |
|||
$define SEEN 16 # bread crumbs for generator |
|||
$define NORTH 8 # sides ... |
|||
$define EAST 4 |
|||
$define SOUTH 2 |
|||
$define WEST 1 |
|||
$define EMPTY 0 |
|||
procedure GenerateMaze(r,c) #: Depth First Maze Generation |
|||
static maze,h,w,rd |
|||
if /maze then { # BEGING - No maze yet |
|||
/h := integer(0 < r) | runerr(r,205) # valid size ? |
|||
/w := integer(0 < c) | runerr(r,205) |
|||
every !(maze := list(h)) := list(w,EMPTY) # shinny new empty maze |
|||
r := ?h # choose random row, |
|||
c := ?w # ... col, and |
|||
case 2 ^(?4 - 1) of { # ... side for openings |
|||
NORTH : { |
|||
maze[r := 1,c] +:= NORTH |
|||
maze[h,w-c+1] +:= SOUTH |
|||
} |
|||
EAST : { |
|||
maze[r, c := w] +:= EAST |
|||
maze[h-r+1,1] +:= WEST |
|||
} |
|||
SOUTH : { |
|||
maze[r := h,c] +:= SOUTH |
|||
maze[1,w-c+1] +:= NORTH |
|||
} |
|||
WEST : { |
|||
maze[r,c := 1] +:= WEST |
|||
maze[h-r+1,w] +:= EAST |
|||
} |
|||
} |
|||
rd := [NORTH, EAST, SOUTH, WEST] # initial list of all directions |
|||
GenerateMaze(r,c) # recurse through maze |
|||
return 1(.maze,maze := &null) # return maze and reset for next |
|||
} |
|||
else { # ----------------------- recursed to clear insize of maze |
|||
if iand(maze[r,c],SEEN) = 0 then { # in bounds and not SEEN yet ? |
|||
maze[r,c] +:= SEEN # Mark the current cell as visited |
|||
every !rd :=: ?rd # randomize list of directions |
|||
every d := !rd do |
|||
case d of { # try all, clearing wall on success |
|||
NORTH : maze[r,c] +:= ( GenerateMaze(r-1,c), NORTH) |
|||
EAST : maze[r,c] +:= ( GenerateMaze(r,c+1), EAST) |
|||
SOUTH : maze[r,c] +:= ( GenerateMaze(r+1,c), SOUTH) |
|||
WEST : maze[r,c] +:= ( GenerateMaze(r,c-1), WEST) |
|||
} |
|||
return # signal success to caller |
|||
} |
|||
} |
|||
end |
|||
$define CELL 20 # cell size in pixels |
|||
$define BORDER 30 # border size in pixels |
|||
record mazeinfo(window,maze,filename) # keepers |
|||
procedure DisplayMaze(maze) #: show it off |
|||
if CELL < 8 then runerr(205,CELL) # too small |
|||
wh := (ch := (mh := *maze ) * CELL) + 2 * BORDER # win, cell, maze height |
|||
ww := (cw := (mw := *maze[1]) * CELL) + 2 * BORDER # win, cell, maze width |
|||
wparms := [ "Maze","g","bg=white","canvas=hidden", |
|||
sprintf("size=%d,%d",ww,wh), |
|||
sprintf("dx=%d",BORDER), |
|||
sprintf("dy=%d",BORDER)] |
|||
&window := open!wparms | stop("Unable to open Window") |
|||
Fg("black") # Draw full grid |
|||
every DrawLine(x := 0 to cw by CELL,0,x,ch+1) # . verticals |
|||
every DrawLine(0,y := 0 to ch by CELL,cw+1,y) # . horizontals |
|||
Fg("white") # Set to erase lines |
|||
every y := CELL*((r := 1 to mh)-1) & x := CELL*((c := 1 to mw)-1) do { |
|||
WAttrib("dx="||x+BORDER,"dy="||y+BORDER) # position @ cell r,c |
|||
if iand(maze[r,c],NORTH) > 0 then DrawLine(2,0,CELL-1,0) |
|||
if iand(maze[r,c],EAST) > 0 then DrawLine(CELL,2,CELL,CELL-1) |
|||
if iand(maze[r,c],SOUTH) > 0 then DrawLine(2,CELL,CELL-1,CELL) |
|||
if iand(maze[r,c],WEST) > 0 then DrawLine(0,2,0,CELL-1) |
|||
} |
|||
return mazeinfo(&window,maze,sprintf("maze-%dx%d-%d.gif",r,c,&now)) |
|||
end</lang> |
|||
{{libheader|Icon Programming Library}} |
|||
[http://www.cs.arizona.edu/icon/library/src/procs/printf.icn printf.icn provides formatting] |
|||
=={{header|J}}== |
=={{header|J}}== |