Advertisement
eigenbom

Circle Maze

Oct 29th, 2016
619
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.35 KB | None | 0 0
  1. # Circular maze generator
  2. # @eigenbom
  3.  
  4. from random import randint, sample
  5. from operator import xor
  6. import math
  7. import pygame
  8.  
  9. TITLE = 'MAZE'
  10.  
  11. WIDTH = 540
  12. HEIGHT = 540
  13.  
  14. NUM_RINGS = 8
  15. ROOMS_PER_RING = 64
  16.  
  17. ROOM, WALL, CORRIDOR = 0, 1, 2
  18.  
  19. valid_rooms = set()
  20. maze = None # list of room pairs indicating a path
  21. generator = None
  22. timer = 0
  23.  
  24. def setup_rooms():
  25.     global valid_rooms
  26.     for i in range(ROOMS_PER_RING):
  27.         for j in range(NUM_RINGS):
  28.             valid_rooms.add((i,j))
  29.      
  30. def adjacent_walls(room):
  31.     walls = set()    
  32.     for dir in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
  33.         if ((room[0]+dir[0])%ROOMS_PER_RING, room[1]+dir[1]) in valid_rooms:
  34.             walls.add((dir[0], dir[1], room))
  35.     return walls
  36.                    
  37. def create_maze():
  38.     global maze    
  39.     open_walls = set()
  40.     start = sample(valid_rooms, 1)[0]
  41.     path = set({start})
  42.     walls = adjacent_walls(start)
  43.     while len(walls)>0:
  44.         wall = sample(walls, 1)[0]
  45.         dx, dy, room = wall
  46.         r1 = room[0], room[1]
  47.         r2 = (room[0] + dx) % ROOMS_PER_RING, (room[1] + dy) % NUM_RINGS
  48.         suitable = xor(r1 in path, r2 in path)
  49.         if suitable:
  50.             r = r2 if r1 in path else r1
  51.             if r is r1:
  52.                 open_walls.add((dx, dy, r))
  53.             else:
  54.                 open_walls.add((-dx, -dy, r))
  55.             path.add(r)
  56.             maze.append((r1, r2, 0))
  57.             walls.update(adjacent_walls(r))
  58.         walls.remove(wall)
  59.        
  60.         for i in range(len(maze)):
  61.             maze[i] = maze[i][0], maze[i][1], maze[i][2] + 1
  62.         yield
  63.  
  64. def generate(instantly = False):
  65.     global maze, generator
  66.     maze = list()
  67.     setup_rooms()
  68.     generator = create_maze()
  69.     if instantly:
  70.         while generator:
  71.             try:
  72.                 next(generator)
  73.             except StopIteration:
  74.                 generator = None
  75.  
  76. generate(True)
  77.  
  78. def update(dt):
  79.     global timer, generator
  80.     timer += dt
  81.     if timer > 0.0001 and generator:
  82.         timer = 0    
  83.         try:
  84.             next(generator)
  85.         except StopIteration:
  86.             generator = None
  87.  
  88. def lerp(a, b, t):
  89.     return a*(1-t) + b*t
  90.            
  91. def room_position(i1, j1):            
  92.     center = WIDTH/2, HEIGHT/2
  93.     inner_radius = WIDTH/4
  94.     outer_radius = WIDTH/2.5
  95.     rad1, th1 = inner_radius + (outer_radius - inner_radius)* j1 / (NUM_RINGS-1), math.fmod(1 + (i1 / ROOMS_PER_RING), 1) * (2 * math.pi)
  96.     x1, y1 = center[0] + rad1 * math.cos(th1), center[1] + rad1 * math.sin(th1)
  97.     return x1, y1
  98.        
  99. def draw():
  100.     screen.fill((0, 0, 0))
  101.     if maze is None:
  102.         return
  103.    
  104.     # render..
  105.     for (r1, r2, v) in maze:
  106.         # draw line between these rooms        
  107.         if v > 0 and v < 40:
  108.             colour = 255, 255, 255
  109.         else:
  110.             colour = 128, 128, 128        
  111.         p1 = room_position(*r1)
  112.         p2 = room_position(*r2)
  113.         screen.draw.line(p1, p2, colour)
  114.         sz1 = int(lerp(2, 4, r1[1] / (NUM_RINGS-1)))
  115.         sz2 = int(lerp(2, 4, r2[1] / (NUM_RINGS-1)))
  116.         screen.draw.filled_circle(p1, sz1, colour)
  117.         screen.draw.filled_circle(p2, sz2, colour)
  118.     new_s = pygame.transform.laplacian(screen.surface)
  119.     new_s.set_alpha(128)
  120.     screen.blit(new_s, (0,0))
  121.                    
  122. def on_key_down():
  123.     generate()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement