Results 1 to 11 of 11

Thread: Random Mazes?

  1. #1

    Thread Starter
    Addicted Member
    Join Date
    Mar 2002
    Location
    St. Louis MO
    Posts
    129

    Random Mazes?

    Is there a general approach to generating a random maze? - One with a guareenteed exit?
    I've seen games in the past with random mazes (at least I think they were random..) and have always been interested in how it's done. Not so much the actual code, but at least the steps involved.


    Thanks!

  2. #2
    Fanatic Member
    Join Date
    Feb 2000
    Location
    Israel
    Posts
    636
    In my opinion, random mazes are done at the above way:

    Say, the map is a map of blocks. Every X,Y of the map is set True/False. Like block or not block.
    At first step, you run through the map using For loops and set randomly every block: True/False.

    After that step, there might be a way out of the random maze.
    "Might be" is not good for us, so we got to make sure that there is a way out.

    This maze is a simple one, so let us say that we start at (1,1) block point and end the maze at the right-bottom block.

    Now comes the hard part, make the way from the start to the end.

    It's something like this:
    Run a visual player the runs through the maze.
    You run a while loop. The while stops when the visual player gets to the end.
    At each point in the maze, ask the following questions in that certain order:

    Am I blocked?
    If not, choose randomly which way to go and remove the block.
    If yes, ask the next question:
    Can I go in a diagonal way?
    If yes, choose randomly which way to go and remove the necessary blocks.
    If not, choose randomly which way to go.

    Well, I didn't check that theory.
    Maybe it's missing some parts, but in general, that's the idea.

    You know, with that question, you got me trying it.
    Thank you.

    I hope you'll get great results from that plan.
    Arie.
    Tip Of The Day: Fake it 'till you make it !

  3. #3
    Fanatic Member
    Join Date
    Feb 2000
    Location
    Israel
    Posts
    636
    Right after I wrote my last post, I wrote this program.
    It's a little sloppy and leaves lots of open areas in the map, yet does its work very well..

    When you run it, press Random map, then press Way out.

    Anyone who sees this post may help to code it better.
    Please post if you have Improved projects.

    Arie.
    Attached Files Attached Files
    Tip Of The Day: Fake it 'till you make it !

  4. #4
    Fanatic Member
    Join Date
    Feb 2000
    Location
    Israel
    Posts
    636
    One little change here.. One big improvement...

    Arie.
    Attached Files Attached Files
    Tip Of The Day: Fake it 'till you make it !

  5. #5
    Fanatic Member McCain's Avatar
    Join Date
    Jan 2002
    Location
    Sweden/Denmark
    Posts
    802
    I haven't written this code and I'm not sure I understand how it works... But it does work very well.
    It's written by "David Brebner, Unlimited Realities"
    VB Code:
    1. Private Sub create_maze()
    2. 'clear maze
    3. For a% = 1 To 29
    4.     For b% = 1 To 29
    5.         mz%(a%, b%) = 0
    6.     Next
    7. Next
    8.  
    9. 'make border
    10. For a% = 0 To 30
    11.     mz%(a%, 0) = 1
    12.     mz%(a%, 30) = 1
    13.     mz%(0, a%) = 1
    14.     mz%(30, a%) = 1
    15. Next
    16. 'generate vertices
    17. For x% = 2 To 28 Step 2
    18.     For y% = 2 To 28 Step 2
    19.         vertsx%(x%, y%) = x%
    20.         vertsy%(x%, y%) = y%
    21.     Next
    22. Next
    23. 'mix up the order to draw verticies
    24. For X1% = 2 To 28 Step 2
    25.     For Y1% = 2 To 28 Step 2
    26.         X2% = (Int(Rnd(1) * 13) + 1) * 2
    27.         Y2% = (Int(Rnd(1) * 13) + 1) * 2
    28.         tmpx% = vertsx%(X1%, Y1%)
    29.         tmpy% = vertsy%(X1%, Y1%)
    30.         vertsx%(X1%, Y1%) = vertsx%(X2%, Y2%)
    31.         vertsy%(X1%, Y1%) = vertsy%(X2%, Y2%)
    32.         vertsx%(X2%, Y2%) = tmpx%
    33.         vertsy%(X2%, Y2%) = tmpy%
    34.     Next
    35. Next
    36.  
    37. 'now draw walls
    38.  'draw a wall from each verticies in a random direction
    39.  'until another wall is reached
    40. For x% = 2 To 28 Step 2
    41.     For y% = 2 To 28 Step 2
    42.         xx% = vertsx%(x%, y%)
    43.         yy% = vertsy%(x%, y%)
    44.         If mz%(xx%, yy%) = 0 Then
    45.             Do
    46.                 cnt% = 0
    47.                 xx% = vertsx%(x%, y%)
    48.                 yy% = vertsy%(x%, y%)
    49.                 dirn% = Int(Rnd(1) * 4)
    50.                 Do
    51.                     cnt% = cnt% + 1
    52.                     Select Case dirn%
    53.                         Case 0: xx% = xx% - 1
    54.                         Case 1: xx% = xx% + 1
    55.                         Case 2: yy% = yy% + 1
    56.                         Case Else: yy% = yy% - 1
    57.                     End Select
    58.                 Loop Until mz%(xx%, yy%) = 1
    59.             Loop Until cnt% < 26
    60.             xx% = vertsx%(x%, y%)
    61.             yy% = vertsy%(x%, y%)
    62.             Do
    63.                 mz%(xx%, yy%) = 1
    64.                 Select Case dirn%
    65.                     Case 0: xx% = xx% - 1
    66.                     Case 1: xx% = xx% + 1
    67.                     Case 2: yy% = yy% + 1
    68.                     Case Else: yy% = yy% - 1
    69.                 End Select
    70.             Loop Until mz%(xx%, yy%) = 1
    71.         End If
    72.     Next
    73. Next
    74.  
    75.  
    76. End Sub
    Never argue with fools, they will only drag you down to their level, and beat you with experience.

    Q: How do you tell an experienced hacker from a novice?
    A: The latter thinks there's 1000 bytes in a kilobyte, while the former is sure there's 1024 meters in a kilometer

  6. #6
    Fanatic Member
    Join Date
    Feb 2000
    Location
    Israel
    Posts
    636
    Can someone explain this code??
    I'd like to know how it works...

    Thank you,
    Arie.
    Tip Of The Day: Fake it 'till you make it !

  7. #7
    Addicted Member NOMADMAN's Avatar
    Join Date
    Aug 2002
    Location
    Closer than you think
    Posts
    237
    This is a differnt way to generate a maze, it shares a similarity with Arie's method but I think its different enough to methion. So Arie if you think Im restating your method, you have my appologise.

    You start with a rectangular array X by Y (squares are rectangles).
    Each cell of the maze has these attributes: (I'd use a Type definition)
    VISITED as Boolean
    NORTHWALL as Boolean
    SOUTHWALL as Boolean
    EASTWALL as Boolean
    WESTWALL as Boolean

    I'm gonna assume that a True value for a wall means the wall exists and blocks the path.

    Now initially set your array with VISITED = FALSE and all the others TRUE. This will result in a grid with no way to get anywhere (Can you visualize it?)

    So make a function that can 'see' (in scope) the array. And is passed the current position in the array. Something like this:
    Public Function MakeMaze(ByVal ROW as Integer, ByVal COL as Integer)

    The function will mark the position it is given as VISTED (VISITED = True) Then it will check if any of its neighboring cells are unvisited (VISITED = False) if even one is then RANDOMLY choose an unvisited cell. And then set the appropriate wall to be false (take away the wall) and recursively call your function (in my case MakeMaze) with the neighbors cell coords. If all the neighbors are already visited then exit the function.

    The recursiveness of this function will make it work.

    If you want a code sample you'll have to pay me
    I hope I made this clear enough. Ask me if you have any questions.

    NOMAD

  8. #8
    Fanatic Member McCain's Avatar
    Join Date
    Jan 2002
    Location
    Sweden/Denmark
    Posts
    802
    Originally posted by Arie
    Can someone explain this code??
    I'd like to know how it works...

    Thank you,
    Arie.
    I've rewritten it using more more standard VB. I've also removed a big chunc of unnessesarry (sp?) code. And I changed the maze-size to 61x61. Here's the code:
    VB Code:
    1. Private Sub CreateMaze()
    2.     Dim intA As Integer
    3.     Dim intX As Integer
    4.     Dim intY As Integer
    5.     Dim intX2 As Integer
    6.     Dim intY2 As Integer
    7.     Dim intTmpX As Integer
    8.     Dim intTmpY As Integer
    9.     Dim intDirn As Integer
    10.    
    11.     'clear maze
    12.     For intX = 1 To 59
    13.         For intY = 1 To 59
    14.             intMz(intX, intY) = 0
    15.         Next
    16.     Next
    17.    
    18.     'make border
    19.     For intA = 0 To 60
    20.         intMz(intA, 0) = 1
    21.         intMz(intA, 60) = 1
    22.         intMz(0, intA) = 1
    23.         intMz(60, intA) = 1
    24.     Next
    25.    
    26.     'generate vertices
    27.     For intX = 2 To 58 Step 2
    28.         For intY = 2 To 58 Step 2
    29.             intVertsX(intX, intY) = intX
    30.             intVertsY(intX, intY) = intY
    31.         Next
    32.     Next
    33.    
    34.     'mix up the order to draw verticies
    35.     For intX = 2 To 58 Step 2
    36.         For intY = 2 To 58 Step 2
    37.             'Int(Rnd * 29) returns a value between 0 and 28. (Int(Rnd * 29) + 1)
    38.             'returns a value between 1 and 29. 1 * 2 = 2 and 29 * 2 = 58. So the
    39.             'entire function (Int(Rnd * 29) + 1) * 2 returns a value between 2
    40.             'and 58.
    41.             intX2 = (Int(Rnd * 29) + 1) * 2
    42.             intY2 = (Int(Rnd * 29) + 1) * 2
    43.            
    44.             'To swap two variables you save the first (A) then you replace (A) with
    45.             'the other variable (B) and then you replace (B) with the saved (A)-
    46.             'variable
    47.             intTmpX = intVertsX(intX, intY)
    48.             intTmpY = intVertsY(intX, intY)
    49.             intVertsX(intX, intY) = intVertsX(intX2, intY2)
    50.             intVertsY(intX, intY) = intVertsY(intX2, intY2)
    51.             intVertsX(intX2, intY2) = intTmpX
    52.             intVertsY(intX2, intY2) = intTmpY
    53.         Next
    54.     Next
    55.  
    56.     'now draw walls
    57.     'draw a wall from each of the verticies in a random direction until another wall
    58.     'is reached
    59.     For intX = 2 To 58 Step 2
    60.         For intY = 2 To 58 Step 2
    61.             intTmpX = intVertsX(intX, intY)
    62.             intTmpY = intVertsY(intX, intY)
    63.             If intX = 2 And intY < 10 Then
    64.                 MsgBox intVertsX(intX, intY) & " " & intVertsY(intX, intY)
    65.             End If
    66.             If intMz(intTmpX, intTmpY) = 0 Then
    67.                 intDirn = Int(Rnd * 4)
    68.                 Do
    69.                     intMz(intTmpX, intTmpY) = 1
    70.                     Select Case intDirn
    71.                         Case 0: intTmpX = intTmpX - 1
    72.                         Case 1: intTmpX = intTmpX + 1
    73.                         Case 2: intTmpY = intTmpY + 1
    74.                         Case Else: intTmpY = intTmpY - 1
    75.                     End Select
    76.                    
    77.                 Loop Until intMz(intTmpX, intTmpY) = 1
    78.             End If
    79.         Next
    80.     Next
    81.  
    82. End Sub
    Globals:
    VB Code:
    1. Option Explicit
    2. Dim intMz(60, 60) As Integer
    3. Dim intVertsX(60, 60) As Integer
    4. Dim intVertsY(60, 60) As Integer
    5. Dim intCnt As Integer 'intCount
    6. Dim intWdt As Integer
    7. Dim intHgt As Integer
    8. Dim lngTimer As Long
    Last edited by McCain; Oct 20th, 2003 at 12:15 AM.
    Never argue with fools, they will only drag you down to their level, and beat you with experience.

    Q: How do you tell an experienced hacker from a novice?
    A: The latter thinks there's 1000 bytes in a kilobyte, while the former is sure there's 1024 meters in a kilometer

  9. #9
    Addicted Member NOMADMAN's Avatar
    Join Date
    Aug 2002
    Location
    Closer than you think
    Posts
    237
    Back to mine, I neglected to state WHY mine works.

    Since the recursive function starts at the beginning and visits every square that means any square is accessible from any other include the start and end.

    Something else I may have glossed over, when you're in the recursive function you should have a while loop that loops until all neighbors have been visited. But make sure to do it randomly or the maze will look the same each time

    NOMAD

  10. #10
    Fanatic Member McCain's Avatar
    Join Date
    Jan 2002
    Location
    Sweden/Denmark
    Posts
    802
    I made a few changes to the code to produce better looking mazes...
    VB Code:
    1. Private Sub CreateMaze()
    2.     Dim intX As Integer
    3.     Dim intY As Integer
    4.     Dim intX2 As Integer
    5.     Dim intY2 As Integer
    6.     Dim intTmpX As Integer
    7.     Dim intTmpY As Integer
    8.     Dim intDirn As Integer
    9.     Dim intTmpDirn As Integer
    10.     Dim intVertsX(sizeX, sizeY) As Integer
    11.     Dim intVertsY(sizeX, sizeY) As Integer
    12.    
    13.     'clear maze
    14.     For intX = 1 To sizeX - 1
    15.         For intY = 1 To sizeY - 1
    16.             intMz(intX, intY) = 0
    17.         Next
    18.     Next
    19.    
    20.     'make border
    21.     For intX = 0 To sizeX
    22.         intMz(intX, 0) = 1
    23.         intMz(intX, sizeY) = 1
    24.     Next
    25.     For intY = 0 To sizeY
    26.         intMz(0, intY) = 1
    27.         intMz(sizeX, intY) = 1
    28.     Next
    29.  
    30.    
    31.     'generate vertices
    32.     For intX = 2 To sizeX - 2 Step 2
    33.         For intY = 2 To sizeY - 2 Step 2
    34.             intVertsX(intX, intY) = intX
    35.             intVertsY(intX, intY) = intY
    36.         Next
    37.     Next
    38.    
    39.     'mix up the order to draw verticies
    40.     For intX = 2 To sizeX - 2 Step 2
    41.         For intY = 2 To sizeY - 2 Step 2
    42.             'Let's say that sizeX and sizeY are both 60, then is
    43.             '(sizeX / 2 - 1) = 29 and (sizeY / 2 - 1) = 29 as well.
    44.             '   Int(Rnd * 29) returns a value between 0 and 28. (Int(Rnd * 29) + 1)
    45.             'returns a value between 1 and 29. 1 * 2 = 2 and 29 * 2 = 58. So the
    46.             'entire function (Int(Rnd * 29) + 1) * 2 returns a value between 2
    47.             'and 58.
    48.             intX2 = (Int(Rnd * (sizeX / 2 - 1)) + 1) * 2
    49.             intY2 = (Int(Rnd * (sizeY / 2 - 1)) + 1) * 2
    50.            
    51.             'To swap two variables you save the first (A) then you replace (A) with
    52.             'the other variable (B) and then you replace (B) with the saved (A)-
    53.             'variable
    54.             intTmpX = intVertsX(intX, intY)
    55.             intTmpY = intVertsY(intX, intY)
    56.             intVertsX(intX, intY) = intVertsX(intX2, intY2)
    57.             intVertsY(intX, intY) = intVertsY(intX2, intY2)
    58.             intVertsX(intX2, intY2) = intTmpX
    59.             intVertsY(intX2, intY2) = intTmpY
    60.         Next
    61.     Next
    62.  
    63.     'Now draw walls.
    64.     'Draw a wall from each of the verticies in a random direction until another wall
    65.     'is reached.
    66.     '   For the best looking maze we don't want any walls going all the way across
    67.     'the maze, so if we're close to an edge, we make it more likely for the wall to
    68.     'go to that closest wall.
    69.     For intX = 2 To sizeX - 2 Step 2
    70.         For intY = 2 To sizeY - 2 Step 2
    71.             intTmpX = intVertsX(intX, intY)
    72.             intTmpY = intVertsY(intX, intY)
    73.             If intMz(intTmpX, intTmpY) = 0 Then
    74.                 ' Top Left ----------
    75.                 If intX < sizeX / 3 And intY < sizeY / 3 Then
    76.                     intTmpDirn = Int(Rnd * 11)
    77.                     If intTmpDirn <= 4 Then
    78.                         intDirn = 0
    79.                     ElseIf intTmpDirn >= 5 And intTmpDirn <= 8 Then
    80.                         intDirn = 3
    81.                     ElseIf intTmpDirn = 9 Then
    82.                         intDirn = 2
    83.                     Else
    84.                         intDirn = 1
    85.                     End If
    86.                 ' Left --------------
    87.                 ElseIf intX < sizeX / 3 And intY >= sizeY / 3 And intY <= sizeY / 3 Then
    88.                     intTmpDirn = Int(Rnd * 8)
    89.                     If intTmpDirn <= 4 Then
    90.                         intDirn = 0
    91.                     ElseIf intTmpDirn = 5 Then
    92.                         intDirn = 1
    93.                     ElseIf intTmpDirn = 6 Then
    94.                         intDirn = 2
    95.                     Else
    96.                         intDirn = 3
    97.                     End If '                     = 40 if sizeY = 60
    98.                 ' Bottom Left -----------          /------^------\
    99.                 ElseIf intX < sizeX / 3 And intY > sizeY * (2 / 3) Then
    100.                     intTmpDirn = Int(Rnd * 11)
    101.                     If intTmpDirn <= 4 Then
    102.                         intDirn = 0
    103.                     ElseIf intTmpDirn >= 5 And intTmpDirn <= 8 Then
    104.                         intDirn = 2
    105.                     ElseIf intTmpDirn = 9 Then
    106.                         intDirn = 1
    107.                     Else
    108.                         intDirn = 3
    109.                     End If
    110.                 ' Bottom ------------
    111.                 ElseIf intX >= sizeX / 3 And intX <= sizeX * (2 / 3) And intY > sizeY * (2 / 3) Then
    112.                     intTmpDirn = Int(Rnd * 8)
    113.                     If intTmpDirn <= 4 Then
    114.                         intDirn = 2
    115.                     ElseIf intTmpDirn = 5 Then
    116.                         intDirn = 0
    117.                     ElseIf intTmpDirn = 6 Then
    118.                         intDirn = 1
    119.                     Else
    120.                         intDirn = 3
    121.                     End If
    122.                 ' Bottom Right ---------
    123.                 ElseIf intX > sizeX * (2 / 3) And intY > sizeY * (2 / 3) Then
    124.                     intTmpDirn = Int(Rnd * 11)
    125.                     If intTmpDirn <= 4 Then
    126.                         intDirn = 1
    127.                     ElseIf intTmpDirn >= 5 And intTmpDirn <= 8 Then
    128.                         intDirn = 2
    129.                     ElseIf intTmpDirn = 9 Then
    130.                         intDirn = 0
    131.                     Else
    132.                         intDirn = 3
    133.                     End If
    134.                 ' Right ----------
    135.                 ElseIf intX > sizeX * (2 / 3) And intY >= sizeY / 3 And intY <= sizeY * (2 / 3) Then
    136.                     intTmpDirn = Int(Rnd * 8)
    137.                     If intTmpDirn <= 4 Then
    138.                         intDirn = 1
    139.                     ElseIf intTmpDirn = 5 Then
    140.                         intDirn = 0
    141.                     ElseIf intTmpDirn = 6 Then
    142.                         intDirn = 2
    143.                     Else
    144.                         intDirn = 3
    145.                     End If
    146.                 ' Top Right ----------
    147.                 ElseIf intX > sizeX * (2 / 3) And intY < sizeY / 3 Then
    148.                     intTmpDirn = Int(Rnd * 11)
    149.                     If intTmpDirn <= 4 Then
    150.                         intDirn = 1
    151.                     ElseIf intTmpDirn >= 5 And intTmpDirn <= 8 Then
    152.                         intDirn = 3
    153.                     ElseIf intTmpDirn = 9 Then
    154.                         intDirn = 0
    155.                     Else
    156.                         intDirn = 2
    157.                     End If
    158.                 ' Top -------------
    159.                 ElseIf intX >= sizeX / 3 And intX <= sizeX * (2 / 3) And intY < sizeY / 3 Then
    160.                     intTmpDirn = Int(Rnd * 8)
    161.                     If intTmpDirn <= 4 Then
    162.                         intDirn = 3
    163.                     ElseIf intTmpDirn = 5 Then
    164.                         intDirn = 0
    165.                     ElseIf intTmpDirn = 6 Then
    166.                         intDirn = 1
    167.                     Else
    168.                         intDirn = 2
    169.                     End If
    170.                 ' Middle -----------
    171.                 Else
    172.                     intDirn = Int(Rnd * 4)
    173.                 End If
    174.                
    175.                 Do
    176.                     intMz(intTmpX, intTmpY) = 1
    177.                     Select Case intDirn
    178.                         Case 0: intTmpX = intTmpX - 1
    179.                         Case 1: intTmpX = intTmpX + 1
    180.                         Case 2: intTmpY = intTmpY + 1
    181.                         Case Else: intTmpY = intTmpY - 1
    182.                     End Select
    183.  
    184.                 Loop Until intMz(intTmpX, intTmpY) = 1
    185.             End If
    186.         Next
    187.     Next
    188.  
    189. End Sub
    Never argue with fools, they will only drag you down to their level, and beat you with experience.

    Q: How do you tell an experienced hacker from a novice?
    A: The latter thinks there's 1000 bytes in a kilobyte, while the former is sure there's 1024 meters in a kilometer

  11. #11

    Thread Starter
    Addicted Member
    Join Date
    Mar 2002
    Location
    St. Louis MO
    Posts
    129

    Random Mazes

    I've been looking at links to maze generation.
    I had no idea there was so much stuff out there. It's all pretty good to.
    Here's a couple of links I've found to be very interesting. I'm not sure I'm up to tackeling them in VB, but it looks to interesting to ignore.

    http://www.mazeworks.com/mazegen/index.htm

    http://www.astrolog.org/labyrnth/algrithm.htm

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width