Advertisement
faubiguy

generatemaze.py

Apr 2nd, 2016
160
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.67 KB | None | 0 0
  1. #!/usr/bin/python3
  2. import sys, argparse, random
  3.  
  4. argparser = argparse.ArgumentParser(description='ASCII Maze Generator')
  5. argparser.add_argument('width', type=int, help='Width of the maze, in cells')
  6. argparser.add_argument('height', type=int, help='Height of the maze, in cells')
  7. argparser.add_argument('--characters', default=None, help='Characters to use in place of \'+|- \', in that order')
  8. argparser.add_argument('--seed', type=int, default=None, help='Seed for the random number generator')
  9. argparser.add_argument('--fullwidth', action='store_true', help='Use fullwidth defaults if no characters specified')
  10. args = argparser.parse_args()
  11.  
  12. # Set the default character set if none specified
  13. if args.characters is None:
  14.     if args.fullwidth:
  15.         args.characters = ' -|+'
  16.     else:
  17.         args.characters = ' -|+'
  18.  
  19. # Directions array, for finding adjacent cells
  20. directions = [(-1, 0), (0, -1), (1, 0), (0, 1)]
  21.  
  22. def generateMaze(width, height, chars, seed=None):
  23.     """Generate a maze using a depth-first search based algorithm"""
  24.     rng = random.Random()
  25.     if seed is not None:
  26.         rng.seed(seed)
  27.     # Create initial maze 2d array with no empty space
  28.     maze = [[1]*(2*width+1) for _ in range(2*height+1)]
  29.     # Add empty space for each cell
  30.     for x in range(width):
  31.         for y in range(height):
  32.             maze[2*y+1][2*x+1] = 0
  33.  
  34.     cells = [] # Stack containing visited cells
  35.     visited = 1 # Number of visited cells
  36.     # Select random cell to start at
  37.     currentCell = [rng.randrange(width), rng.randrange(height)]
  38.     while visited < width * height:
  39.         adjacent = []
  40.         # Find adjacent cells to current one that haven't had any walls removed yet
  41.         for d in directions:
  42.             cell = currentCell.copy()
  43.             cell[0] += d[0]
  44.             cell[1] += d[1]
  45.             # Skip cells outside of the maze area
  46.             if not ((0 <= cell[0] < height) and (0 <= cell[1] < width)):
  47.                 continue
  48.             if all(maze[cell[0]*2+1+z[0]][cell[1]*2+1+z[1]] for z in directions):
  49.                 # All walls of cell still exist, so add to list along with direction
  50.                 adjacent.append((cell, d));
  51.         if adjacent:
  52.             cell, d = rng.choice(adjacent)
  53.             # Remove the wall between the current cell and random adjacent one
  54.             maze[currentCell[0]*2+1+d[0]][currentCell[1]*2+1+d[1]] = 0
  55.             cells.append(currentCell)
  56.             currentCell = cell;
  57.             visited += 1
  58.         else:
  59.             currentCell = cells.pop()
  60.    
  61.     # Translate binary maze to ascii/unicode characters
  62.     char_maze = []
  63.     for y in range(2*height+1):
  64.         row = ''
  65.         for x in range(2*width+1):
  66.             if not maze[y][x]:
  67.                 # Character is empty space, use space character
  68.                 row += chars[0]
  69.             else:
  70.                 # Character is a wall
  71.                 vertical = False
  72.                 horizontal = False
  73.                 # Determine whether wall has adjacent walls horizontally or vertically
  74.                 for i, d in enumerate(directions):
  75.                     ny, nx = y+d[0], x+d[1]
  76.                     if not ((0 <= ny < 2*height+1) and (0 <= nx < 2*width+1)):
  77.                         continue
  78.                     if i%2 == 0 and maze[ny][nx]:
  79.                         vertical = True
  80.                     if i%2 == 1 and maze[ny][nx]:
  81.                         horizontal = True
  82.                 # Add corresponding character for wall
  83.                 row += chars[horizontal + 2*vertical]
  84.         char_maze.append(row)
  85.  
  86.     return '\n'.join(char_maze)
  87.  
  88. print(generateMaze(args.width, args.height, args.characters, args.seed))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement