"""Maze Gen, a scrolling terminal animation by Al Sweigart.""" import random, shutil, sys, time DELAY = 0.04 # Pause between rows in seconds. WIDTH = None # None uses the terminal width. JOIN_CHANCE = 0.5 # Chance that neighboring cells are joined. WALL, PATH = '█', ' ' def get_width(width=None): result = shutil.get_terminal_size()[0] if width is None else width return result - 1 if sys.platform == 'win32' else result def maze_gen(delay=DELAY, width=WIDTH): maze_width = max(3, (get_width(width) - 1) // 2) sets, next_set, first_row = list(range(maze_width)), maze_width, True while True: current_width = get_width(width); maze_width = max(3, (current_width - 1) // 2) while len(sets) < maze_width: sets.append(next_set); next_set += 1 sets = sets[:maze_width]; right_walls = [True] * maze_width for i in range(maze_width - 1): if sets[i] != sets[i + 1] and random.random() < JOIN_CHANCE: right_walls[i] = False; old_set, new_set = sets[i + 1], sets[i] sets = [new_set if item == old_set else item for item in sets] if first_row: print((WALL * (maze_width * 2 + 1))[:current_width]); time.sleep(delay); first_row = False print((WALL + ''.join(PATH + (WALL if i == maze_width - 1 or right_walls[i] else PATH) for i in range(maze_width)))[:current_width]); time.sleep(delay) bottom_walls, groups = [True] * maze_width, {} for i, set_id in enumerate(sets): groups.setdefault(set_id, []).append(i) for cells in groups.values(): opened = [cell for cell in cells if random.random() < JOIN_CHANCE] if not opened: opened = [random.choice(cells)] for cell in opened: bottom_walls[cell] = False print((WALL + ''.join((WALL if bottom_walls[i] else PATH) + WALL for i in range(maze_width)))[:current_width]); time.sleep(delay) for i in range(maze_width): if bottom_walls[i]: sets[i] = next_set; next_set += 1 try: maze_gen() except KeyboardInterrupt: print('Maze Gen, by Al Sweigart al@inventwithpython.com')