Advertisement
eigenbom

Maze

Oct 29th, 2016
518
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.66 KB | None | 0 0
  1. # Basic Maze generator
  2. # @eigenbom
  3.  
  4. from random import randint, sample
  5. from operator import xor
  6.  
  7. TITLE = 'MAZE'
  8.  
  9. CELL_SIZE = 16
  10. ROOMS_WIDE = 18
  11. ROOMS_HIGH = 18
  12. CELLS_WIDE = 2 * ROOMS_WIDE + 1
  13. CELLS_HIGH = 2 * ROOMS_HIGH + 1
  14. WIDTH = CELL_SIZE * CELLS_WIDE
  15. HEIGHT = CELL_SIZE * CELLS_HIGH
  16. ROOM, WALL, CORRIDOR = 0, 1, 2
  17.  
  18. valid_rooms = set()  
  19. cells = None
  20. generator = None
  21. timer = 0
  22.  
  23. def setup_rooms():
  24.     """Create a donut-shaped world for rooms to live"""
  25.     global valid_rooms
  26.     for i in range(ROOMS_WIDE):
  27.         for j in range(ROOMS_HIGH):
  28.             if (i < ROOMS_WIDE/3 or i >= 2*ROOMS_WIDE/3) or (j < ROOMS_HIGH/3 or j >= 2*ROOMS_HIGH/3):
  29.                 valid_rooms.add((i,j))
  30.      
  31. def adjacent_walls(room):    
  32.     walls = set()    
  33.     for dir in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
  34.         if (room[0]+dir[0], room[1]+dir[1]) in valid_rooms:
  35.         # if 0 <= room[0]+dir[0] < ROOMS_WIDE and 0 <= room[1]+dir[1] < ROOMS_HIGH:
  36.             walls.add((dir[0], dir[1], room))
  37.     return walls
  38.                    
  39. def create_maze():
  40.     global cells    
  41.     open_walls = set()
  42.     start = sample(valid_rooms, 1)[0]
  43.     path = set({start})
  44.     walls = adjacent_walls(start)
  45.     while len(walls)>0:
  46.         wall = sample(walls, 1)[0]
  47.         dx, dy, room = wall
  48.         r1 = room[0], room[1]
  49.         r2 = room[0] + dx, room[1] + dy
  50.         suitable = xor(r1 in path, r2 in path)
  51.         if suitable:
  52.             r = r2 if r1 in path else r1
  53.             if r is r1:
  54.                 open_walls.add((dx, dy, r))
  55.             else:
  56.                 open_walls.add((-dx, -dy, r))
  57.             path.add(r)
  58.             walls.update(adjacent_walls(r))
  59.         walls.remove(wall)
  60.  
  61.         # update cells
  62.         for rx, ry in path:
  63.             c, v = cells[1 + 2*ry][1 + 2*rx]
  64.             if c != ROOM:
  65.                 v = 0
  66.             else:
  67.                 v = v + 1
  68.             cells[1 + 2*ry][1 + 2*rx] = (ROOM, v)
  69.         for ow in open_walls:
  70.             dx, dy, r = ow
  71.             cells[1 + 2*r[1] + dy][1 + 2*r[0] + dx] = (CORRIDOR, 0)
  72.         yield
  73.  
  74. def generate():
  75.     global cells, generator
  76.     cells = [[(WALL, 0) for i in range(CELLS_WIDE)] for j in range(CELLS_HIGH)]
  77.     setup_rooms()
  78.     generator = create_maze()
  79.  
  80. def update(dt):
  81.     global timer, generator
  82.     timer += dt
  83.     if timer > 0.001 and generator:
  84.         timer = 0    
  85.         try:
  86.             next(generator)
  87.         except StopIteration:
  88.             generator = None
  89.             for i in range(CELLS_WIDE):
  90.                 for j in range(CELLS_HIGH):
  91.                     cells[j][i] = cells[j][i][0], 0
  92.  
  93. def draw():
  94.     screen.fill((42, 52, 67))
  95.     if cells is None:
  96.         return
  97.    
  98.     # corridors    
  99.     for i in range(CELLS_WIDE):
  100.         for j in range(CELLS_HIGH):
  101.             cell, value = cells[j][i]
  102.             if cell == CORRIDOR:
  103.                 sz = int(0.75 * CELL_SIZE)
  104.                 rect = Rect((i*CELL_SIZE + (CELL_SIZE - sz)/2, j*CELL_SIZE + (CELL_SIZE - sz)/2), (sz, sz))
  105.                 colour = 131, 117, 135
  106.                 screen.draw.filled_rect(rect, colour)
  107.     # rooms
  108.     for i in range(CELLS_WIDE):
  109.         for j in range(CELLS_HIGH):
  110.             cell, value = cells[j][i]
  111.             if cell == ROOM:
  112.                 colour = 131, 117, 135                
  113.                 screen.draw.filled_circle(((i+0.5)*CELL_SIZE, (j+0.5)*CELL_SIZE), int(0.8*CELL_SIZE), colour)
  114.                 if 0 < value < 40:
  115.                     colour = 132, 219, 252
  116.                     screen.draw.filled_circle(((i+0.5)*CELL_SIZE, (j+0.5)*CELL_SIZE), int(0.5*CELL_SIZE), colour)
  117.                    
  118. def on_key_down():
  119.     generate()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement