Maze generation: Difference between revisions

→‎{{header|PureBasic}}: Updated code to add clarity and to generalize it
(→‎{{header|PureBasic}}: Updated code to add clarity and to generalize it)
Line 668:
EndDataSection
 
#cellDWidth = 4
;setup reference values indexed by direction from current map cell
 
Structure mazeOutput
vWall.s
hWall.s
EndStructure
 
 
;setup reference values indexed by type and direction from current map cell
Global Dim offset.POINT(#numOffsets, #numDirs)
Define i, j
Line 680 ⟶ 688:
For i = 0 To #numDirs: Read.i wallvalue(i): Next
 
 
Procedure displayMaze(Array maze(2))
Procedure makeDisplayMazeRow(Array mazeRow.mazeOutput(1), Array maze(2), y)
Protected x, y, vWall.s, hWall.s
;modify mazeRow() to produce output of 2 strings showing the vertical walls above and horizontal walls across a given maze row
Protected x, y, vWall.s, hWall.s
Protected mazeWidth = ArraySize(maze(), 1), mazeHeight = ArraySize(maze(), 2)
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
mazeRow(0)\vWall = Left(vWall, mazeWidth * #cellDWidth + 1)
If y <> mazeHeight: mazeRow(0)\hWall = Left(hWall, mazeWidth * #cellDWidth + 1): Else: mazeRow(0)\hWall = "": EndIf
EndProcedure
 
Procedure displayMaze(Array maze(2))
Protected x, y, vWall.s, hWall.s, mazeHeight = ArraySize(maze(), 2)
Protected Dim mazeRow.mazeOutput(0)
For y = 0 To mazeHeight
makeDisplayMazeRow(mazeRow(), maze(), y)
vWall = "": hWall = ""
PrintN(mazeRow(0)\vWall): PrintN(mazeRow(0)\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) ;includesEach ancell extraspecifies rowwalls andpresent columnabove forand to the SEleft of cornerit,
;array includes an extra row and column for the right and bottom walls
Dim visited(mazeWidth + 1, mazeHeight + 1) ;includes padding for easy border detection
Dim visited(mazeWidth + 1, mazeHeight + 1) ;Each cell represents a cell of the maze, an extra line of cells are included
;as padding around the representative cells for easy border detection
Protected i
;mark outside border as already visited (off limits)
For i = 10 To mazeWidth
visited(i, 0) =+ offset(#True: visited(i, mazeHeight#dir_N)\x, 0 + 1offset(#visited, #dir_N)\y) = #True
visited(i + offset(#visited, #dir_S)\x, mazeHeight - 1 + offset(#visited, #dir_S)\y) = #True
Next
For i = 10 To mazeHeight
visited(0, i)+ =offset(#visited, #True:dir_W)\x, visited(mazeWidthi + 1offset(#visited, i#dir_W)\y) = #True
visited(mazeWidth - 1 + offset(#visited, #dir_E)\x, i + offset(#visited, #dir_E)\y) = #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("StartedMaze of size " + Str(mazeWidth) + " x " + Str(mazeHeight) + ", generation started at " + Str(x) + " x " + Str(y))
NewList stack.POINT()
Line 727 ⟶ 749:
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())
Line 740 ⟶ 762:
EndIf
ForEver
 
; ;mark random entry and exit point
; x = Random(mazeWidth - 1): y = Random(mazeHeight - 1)
; maze(x, 0) | wallvalue(#dir_N): maze(mazeWidth, y) | wallvalue(#dir_E)
ProcedureReturn
EndProcedure
Dim maze(0, 0)
 
If OpenConsole()
generateMaze(Dim maze(), 110, 80)
Define mazeWidth = Random(5) + 7: mazeHeight = Random(5) + 3
generateMaze(maze(), mazeWidth, mazeHeight)
displayMaze(maze())
 
Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input()
CloseConsole()
EndIf</lang>
The maze is represented by an array of cells where each cell indicates the walls present above (#dir_N) and to its left (#dir_W). Maze generation is done with a additional array marking the visited cells. Neither an entry nor an exit are created, these were not part of the task. A simple means of doing so is included but has been commented out.
 
Sample output:
<pre>StartedMaze of size 11 x 8, generation started at 9 x 3
+---+---+---+---+---+---+---+---+---+---+---+
| | | | |
Anonymous user