Simple maze

From RogueBasin
(Difference between revisions)
Jump to: navigation, search
(Wikified Jakub's maze algorithm)
 
(written vb6 maze generator + examples)
Line 1: Line 1:
 +
__TOC__
 +
 +
== Maze Generator in C++ ==
 +
 
Simple maze generator written in 10 minutes :)  
 
Simple maze generator written in 10 minutes :)  
 
The source code is public domain.  
 
The source code is public domain.  
Line 103: Line 107:
 
   }  
 
   }  
  
Sample result:
+
=== Examples ===
 +
 
 
<pre>
 
<pre>
 
######.........#.#.......#.....#...#.....#.........#.#...#.#.......#.......#####  
 
######.........#.#.......#.....#...#.....#.........#.#...#.#.......#.......#####  
Line 204: Line 209:
 
######.###.#.#.###.#.###.#.#.###.#.#.#.#.#.###.#####.#.#######.#.#.###.#########  
 
######.###.#.#.###.#.###.#.#.###.#.#.#.#.#.###.#####.#.#######.#.#.###.#########  
 
##.......#.#...........#.#.....#.#.#.#.#.#.....###...#.###.......#...#...#######
 
##.......#.#...........#.#.....#.#.#.#.#.#.....###...#.###.......#...#...#######
 +
</pre>
 +
 +
== Maze Generator in [[Visual Basic]] 6 ==
 +
 +
<pre>
 +
''''''''''''''''''''''''''
 +
' Perfect Maze Generator '
 +
'    Visual Basic 6    '
 +
'          Icey          '
 +
'        Oct 2006        '
 +
'      Public Domain    '
 +
''''''''''''''''''''''''''
 +
 +
' this code is designed to be run from a module, using sub main
 +
 +
' all variables are declared
 +
Option Explicit
 +
' used for storing the current square and squares potentially to move to
 +
Private Type COORDS
 +
    X As Integer
 +
    Y As Integer
 +
End Type
 +
' stores the directions that corridors go in
 +
Dim cDir(3) As COORDS
 +
' these can be any odd numbers
 +
Dim blnMaze(31, 33) As Boolean
 +
' 0 is the most random, randomisation gets lower after that
 +
' less randomisation means more straight corridors
 +
Private Const RANDOMISATION As Integer = 0
 +
 +
Private Sub GenerateMaze()
 +
    Dim cN As COORDS, cS As COORDS
 +
    Dim intDir As Integer, intDone As Integer
 +
    Dim blnBlocked As Boolean
 +
    Randomize
 +
    Erase blnMaze
 +
    Do
 +
        ' this code is used to make sure the numbers are odd
 +
        cS.X = 2 + (Int(((UBound(blnMaze, 1) - 1) * Rnd) / 2) * 2)
 +
        cS.Y = 2 + (Int(((UBound(blnMaze, 2) - 1) * Rnd) / 2) * 2)
 +
        ' first one is free!
 +
        If intDone = 0 Then blnMaze(cS.X, cS.Y) = True
 +
        If blnMaze(cS.X, cS.Y) Then
 +
            ' always randomisation directions to start
 +
            RandomDirections
 +
            Do
 +
                ' only randomisation directions, based on the constant
 +
                If Int(RANDOMISATION * Rnd) = 0 Then RandomDirections
 +
                blnBlocked = True
 +
                ' loop through order of directions
 +
                For intDir = 0 To 3
 +
                    ' work out where this direction is
 +
                    cN.X = cS.X + (cDir(intDir).X * 2)
 +
                    cN.Y = cS.Y + (cDir(intDir).Y * 2)
 +
                    ' check if the tile can be used
 +
                    If IsFree(cN) Then
 +
                        ' create a path
 +
                        blnMaze(cN.X, cN.Y) = True
 +
                        ' and the square inbetween
 +
                        blnMaze(cS.X + cDir(intDir).X, cS.Y + cDir(intDir).Y) = True
 +
                        ' this is now the current square
 +
                        cS.X = cN.X
 +
                        cS.Y = cN.Y
 +
                        blnBlocked = False
 +
                        ' increment paths created
 +
                        intDone = intDone + 1
 +
                        Exit For
 +
                    End If
 +
                Next
 +
            ' loop until a path was created
 +
            Loop Until blnBlocked
 +
        End If
 +
    ' create enough paths to fill the whole grid
 +
    Loop While intDone + 1 < ((UBound(blnMaze, 1) - 1) * (UBound(blnMaze, 2) - 1)) / 4
 +
End Sub
 +
 +
' this changes the direction to go from the current square, to the next available
 +
Private Sub RandomDirections()
 +
    ' clear the array
 +
    Erase cDir
 +
    ' four possible sets of directions
 +
    Select Case Int(3 * Rnd)
 +
        Case 0
 +
            cDir(0).X = -1: cDir(1).X = 1
 +
            cDir(2).Y = -1: cDir(3).Y = 1
 +
        Case 1
 +
            cDir(3).X = -1: cDir(2).X = 1
 +
            cDir(1).Y = -1: cDir(0).Y = 1
 +
        Case 2
 +
            cDir(2).X = -1: cDir(3).X = 1
 +
            cDir(0).Y = -1: cDir(1).Y = 1
 +
        Case 3
 +
            cDir(1).X = -1: cDir(0).X = 1
 +
            cDir(3).Y = -1: cDir(2).Y = 1
 +
    End Select
 +
End Sub
 +
 +
' checks if a tile is free for use
 +
Private Function IsFree(cF As COORDS) As Boolean
 +
    ' check it's within the grid
 +
    If cF.X < UBound(blnMaze, 1) And cF.X > 1 And cF.Y < UBound(blnMaze, 2) And cF.Y > 1 Then
 +
        ' check it hasn't been used yet
 +
        IsFree = (blnMaze(cF.X, cF.Y) = False)
 +
    End If
 +
End Function
 +
 +
' this code should be run from a module
 +
' go to Project > [projectname] Properties
 +
' and then select Sub Main from the Startup Object list
 +
Sub Main()
 +
    ' the maze is added to this string, which is then copied to the clipboard
 +
    Dim strOutput As String
 +
    GenerateMaze
 +
    Dim A As Integer, B As Integer
 +
    ' loops through columns
 +
    For A = 1 To UBound(blnMaze, 1)
 +
        ' loop through rows
 +
        For B = 1 To UBound(blnMaze, 2)
 +
            ' check if a path was created here
 +
            If blnMaze(A, B) Then
 +
                ' empty
 +
                strOutput = strOutput & " "
 +
            Else
 +
                ' wall
 +
                strOutput = strOutput & "#"
 +
            End If
 +
        Next
 +
        ' go down to the next row
 +
        strOutput = strOutput & vbNewLine
 +
    Next
 +
    Clipboard.Clear
 +
    Clipboard.SetText strOutput
 +
    ' tell the user what has happened
 +
    MsgBox "Maze copied to the clipboard.", vbInformation, "Maze generator"
 +
End Sub
 +
</pre>
 +
 +
=== Examples ===
 +
 +
<pre>
 +
Randomisation: 0
 +
 +
###########################################
 +
#    #    #          #          #    #
 +
# ### # ##### # # ##### ### ### # ### #####
 +
# # # # #  # # #    #    # # # #      #
 +
# # # # # # # # ##### ##### # # # # ##### #
 +
# #  # # # # #  # #  #  #  #      # #
 +
# ##### # # # ### # ### ######### ##### # #
 +
#  #  # #  # # #  # #  # #  #  # # #
 +
### ### # # ### # ### # # # # # ##### ### #
 +
# # #  # # #  #  # #  # #        #  #
 +
# # # ### # # # ### # # ### ########### ###
 +
#  #    # # #  #  # # # #    # #  # #
 +
# ######### # ######### # # # ### # # ### #
 +
# # #  #  # #      #  # #  # # #  # #
 +
# # # # # ### # # ### ### # ### # # ### # #
 +
# # # # # #  # # # # #  #  # # #  #  #
 +
# # # # # # ##### # # # ### # ### # # #####
 +
# # # #  # #  # # #  # # #  #  # #  #
 +
# # # ### # # # # # # ### # ### ##### # # #
 +
# #    # # # # #  #    #  #      # # #
 +
# ####### # # # ######### ### ########### #
 +
#        #  #          #              #
 +
###########################################
 +
</pre>
 +
 +
<pre>
 +
Randomisation: 5
 +
 +
#####################################################
 +
#                #  #  #                      # #
 +
# ############### # # # # ##################### # # #
 +
#      #  #  # # # # #                      # # #
 +
####### # # # # # # # # ######################### # #
 +
# #  # # #  # # # # # #                      # # #
 +
# # # # ### ##### # # # # # ################### # # #
 +
# # # # # #    # # # # # # #        #  #    # # #
 +
# # # # # ### # # # # # ### ######### # # # # ### # #
 +
# # # # # #  # #  # #  # #        # # # #  # # #
 +
# # # # # ##### ##### # # # # ######### # # ### # # #
 +
# # # # # #          # # # #        # # # #  # # #
 +
# # # # # # ########### # # ######### # # # # ### # #
 +
# # # # # #  #  #  # # # #  #  # # # # #  # # #
 +
# # # # # # # # # # # # # # # # # # # # # # ### # # #
 +
#  #  #  #  #  #  #  # #  #    #  #  #  #
 +
#####################################################
 +
</pre>
 +
 +
<pre>
 +
Randomisation: 25
 +
 +
###################################################
 +
#    #  #  #    #  #                        #
 +
### # # # # # # # # # # ######################### #
 +
#  # # # # # # # # # #                          #
 +
# ##### # # # # # # ### ############### ######### #
 +
#    # # # # # # #  # #  # #  #  # #  #  # #
 +
##### # # # # # ### # # # # # # # # # # # # # # # #
 +
#    # # # # # # # # # # # # # # # # # # # # # # #
 +
# ##### # # # # # # # # # # # # # # # ### # # # # #
 +
#    # # # # # # # # # # # # # # # #  # # # # # #
 +
##### # # # # # # # # # # # # # # # # # # # # # # #
 +
#    # # # # # # # # # # # # # # # # #  # # # # #
 +
# ##### # # # # # # # # # # # # # # # ####### # # #
 +
#    # # # # # # # # # # # # # # # #      # # # #
 +
##### # # # # # # # # # ### # # # # ####### # # # #
 +
#    # # # # # # # # #  # # # # # #    # # # # #
 +
# ##### # # # # # # # # # # # # # # # ##### # # # #
 +
#    # # # # # # # # # # # # # # # #      # # # #
 +
##### # # # # # # # # # # # # # # # ####### # # # #
 +
#    # # # # # # # # # # # # # # # #    # # # # #
 +
# ##### # # # # # # # # # # # # # # # ##### # # # #
 +
#    # # # # # # # # # # # #  # # #    # # # # #
 +
##### # # # # # # # # # # # ##### # ##### # # # # #
 +
#    # # # # # # # # # # # #  # # #    # # # # #
 +
# ##### # # # # # # # # # # # # # # # ##### # # # #
 +
#    # # # # # # # # # # #  # # # #      # # # #
 +
##### # # # # # # # # # # # ### # # ####### # # # #
 +
#    # # # # # # # # # # # # # # # #  # # # # # #
 +
# ##### # # # # # # # # # # # # # # # # # # # # # #
 +
#      #  #  #  #  #  #  #    #  #  #  #
 +
###################################################
 
</pre>
 
</pre>

Revision as of 17:46, 22 October 2006

Contents


Maze Generator in C++

Simple maze generator written in 10 minutes :) The source code is public domain.

  // Simple Maze Generator in C++ by Jakub Debski '2006 
  
  #include <time.h>
  #include <vector>
  #include <list>
  using namespace std;
  
  int main() 
  { 
          srand(time(0)); 
  
          const int maze_size_x=80; 
          const int maze_size_y=25; 
          vector < vector < bool > > maze; 
          list < pair < int, int> > drillers; 
  
          maze.resize(maze_size_y); 
          for (size_t y=0;y<maze_size_y;y++) 
                  maze[y].resize(maze_size_x); 
  
          for (size_t x=0;x<maze_size_x;x++) 
                  for (size_t y=0;y<maze_size_y;y++) 
                          maze[y][x]=false; 
  
          drillers.push_back(make_pair(maze_size_x/2,maze_size_y/2)); 
          while(drillers.size()>0) 
          { 
                  list < pair < int, int> >::iterator m,_m,temp; 
                  m=drillers.begin(); 
                  _m=drillers.end(); 
                  while (m!=_m) 
                  { 
                          bool remove_driller=false; 
                          switch(rand()%4) 
                          { 
                          case 0: 
                                  (*m).second-=2; 
                                  if ((*m).second<0 || maze[(*m).second][(*m).first]) 
                                  { 
                                          remove_driller=true; 
                                          break; 
                                  } 
                                  maze[(*m).second+1][(*m).first]=true; 
                                  break; 
                          case 1: 
                                  (*m).second+=2; 
                                  if ((*m).second>=maze_size_y || maze[(*m).second][(*m).first]) 
                                  { 
                                          remove_driller=true; 
                                          break; 
                                  } 
                                  maze[(*m).second-1][(*m).first]=true; 
                                  break; 
                          case 2: 
                                  (*m).first-=2; 
                                  if ((*m).first<0 || maze[(*m).second][(*m).first]) 
                                  { 
                                          remove_driller=true; 
                                          break; 
                                  } 
                                  maze[(*m).second][(*m).first+1]=true; 
                                  break; 
                          case 3: 
                                  (*m).first+=2; 
                                  if ((*m).first>=maze_size_x || maze[(*m).second][(*m).first]) 
                                  { 
                                          remove_driller=true; 
                                          break; 
                                  } 
                                  maze[(*m).second][(*m).first-1]=true; 
                                  break; 
                          } 
                          if (remove_driller) 
                                  m = drillers.erase(m); 
                          else 
                          { 
                                  drillers.push_back(make_pair((*m).first,(*m).second)); 
                                  // uncomment the line below to make the maze easier 
                                  // if (rand()%2) 
                                  drillers.push_back(make_pair((*m).first,(*m).second)); 
  
                                  maze[(*m).second][(*m).first]=true; 
                                  ++m; 
                          } 
                  } 
          } 
  
          // Done 
          for (size_t y=0;y<maze_size_y;y++) 
                  for (size_t x=0;x<maze_size_x;x++) 
                  { 
                          if (maze[y][x]==true) 
                                  printf("."); 
                          else 
                                  printf("#"); 
                  } 
  
          return 0; 
  
  } 

Examples

######.........#.#.......#.....#...#.....#.........#.#...#.#.......#.......##### 
######.#.###.#.#.#.#######.#.#####.#.###.#.#.#####.#.###.#.#.#######.########### 
.....#.#.#...#.#.........#.#.#.....#.###...#.#.....#.......#.......#.....####### 
.#.#.###.#.#####.#.#.#######.#.#.#.#.#####################.#.###.#######.####### 
.#.#.#...#...#...#.#...#.#.#.#.#.#.#.........#.....#...........#.#.............# 
####.#.#######.#######.#.#.#.#.#.#######.#.#.#.#.#.#.#######.#######.#######.#.# 
##...#...#####.#.#####.#...#...#.#...#.#.#.#...#.#...###...#.#.......#.......#.# 
####.###.#####.#.#####.#.###.#.###.###.#.#.###.#########.#####.###.############# 
.........###.#.....###.#...#.#.#.#.......#.#...#...#.#.#.#.......#.###...#.....# 
########.###.#.#.#.###.#.#.###.#.#.#####.#.###.#.###.#.#.#.#.###.#####.###.#.### 
.......#.....#.#.#.#...#.#...........#...#.#.....#.......#.#...#.#.........#...# 
####.#.#.#####.#.###.#######.#######.###.#.#.###.#.#####.#.#####.#.#.#####.##### 
...#.#.#.......#...#.....#.....#.#...#####.#...#.......#.#...#.....#...#.#.....# 
##.###.#.#.#.###.#####.#.#####.#.#.#######.#####.#####.#.###.#.###.#####.#####.# 
##...#...#.#.#.......#.#.....#...#.......#...#...#.....#.....#...#...........#.# 
####.#.###########.###.#.###.#####.#######.###.###########.###.###.#####.###.### 
####...###.....#...#.#.#...#...........###...#.###...#.###.###...#.....#.#.....# 
####.#####.#######.#.###.###.#.#####.#.#############.#.###.#####.#####.#.###.### 
####.........#.#...#.....#.#.#.#.....#.###.#...#.............#...#####.#...#...# 
######.#.#####.#.###.#.#.#.###.#######.###.#.#####.###.#################.####### 
######.#...#.#.....#.#.#.#...#...###...###.....#...#.......#########...#.......# 
######.###.#.#####.#####.#.###.#.###.#.###.#.###.###.#####.#########.#########.# 
######.#.#.#...###...#...#.#.#.#...#.#.....#.#.#...#.###...#########...#.......# 
########.#.###.#######.#.#.#.###.#######.###.#.#####.###############.#.###.##### 
########...###.........#.#.......#######.#.....#####.......#########.#.........#

With little changes you can get cool results, f.e.

  else 
  { 
          // drillers.push_back(make_pair((*m).first,(*m).second)); 
          // drillers.push_back(make_pair((*m).first,(*m).second)); 
          // change to 
          for (size_t index=0;index<10;index++) 
                  drillers.push_front(make_pair((*m).first,(*m).second)); 

gives "star-like" effect:

.#.#...#...#.....#...#...#...#.#...#...#.....#...#...#.......#...#.....#.....#.# 
.#.###.###.#####.###.###.###.#.###.###.#.#####.###.###.#######.###.#####.#####.# 
...#.#...#...#...#.#...#...#...#.#...#.....#...#.......#.............#.#...#...# 
##.#.###.###.###.#.###.###.###.#.###.#.#####.###.#######.#############.#.###.### 
.......#...#.#.#.....#.#.#.......#.#.....#...#...#.#...#...#...#.#.#.#...#...#.# 
######.###.#.#.#####.#.#.#######.#.###.###.###.###.#.###.###.###.#.#.#.###.###.# 
...#.#...#...#...#.......#.#...#.....#.....#...#.....#...#...#.#.......#...#...# 
##.#.###.###.###.#######.#.###.#####.#.#####.###.#####.###.###.#.#######.###.### 
.#...#.#.#.#...#.#.#.....#.#.#...#.......#...#.#...#.#.#...#.#...#.#...#.#...#.# 
.###.#.#.#.###.#.#.#####.#.#.###.#####.###.###.#.###.#.#.###.#.###.#.###.#.###.# 
.................#...#...#.#.#.#...#...#.......................................# 
####.###.###.###.###.###.#.#.#.###.###.#.###.###.###.###.###.###.###.###.###.### 
.#.#.#.#.#.#.#...........................#.#.#.#.#.#.#.#.#.#.#.#...#.#.#.#.#.#.# 
.#.###.###.#####.#.#.#####.#####.#.###.#.#.###.###.###.###.###.#######.###.###.# 
.................#.#.#.....#.....#.#...#.......................................# 
##.###.#.###.#.###.#####.###.#.#.#####.###.#.#.###.#.###.###.#.#.###.#.###.#.#.# 
...#...#.#...#.#...#.....#...#.#.#.......#.#.#...#.#...#...#.#.#...#.#...#.#.#.# 
.###.#.###.#.###.#.#######.#.#.#####.#.#####.###.###.#.#######.###.###.#.###.### 
.#...#.#...#.#...#.#.......#.#.#.....#.....#...#...#.#.......#...#...#.#...#...# 
##.#.#####.###.#.###.###.###.#####.###.#.#.###.###.###.#.###.###.#.#####.#####.# 
...#.#.....#...#.#...#...#...#.....#...#.#...#...#...#.#...#...#.#.....#.....#.# 
.#.###.#.#####.###.###.###.###.#.###.#.###.#.###.###.###.#####.###.###.###.#.### 
.#.#...#.#.....#...#...#...#...#.#...#...#.#...#...#...#.....#...#...#...#.#...# 
.#####.#####.###.###.###.###.#.###.###.#####.#.###.###.###.#.###.#.#.###.###.### 
.#.....#.....#...#...#...#...#.#...#.......#.#...#...#...#.#...#.#.#...#...#...# 

or

          (*m).second-=2; 
          // if ((*m).second<0 || maze[(*m).second][(*m).first]) 
          // change to 
          if ((*m).second<0 || (maze[(*m).second][(*m).first] && rand()%5)) 

allows loops (sample loop top left corner is marked with comas):

.......#,,,,,,,,.#####.....#####...#...............#...#.###.....###...#.#.#.### 
.#######,#####.#,#######.#######.#.#############.#.###.#.###.#########.#.#.#.### 
.#...#..,,,,,#.#,,,###...#######.#.#...#.........#.....#.......................# 
.#.###.#####,#####,###.#.#########.#.#########.#####.#.#.###.#.#########.#.#.#.# 
.#.....#....,,,,,,,....#.#######.....#...#...#...###.#.......#.###.#.....#.#...# 
.#.#.#####.#.#.###.#################.#.#.###.#######.#####.###.###.#.#####.##### 
.#...#.....#.....#.#...#.......#.#...#.#.....#######...#...#...#.#.#.###...#.### 
.#.###.###.#.###.#.###.#.#######.#.#.###.#.#.#######.###########.#.#######.#.### 
...#...#.#.#.#...#.....#.....#...#.#.....#...#.#####.......#.....#.........#...# 
####.#.#.#.#####.#.#.#.###.#.###.#######.#.#.#.#######.#.#.#.#.#.###.#######.### 
...#.#.#.....#.....#.#.#...#.#...#.....#.#.#...#...#...#.#...#.#...............# 
.###.###.#####.#######.###.#.###.#.###.###.#.#.#.#####.#######.###.#######.#.#.# 
.....#.#.#...#...#...#.#...#...........#.....#.........#.#####.#...#...###...#.# 
##.###.#.#.#.#.#.#.#########.#.###.###.#.###.#######.###.#####.###.#.#.###.##### 
...#.......#...#...#.......#.#.#...#...#...#.#.#...#.#.....#...#...#.#.#...#...# 
####.#.#######.#.#.#.###.###.#.#.#####.#####.#.#.#####.#.#.#.#.#######.#####.### 
.......#...#...#.#.....#.#...#...#...............#.....#.#...#...........#...### 
##.#####.###########.#####.#########.#.###.###.#.#########.###.###.#.#.###.#.### 
.......#...#.#.......#.....#.....#...#.#.....#.#.#...........#...#.....#.#.#...# 
##.#.###.###.#.#.###.#######.#.#.#####.###.#####.###.#.#.#####.###.#.###.###.### 
##.#...#.......#...#.........#.#.......#...###.#.....#...#####...#.............# 
########.###.#.#.#########.#####.#.#####.#####.#.#####.#.#####.#####.#.#.####### 
##.........#.#...#.#...#...#...#.....#.....#...#.....#.#.#####.....#...#.....### 
######.###.#.#.###.#.###.#.#.###.#.#.#.#.#.###.#####.#.#######.#.#.###.######### 
##.......#.#...........#.#.....#.#.#.#.#.#.....###...#.###.......#...#...#######

Maze Generator in Visual Basic 6

''''''''''''''''''''''''''
' Perfect Maze Generator '
'     Visual Basic 6     '
'          Icey          '
'        Oct 2006        '
'      Public Domain     '
''''''''''''''''''''''''''

' this code is designed to be run from a module, using sub main

' all variables are declared
Option Explicit
' used for storing the current square and squares potentially to move to
Private Type COORDS
    X As Integer
    Y As Integer
End Type
' stores the directions that corridors go in
Dim cDir(3) As COORDS
' these can be any odd numbers
Dim blnMaze(31, 33) As Boolean
' 0 is the most random, randomisation gets lower after that
' less randomisation means more straight corridors
Private Const RANDOMISATION As Integer = 0

Private Sub GenerateMaze()
    Dim cN As COORDS, cS As COORDS
    Dim intDir As Integer, intDone As Integer
    Dim blnBlocked As Boolean
    Randomize
    Erase blnMaze
    Do
        ' this code is used to make sure the numbers are odd
        cS.X = 2 + (Int(((UBound(blnMaze, 1) - 1) * Rnd) / 2) * 2)
        cS.Y = 2 + (Int(((UBound(blnMaze, 2) - 1) * Rnd) / 2) * 2)
        ' first one is free!
        If intDone = 0 Then blnMaze(cS.X, cS.Y) = True
        If blnMaze(cS.X, cS.Y) Then
            ' always randomisation directions to start
            RandomDirections
            Do
                ' only randomisation directions, based on the constant
                If Int(RANDOMISATION * Rnd) = 0 Then RandomDirections
                blnBlocked = True
                ' loop through order of directions
                For intDir = 0 To 3
                    ' work out where this direction is
                    cN.X = cS.X + (cDir(intDir).X * 2)
                    cN.Y = cS.Y + (cDir(intDir).Y * 2)
                    ' check if the tile can be used
                    If IsFree(cN) Then
                        ' create a path
                        blnMaze(cN.X, cN.Y) = True
                        ' and the square inbetween
                        blnMaze(cS.X + cDir(intDir).X, cS.Y + cDir(intDir).Y) = True
                        ' this is now the current square
                        cS.X = cN.X
                        cS.Y = cN.Y
                        blnBlocked = False
                        ' increment paths created
                        intDone = intDone + 1
                        Exit For
                    End If
                Next
            ' loop until a path was created
            Loop Until blnBlocked
        End If
    ' create enough paths to fill the whole grid
    Loop While intDone + 1 < ((UBound(blnMaze, 1) - 1) * (UBound(blnMaze, 2) - 1)) / 4
End Sub

' this changes the direction to go from the current square, to the next available
Private Sub RandomDirections()
    ' clear the array
    Erase cDir
    ' four possible sets of directions
    Select Case Int(3 * Rnd)
        Case 0
            cDir(0).X = -1: cDir(1).X = 1
            cDir(2).Y = -1: cDir(3).Y = 1
        Case 1
            cDir(3).X = -1: cDir(2).X = 1
            cDir(1).Y = -1: cDir(0).Y = 1
        Case 2
            cDir(2).X = -1: cDir(3).X = 1
            cDir(0).Y = -1: cDir(1).Y = 1
        Case 3
            cDir(1).X = -1: cDir(0).X = 1
            cDir(3).Y = -1: cDir(2).Y = 1
    End Select
End Sub

' checks if a tile is free for use
Private Function IsFree(cF As COORDS) As Boolean
    ' check it's within the grid
    If cF.X < UBound(blnMaze, 1) And cF.X > 1 And cF.Y < UBound(blnMaze, 2) And cF.Y > 1 Then
        ' check it hasn't been used yet
        IsFree = (blnMaze(cF.X, cF.Y) = False)
    End If
End Function

' this code should be run from a module
' go to Project > [projectname] Properties
' and then select Sub Main from the Startup Object list
Sub Main()
    ' the maze is added to this string, which is then copied to the clipboard
    Dim strOutput As String
    GenerateMaze
    Dim A As Integer, B As Integer
    ' loops through columns
    For A = 1 To UBound(blnMaze, 1)
        ' loop through rows
        For B = 1 To UBound(blnMaze, 2)
            ' check if a path was created here
            If blnMaze(A, B) Then
                ' empty
                strOutput = strOutput & " "
            Else
                ' wall
                strOutput = strOutput & "#"
            End If
        Next
        ' go down to the next row
        strOutput = strOutput & vbNewLine
    Next
    Clipboard.Clear
    Clipboard.SetText strOutput
    ' tell the user what has happened
    MsgBox "Maze copied to the clipboard.", vbInformation, "Maze generator"
End Sub

Examples

Randomisation: 0

###########################################
#     #     #           #           #     #
# ### # ##### # # ##### ### ### # ### #####
# # # # #   # # #     #     # # # #       #
# # # # # # # # ##### ##### # # # # ##### #
# #   # # # # #   # #   #   #   #       # #
# ##### # # # ### # ### ######### ##### # #
#   #   # #   # # #   # #   # #   #   # # #
### ### # # ### # ### # # # # # ##### ### #
# # #   # # #   #   # #   # #         #   #
# # # ### # # # ### # # ### ########### ###
#   #     # # #   #   # # # #     # #   # #
# ######### # ######### # # # ### # # ### #
# # #   #   # #       #   # #   # # #   # #
# # # # # ### # # ### ### # ### # # ### # #
# # # # # #   # # # # #   #   # # #   #   #
# # # # # # ##### # # # ### # ### # # #####
# # # #   # #   # # #   # # #   #   # #   #
# # # ### # # # # # # ### # ### ##### # # #
# #     # # # # #   #     #   #       # # #
# ####### # # # ######### ### ########### #
#         #   #           #               #
###########################################
Randomisation: 5

#####################################################
#                 #   #   #                       # #
# ############### # # # # ##################### # # #
#       #   #   # # # # #                       # # #
####### # # # # # # # # ######################### # #
# #   # # #   # # # # # #                       # # #
# # # # ### ##### # # # # # ################### # # #
# # # # # #     # # # # # # #         #   #     # # #
# # # # # ### # # # # # ### ######### # # # # ### # #
# # # # # #   # #   # #   # #         # # # #   # # #
# # # # # ##### ##### # # # # ######### # # ### # # #
# # # # # #           # # # #         # # # #   # # #
# # # # # # ########### # # ######### # # # # ### # #
# # # # # #   #   #   # # # #   #   # # # # #   # # #
# # # # # # # # # # # # # # # # # # # # # # ### # # #
#   #   #   #   #   #   #   # #   #     #   #   #   #
#####################################################
Randomisation: 25

###################################################
#     #   #   #     #   #                         #
### # # # # # # # # # # ######################### #
#   # # # # # # # # # #                           #
# ##### # # # # # # ### ############### ######### #
#     # # # # # # #   # #   # #   #   # #   #   # #
##### # # # # # ### # # # # # # # # # # # # # # # #
#     # # # # # # # # # # # # # # # # # # # # # # #
# ##### # # # # # # # # # # # # # # # ### # # # # #
#     # # # # # # # # # # # # # # # #   # # # # # #
##### # # # # # # # # # # # # # # # # # # # # # # #
#     # # # # # # # # # # # # # # # # #   # # # # #
# ##### # # # # # # # # # # # # # # # ####### # # #
#     # # # # # # # # # # # # # # # #       # # # #
##### # # # # # # # # # ### # # # # ####### # # # #
#     # # # # # # # # #   # # # # # #     # # # # #
# ##### # # # # # # # # # # # # # # # ##### # # # #
#     # # # # # # # # # # # # # # # #       # # # #
##### # # # # # # # # # # # # # # # ####### # # # #
#     # # # # # # # # # # # # # # # #     # # # # #
# ##### # # # # # # # # # # # # # # # ##### # # # #
#     # # # # # # # # # # # #   # # #     # # # # #
##### # # # # # # # # # # # ##### # ##### # # # # #
#     # # # # # # # # # # # #   # # #     # # # # #
# ##### # # # # # # # # # # # # # # # ##### # # # #
#     # # # # # # # # # # #   # # # #       # # # #
##### # # # # # # # # # # # ### # # ####### # # # #
#     # # # # # # # # # # # # # # # #   # # # # # #
# ##### # # # # # # # # # # # # # # # # # # # # # #
#       #   #   #   #   #   #   #     #   #   #   #
###################################################
Personal tools