Maze generation: Difference between revisions

→‎{{header|PicoLisp}}: Added PureBasic
(→‎{{header|PicoLisp}}: Added PureBasic)
Line 848:
+---+---+---+---+---+---+---+---+---+---+---+
a b c d e f g h i j k</pre>
=={{header|PureBasic}}==
<lang PureBasic>Enumeration
;types of offsets
#visited
#maze
#wall
;direction indexes
#dir_N = 0
#dir_E
#dir_S
#dir_W
#dir_ID ;identity value, produces no changes
#dirMax
EndEnumeration
 
DataSection
;maze(x,y) offsets for visited, maze, & walls for each direction
Data.i 1, 0, 0, -1, 0, 0 ;N
Data.i 2, 1, 1, 0, 1, 0 ;E
Data.i 1, 2, 0, 1, 0, 1 ;S
Data.i 0, 1, -1, 0, 0, 0 ;W
Data.i 1, 1, 0, 0, 0, 0 ;ID
Data.i %01, %10, %01, %10, %00 ;wall values for N, E, S, W, ID
EndDataSection
 
;setup reference values indexed by direction from current map cell
Global Dim offset.POINT(2, #dirMax)
Define i, j
For i = #dir_N To #dir_ID
For j = 0 To 2
Read.i offset(j, i)\x: Read.i offset(j, i)\y
Next
Next
 
Global Dim wallvalue(#dirMax)
For i = #dir_N To #dir_ID: Read.i wallvalue(i): Next
 
Procedure displayMaze(Array maze(2))
Protected x, y, vWall.s, hWall.s
Protected mazeWidth = ArraySize(maze(), 1), mazeHeight = ArraySize(maze(), 2)
 
For y = 0 To mazeHeight
vWall = "": hWall = ""
For x = 0 To mazeWidth
If maze(x, y) & wallvalue(#dir_N): vWall + "+ ": Else: vWall + "+---": EndIf
If maze(x, y) & wallvalue(#dir_W): hWall + " ": Else: hWall + "| ": EndIf
Next
PrintN(Left(vWall, Len(vWall) - 3))
If y <> mazeHeight: PrintN(hWall): EndIf
Next
EndProcedure
 
Procedure generateMaze(Array maze(2), mazeWidth, mazeHeight)
Dim maze(mazeWidth, mazeHeight) ;includes an extra row and column for the SE corner
Dim visited(mazeWidth + 1, mazeHeight + 1) ;includes padding for easy border detection
Protected i
;mark outside border as already visited (off limits)
For i = 1 To mazeWidth
visited(i, 0) = #True: visited(i, mazeHeight + 1) = #True
Next
For i = 1 To mazeHeight
visited(0, i) = #True: visited(mazeWidth + 1, i) = #True
Next
 
;generate maze
Protected x = Random(mazeWidth - 1), y = Random (mazeHeight - 1), cellCount, nextCell
visited(x + offset(#visited, #dir_ID)\x, y + offset(#visited, #dir_ID)\y) = #True
PrintN("Started generation at " + Str(x) + " x " + Str(y))
NewList stack.POINT()
Dim unvisited(#dirMax - 1)
Repeat
cellCount = 0
For i = #dir_N To #dir_W
If Not visited(x + offset(#visited, i)\x, y + offset(#visited, i)\y)
unvisited(cellCount) = i: cellCount + 1
EndIf
Next
If cellCount
nextCell = unvisited(Random(cellCount - 1))
visited(x + offset(#visited, nextCell)\x, y + offset(#visited, nextCell)\y) = #True
maze(x + offset(#wall, nextCell)\x, y + offset(#wall, nextCell)\y) | wallvalue(nextCell)
 
If cellCount > 1
AddElement(stack())
stack()\x = x: stack()\y = y
EndIf
x + offset(#maze, nextCell)\x: y + offset(#maze, nextCell)\y
ElseIf ListSize(stack()) > 0
x = stack()\x: y = stack()\y
DeleteElement(stack())
Else
Break ;end maze generation
EndIf
ForEver
 
ProcedureReturn
EndProcedure
Dim maze(0, 0)
 
If OpenConsole()
generateMaze(maze(), 11, 8)
displayMaze(maze())
 
Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input()
CloseConsole()
EndIf
</lang>
Sample output:
<pre>Started generation at 9 x 3
+---+---+---+---+---+---+---+---+---+---+---+
| | | | |
+ + +---+ + +---+ + +---+ + +
| | | | | | | |
+ +---+ +---+---+ +---+ + +---+---+
| | | | | |
+ + +---+---+ +---+---+---+---+---+ +
| | | | | |
+ +---+ +---+ + +---+ + +---+---+
| | | | | |
+---+---+---+ + + +---+---+ +---+ +
| | | | | |
+ +---+---+ +---+ +---+---+ + +---+
| | | | | | |
+ + + +---+---+---+ + +---+---+ +
| | | |
+---+---+---+---+---+---+---+---+---+---+---+</pre>
 
=={{header|Tcl}}==
Anonymous user