Advertisement
asweigart

Maze Generator

Sep 14th, 2021
190
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.51 KB | None | 0 0
  1. import random
  2.  
  3. WIDTH = 39 # Width of the maze (must be odd).
  4. HEIGHT = 19 # Height of the maze (must be odd).
  5. SEED = 1
  6. random.seed(SEED)
  7. assert WIDTH % 2 == 1 and WIDTH > 2
  8. assert HEIGHT % 2 == 1 and HEIGHT > 2
  9.  
  10. # Use these characters for displaying the maze:
  11. EMPTY = ' '
  12. MARK = '@'
  13. WALL = chr(9608) # Character 9608 is '█'
  14. NORTH, SOUTH, EAST, WEST = 'n', 's', 'e', 'w'
  15.  
  16. def displayMaze(maze, markX=None, markY=None):
  17. """Displays the maze data structure in the maze argument. The
  18. markX and markY arguments are coordinates of the current
  19. '@' location of the algorithm as it generates the maze."""
  20. for y in range(HEIGHT):
  21. for x in range(WIDTH):
  22. if markX == x and markY == y:
  23. # Display the '@' mark here:
  24. print(MARK, end='')
  25. else:
  26. # Display the wall or empty space:
  27. print(maze[(x, y)], end='')
  28. print() # Print a newline after printing the row.
  29.  
  30. def visit(x, y):
  31. """"Carve out" empty spaces in the maze at x, y and then
  32. recursively move to neighboring unvisited spaces. This
  33. function backtracks when the mark has reached a dead end."""
  34. global hasVisited, maze
  35.  
  36. maze[(x, y)] = EMPTY # "Carve out" the space at x, y.
  37. displayMaze(maze, x, y) # Display the maze as we generate it.
  38. print('\n\n')
  39.  
  40. while True:
  41. # Check which neighboring spaces adjacent to
  42. # the mark have not been visited already:
  43. unvisitedNeighbors = []
  44. if y > 1 and (x, y - 2) not in hasVisited:
  45. unvisitedNeighbors.append(NORTH)
  46. if y < HEIGHT - 2 and (x, y + 2) not in hasVisited:
  47. unvisitedNeighbors.append(SOUTH)
  48. if x > 1 and (x - 2, y) not in hasVisited:
  49. unvisitedNeighbors.append(WEST)
  50. if x < WIDTH - 2 and (x + 2, y) not in hasVisited:
  51. unvisitedNeighbors.append(EAST)
  52.  
  53. if len(unvisitedNeighbors) == 0:
  54. # BASE CASE
  55. # All neighboring spaces have been visited, so this is a
  56. # dead end. Backtrack to an earlier space:
  57. return
  58. else:
  59. # RECURSIVE CASE
  60. # Randomly pick an unvisited neighbor to visit:
  61. nextIntersection = random.choice(unvisitedNeighbors)
  62.  
  63. # Move the mark to an unvisited neighboring space:
  64. if nextIntersection == NORTH:
  65. nextX = x
  66. nextY = y - 2
  67. maze[(x, y - 1)] = EMPTY # Connecting hallway.
  68. elif nextIntersection == SOUTH:
  69. nextX = x
  70. nextY = y + 2
  71. maze[(x, y + 1)] = EMPTY # Connecting hallway.
  72. elif nextIntersection == WEST:
  73. nextX = x - 2
  74. nextY = y
  75. maze[(x - 1, y)] = EMPTY # Connecting hallway.
  76. elif nextIntersection == EAST:
  77. nextX = x + 2
  78. nextY = y
  79. maze[(x + 1, y)] = EMPTY # Connecting hallway.
  80.  
  81. hasVisited.append((nextX, nextY)) # Mark as visited.
  82. visit(nextX, nextY) # Recursively visit this space.
  83.  
  84.  
  85. # Create the filled-in maze data structure to start:
  86. maze = {}
  87. for x in range(WIDTH):
  88. for y in range(HEIGHT):
  89. maze[(x, y)] = WALL # Every space is a wall at first.
  90.  
  91. # Carve out the paths in the maze data structure:
  92. hasVisited = [(1, 1)] # Start by visiting the top left corner.
  93. visit(1, 1)
  94.  
  95. # Display the final resulting maze data structure:
  96. displayMaze(maze)
  97.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement