🐭
┃┣━━━┳━━━━┳━━┓
┃┗┓┏┛┃╻╺━━┛╺┓┃
┣┓┃┗┓┗┻━━━┳╸┃┃
┃┃┣╸┣━━┳━┓┗━┛┃
┃┃┃┏┛┏╸┃╻┣━┳╸┃
┃┗━┫╻┣━━┫┗╸┃┏┫
┃┏━┫┃┃╺┓┗━┓┃┃┃
┃┃┃┃┃┗┓┗━┓┗┻╸┃
┗━┫┏┻━━━━┻━━━┛
🧀
http://xahlee.info/comp/unicode_drawing_shapes.html by Xah Lee
Jacqueline de Jong (one of the makers of the Situationist Times) talking about printed mazes with overlay.
The PDFs of the Situationist Times are available on Monoskop!
Nick Montfort and others compilation of maze generation and other simple scripts from early home computing.
https://hub.xpub.nl/bootleglibrary/book/583
Some links to nice parts:
The terms “maze” and “labyrinth” are generally synonyms in colloquial English. Still, many scholars and historians have argued over the distinction between these two terms. In the most popular proposed distinction, “labyrinth” refers only to single-path (unicursal) structures, while “maze” refers only to branching-path (multicursal) structures.In this book, the terms “maze” and “labyrinth” are not used to distinguish two different categories of structure or image. Instead, the two terms indicate a single conceptual category, with this book primarily using the term “maze” for both
AND an interesting link to the conversation about popular culture and the middle-class:
This notebook is based on the Medium article "Fun with Python part 1: Maze Generator" written by Orestis Zekai in 2020.
It is a nice tutorial which talks you through a Python implementation of a maze generator.
You can find the tutorial here: https://medium.com/swlh/fun-with-python-1-maze-generator-931639b4fb7e
The maze generator is based on a randomized version of Prim's algorithm, which is one of the maze algorithms that is used to generate a maze:
from IPython.display import IFrame
IFrame("maze-generator-on-paper.pdf", width=600, height=400)
The code below is a slightly adapted version of maze.py
written by Orestis Zekai: https://github.com/OrWestSide/python-scripts/blob/master/maze.py
You can use the code to generate custom mazes.
Change the following variables in the code, to make your maze bigger or smaller and to change how your maze looks like!
# --------------------------
wall_tile = "▓"
cell_tile = "░"
height = 11
width = 27
# --------------------------
NOTE: The code below is a slightly different version of the code from the tutorial. The variable names are changed in the double for-loops, to make them connect to the other canvas examples in the other notebooks. For example, a for loop to move block by block through the maze is written below in the following way, using y
and x
to refer to the coordinates of a block:
for y in range(height):
for x in range(width):
if (maze[y][x] == "u"):
print(unvisited, end="")
# Maze generator -- Randomized Prim Algorithm
## Imports
import random
## Functions
def printMaze(maze):
for y in range(height):
for x in range(width):
if (maze[y][x] == "u"):
print(unvisited, end="")
elif (maze[y][x] == "c"):
print(cell_tile, end="")
else:
print(wall_tile, end="")
print("")
# Find number of surrounding cells (c) of a random wall
def surroundingCells(rand_wall):
s_cells = 0
if (maze[rand_wall[0]-1][rand_wall[1]] == "c"): # cell below the random wall (y-1)
s_cells += 1
if (maze[rand_wall[0]+1][rand_wall[1]] == "c"): # cell above the random wall (y+1)
s_cells += 1
if (maze[rand_wall[0]][rand_wall[1]-1] == "c"): # cell left from random wall (x-1)
s_cells +=1
if (maze[rand_wall[0]][rand_wall[1]+1] == "c"): # cell right from random wall (x+1)
s_cells += 1
return s_cells # how many of the four surrounding cells are marked as "c"?
## Main code
# Init variables
# --------------------------
wall_tile = "▓"
cell_tile = "░"
height = 11
width = 27
# --------------------------
wall = "w"
cell = "c"
unvisited = "u"
maze = []
# Denote all cells as unvisited
for y in range(height):
line = []
for x in range(width):
line.append(unvisited)
maze.append(line)
# Randomize starting point and set it a cell
starting_height = int(random.random()*height) # picks a random number in the range of the height
starting_width = int(random.random()*width) # same with width
# We need to make sure that we do not start on a cell that is on the edge of the maze:
if (starting_height == 0):
starting_height += 1 # if the cell is on the bottom edge of the maze, add 1
if (starting_height == height-1):
starting_height -= 1 # if the cell is on the top edge of the maze, minus 1
if (starting_width == 0):
starting_width += 1 # if the cell is on the left edge of the maze, add 1
if (starting_width == width-1):
starting_width -= 1 # if the cell is on the right edge of the maze, minus 1
# shoudnt we rewrite the code because the chance to get a 1 is now double as high? should it be something like:
# if starting_height == 0 : try again to pick a random number
# or: directly pick a random int(random.random()*len(height))-1
#??????????????????
# Mark it as cell and add surrounding walls to the list
maze[starting_height][starting_width] = cell
walls = []
walls.append([starting_height - 1, starting_width])
walls.append([starting_height + 1, starting_width])
walls.append([starting_height, starting_width - 1])
walls.append([starting_height, starting_width + 1])
# mark the surrounding cells as walls
maze[starting_height-1][starting_width] = "w"
maze[starting_height][starting_width - 1] = "w"
maze[starting_height][starting_width + 1] = "w"
maze[starting_height + 1][starting_width] = "w"
# While there are walls in the wall-list pick a random wall from the list
while (walls):
# Pick a random wall
rand_wall = walls[int(random.random()*len(walls))-1]
# Check if it is a left wall
if (rand_wall[1] != 0):
if (maze[rand_wall[0]][rand_wall[1]-1] == "u" and maze[rand_wall[0]][rand_wall[1]+1] == "c"):
# Find the number of surrounding cells
s_cells = surroundingCells(rand_wall)
if (s_cells < 2):
# mark the new path
maze[rand_wall[0]][rand_wall[1]] = "c"
# Mark the new walls
# Upper cell
if (rand_wall[0] != 0):
if (maze[rand_wall[0]-1][rand_wall[1]] != "c"):
maze[rand_wall[0]-1][rand_wall[1]] = "w"
if ([rand_wall[0]-1, rand_wall[1]] not in walls):
walls.append([rand_wall[0]-1, rand_wall[1]])
# Bottom cell
if (rand_wall[0] != height-1):
if (maze[rand_wall[0]+1][rand_wall[1]] != "c"):
maze[rand_wall[0]+1][rand_wall[1]] = "w"
if ([rand_wall[0]+1, rand_wall[1]] not in walls):
walls.append([rand_wall[0]+1, rand_wall[1]])
# Leftmost cell
if (rand_wall[1] != 0):
if (maze[rand_wall[0]][rand_wall[1]-1] != "c"):
maze[rand_wall[0]][rand_wall[1]-1] = "w"
if ([rand_wall[0], rand_wall[1]-1] not in walls):
walls.append([rand_wall[0], rand_wall[1]-1])
# Delete wall
for wall in walls:
if (wall[0] == rand_wall[0] and wall[1] == rand_wall[1]):
walls.remove(wall)
continue
# Check if it is an upper wall
if (rand_wall[0] != 0):
if (maze[rand_wall[0]-1][rand_wall[1]] == "u" and maze[rand_wall[0]+1][rand_wall[1]] == "c"):
s_cells = surroundingCells(rand_wall)
if (s_cells < 2):
# Denote the new path
maze[rand_wall[0]][rand_wall[1]] = "c"
# Mark the new walls
# Upper cell
if (rand_wall[0] != 0):
if (maze[rand_wall[0]-1][rand_wall[1]] != "c"):
maze[rand_wall[0]-1][rand_wall[1]] = "w"
if ([rand_wall[0]-1, rand_wall[1]] not in walls):
walls.append([rand_wall[0]-1, rand_wall[1]])
# Leftmost cell
if (rand_wall[1] != 0):
if (maze[rand_wall[0]][rand_wall[1]-1] != "c"):
maze[rand_wall[0]][rand_wall[1]-1] = "w"
if ([rand_wall[0], rand_wall[1]-1] not in walls):
walls.append([rand_wall[0], rand_wall[1]-1])
# Rightmost cell
if (rand_wall[1] != width-1):
if (maze[rand_wall[0]][rand_wall[1]+1] != "c"):
maze[rand_wall[0]][rand_wall[1]+1] = "w"
if ([rand_wall[0], rand_wall[1]+1] not in walls):
walls.append([rand_wall[0], rand_wall[1]+1])
# Delete wall
for wall in walls:
if (wall[0] == rand_wall[0] and wall[1] == rand_wall[1]):
walls.remove(wall)
continue
# Check the bottom wall
if (rand_wall[0] != height-1):
if (maze[rand_wall[0]+1][rand_wall[1]] == "u" and maze[rand_wall[0]-1][rand_wall[1]] == "c"):
s_cells = surroundingCells(rand_wall)
if (s_cells < 2):
# Denote the new path
maze[rand_wall[0]][rand_wall[1]] = "c"
# Mark the new walls
if (rand_wall[0] != height-1):
if (maze[rand_wall[0]+1][rand_wall[1]] != "c"):
maze[rand_wall[0]+1][rand_wall[1]] = "w"
if ([rand_wall[0]+1, rand_wall[1]] not in walls):
walls.append([rand_wall[0]+1, rand_wall[1]])
if (rand_wall[1] != 0):
if (maze[rand_wall[0]][rand_wall[1]-1] != "c"):
maze[rand_wall[0]][rand_wall[1]-1] = "w"
if ([rand_wall[0], rand_wall[1]-1] not in walls):
walls.append([rand_wall[0], rand_wall[1]-1])
if (rand_wall[1] != width-1):
if (maze[rand_wall[0]][rand_wall[1]+1] != "c"):
maze[rand_wall[0]][rand_wall[1]+1] = "w"
if ([rand_wall[0], rand_wall[1]+1] not in walls):
walls.append([rand_wall[0], rand_wall[1]+1])
# Delete wall
for wall in walls:
if (wall[0] == rand_wall[0] and wall[1] == rand_wall[1]):
walls.remove(wall)
continue
# Check the right wall
if (rand_wall[1] != width-1):
if (maze[rand_wall[0]][rand_wall[1]+1] == "u" and maze[rand_wall[0]][rand_wall[1]-1] == "c"):
s_cells = surroundingCells(rand_wall)
if (s_cells < 2):
# Denote the new path
maze[rand_wall[0]][rand_wall[1]] = "c"
# Mark the new walls
if (rand_wall[1] != width-1):
if (maze[rand_wall[0]][rand_wall[1]+1] != "c"):
maze[rand_wall[0]][rand_wall[1]+1] = "w"
if ([rand_wall[0], rand_wall[1]+1] not in walls):
walls.append([rand_wall[0], rand_wall[1]+1])
if (rand_wall[0] != height-1):
if (maze[rand_wall[0]+1][rand_wall[1]] != "c"):
maze[rand_wall[0]+1][rand_wall[1]] = "w"
if ([rand_wall[0]+1, rand_wall[1]] not in walls):
walls.append([rand_wall[0]+1, rand_wall[1]])
if (rand_wall[0] != 0):
if (maze[rand_wall[0]-1][rand_wall[1]] != "c"):
maze[rand_wall[0]-1][rand_wall[1]] = "w"
if ([rand_wall[0]-1, rand_wall[1]] not in walls):
walls.append([rand_wall[0]-1, rand_wall[1]])
# Delete wall
for wall in walls:
if (wall[0] == rand_wall[0] and wall[1] == rand_wall[1]):
walls.remove(wall)
continue
# Delete the wall from the list anyway
for wall in walls:
if (wall[0] == rand_wall[0] and wall[1] == rand_wall[1]):
walls.remove(wall)
# Mark the remaining unvisited cells as walls
for y in range(height):
for x in range(width):
if (maze[y][x] == "u"):
maze[y][x] = "w"
# Set entrance and exit
for x in range(width):
if (maze[1][x] == "c"):
maze[0][x] = "c"
break
for x in range(width-1, 0, -1):
if (maze[height-2][x] == "c"):
maze[height-1][x] = "c"
break
# Print final maze
printMaze(maze)
▓▓░▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓░▓▓░▓░▓▓░▓▓░░░░░▓░▓▓░░░░▓ ▓░░░▓░░░▓░░░░░▓▓▓▓▓░░▓░▓▓▓▓ ▓▓░▓▓░▓▓▓░▓▓▓░░░░░░░▓▓░░░░▓ ▓▓░░░░░░░░▓▓▓░▓▓░▓░▓▓░░▓▓░▓ ▓░░▓▓░▓▓▓░░░▓░▓▓░▓▓▓▓▓░▓▓▓▓ ▓░▓▓▓░▓▓▓▓░▓▓▓▓▓▓▓▓░▓▓░▓░▓▓ ▓░░░▓░░░░▓▓▓░▓▓░▓░░░░░░░░░▓ ▓▓░▓▓▓░▓░░▓▓░▓░░░░▓▓▓░▓▓▓░▓ ▓░░░░▓░▓▓░░░░░░▓▓░░░▓░░░▓░▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░▓
# Maze generator -- Randomized Prim Algorithm
## Imports
import random
from random import choice
## Functions
def printMaze(maze):
for y in range(height):
for x in range(width):
if (maze[y][x] == "u"):
print(unvisited, end="")
elif (maze[y][x] == "c"):
print(cell_tile, end="")
else:
print(choice(wall_tile), end="")
print("")
# Find number of surrounding cells (c) of a random wall
def surroundingCells(rand_wall):
s_cells = 0
if (maze[rand_wall[0]-1][rand_wall[1]] == "c"): # cell below the random wall (y-1)
s_cells += 1
if (maze[rand_wall[0]+1][rand_wall[1]] == "c"): # cell above the random wall (y+1)
s_cells += 1
if (maze[rand_wall[0]][rand_wall[1]-1] == "c"): # cell left from random wall (x-1)
s_cells +=1
if (maze[rand_wall[0]][rand_wall[1]+1] == "c"): # cell right from random wall (x+1)
s_cells += 1
return s_cells # how many of the four surrounding cells are marked as "c"?
## Main code
# Init variables
# --------------------------
wall_tile = "🌵🌴"
cell_tile = "⬜️"
height = 30
width = 40
# --------------------------
wall = "w"
cell = "c"
unvisited = "u"
maze = []
# Denote all cells as unvisited
for y in range(height):
line = []
for x in range(width):
line.append(unvisited)
maze.append(line)
# Randomize starting point and set it a cell
starting_height = int(random.random()*height) # picks a random number in the range of the height
starting_width = int(random.random()*width) # same with width
# We need to make sure that we do not start on a cell that is on the edge of the maze:
if (starting_height == 0):
starting_height += 1 # if the cell is on the bottom edge of the maze, add 1
if (starting_height == height-1):
starting_height -= 1 # if the cell is on the top edge of the maze, minus 1
if (starting_width == 0):
starting_width += 1 # if the cell is on the left edge of the maze, add 1
if (starting_width == width-1):
starting_width -= 1 # if the cell is on the right edge of the maze, minus 1
# shoudnt we rewrite the code because the chance to get a 1 is now double as high? should it be something like:
# if starting_height == 0 : try again to pick a random number
# or: directly pick a random int(random.random()*len(height))-1
#??????????????????
# Mark it as cell and add surrounding walls to the list
maze[starting_height][starting_width] = cell
walls = []
walls.append([starting_height - 1, starting_width])
walls.append([starting_height + 1, starting_width])
walls.append([starting_height, starting_width - 1])
walls.append([starting_height, starting_width + 1])
# mark the surrounding cells as walls
maze[starting_height-1][starting_width] = "w"
maze[starting_height][starting_width - 1] = "w"
maze[starting_height][starting_width + 1] = "w"
maze[starting_height + 1][starting_width] = "w"
# While there are walls in the wall-list pick a random wall from the list
while (walls):
# Pick a random wall
rand_wall = walls[int(random.random()*len(walls))-1]
# Check if it is a left wall
if (rand_wall[1] != 0):
if (maze[rand_wall[0]][rand_wall[1]-1] == "u" and maze[rand_wall[0]][rand_wall[1]+1] == "c"):
# Find the number of surrounding cells
s_cells = surroundingCells(rand_wall)
if (s_cells < 2):
# mark the new path
maze[rand_wall[0]][rand_wall[1]] = "c"
# Mark the new walls
# Upper cell
if (rand_wall[0] != 0):
if (maze[rand_wall[0]-1][rand_wall[1]] != "c"):
maze[rand_wall[0]-1][rand_wall[1]] = "w"
if ([rand_wall[0]-1, rand_wall[1]] not in walls):
walls.append([rand_wall[0]-1, rand_wall[1]])
# Bottom cell
if (rand_wall[0] != height-1):
if (maze[rand_wall[0]+1][rand_wall[1]] != "c"):
maze[rand_wall[0]+1][rand_wall[1]] = "w"
if ([rand_wall[0]+1, rand_wall[1]] not in walls):
walls.append([rand_wall[0]+1, rand_wall[1]])
# Leftmost cell
if (rand_wall[1] != 0):
if (maze[rand_wall[0]][rand_wall[1]-1] != "c"):
maze[rand_wall[0]][rand_wall[1]-1] = "w"
if ([rand_wall[0], rand_wall[1]-1] not in walls):
walls.append([rand_wall[0], rand_wall[1]-1])
# Delete wall
for wall in walls:
if (wall[0] == rand_wall[0] and wall[1] == rand_wall[1]):
walls.remove(wall)
continue
# Check if it is an upper wall
if (rand_wall[0] != 0):
if (maze[rand_wall[0]-1][rand_wall[1]] == "u" and maze[rand_wall[0]+1][rand_wall[1]] == "c"):
s_cells = surroundingCells(rand_wall)
if (s_cells < 2):
# Denote the new path
maze[rand_wall[0]][rand_wall[1]] = "c"
# Mark the new walls
# Upper cell
if (rand_wall[0] != 0):
if (maze[rand_wall[0]-1][rand_wall[1]] != "c"):
maze[rand_wall[0]-1][rand_wall[1]] = "w"
if ([rand_wall[0]-1, rand_wall[1]] not in walls):
walls.append([rand_wall[0]-1, rand_wall[1]])
# Leftmost cell
if (rand_wall[1] != 0):
if (maze[rand_wall[0]][rand_wall[1]-1] != "c"):
maze[rand_wall[0]][rand_wall[1]-1] = "w"
if ([rand_wall[0], rand_wall[1]-1] not in walls):
walls.append([rand_wall[0], rand_wall[1]-1])
# Rightmost cell
if (rand_wall[1] != width-1):
if (maze[rand_wall[0]][rand_wall[1]+1] != "c"):
maze[rand_wall[0]][rand_wall[1]+1] = "w"
if ([rand_wall[0], rand_wall[1]+1] not in walls):
walls.append([rand_wall[0], rand_wall[1]+1])
# Delete wall
for wall in walls:
if (wall[0] == rand_wall[0] and wall[1] == rand_wall[1]):
walls.remove(wall)
continue
# Check the bottom wall
if (rand_wall[0] != height-1):
if (maze[rand_wall[0]+1][rand_wall[1]] == "u" and maze[rand_wall[0]-1][rand_wall[1]] == "c"):
s_cells = surroundingCells(rand_wall)
if (s_cells < 2):
# Denote the new path
maze[rand_wall[0]][rand_wall[1]] = "c"
# Mark the new walls
if (rand_wall[0] != height-1):
if (maze[rand_wall[0]+1][rand_wall[1]] != "c"):
maze[rand_wall[0]+1][rand_wall[1]] = "w"
if ([rand_wall[0]+1, rand_wall[1]] not in walls):
walls.append([rand_wall[0]+1, rand_wall[1]])
if (rand_wall[1] != 0):
if (maze[rand_wall[0]][rand_wall[1]-1] != "c"):
maze[rand_wall[0]][rand_wall[1]-1] = "w"
if ([rand_wall[0], rand_wall[1]-1] not in walls):
walls.append([rand_wall[0], rand_wall[1]-1])
if (rand_wall[1] != width-1):
if (maze[rand_wall[0]][rand_wall[1]+1] != "c"):
maze[rand_wall[0]][rand_wall[1]+1] = "w"
if ([rand_wall[0], rand_wall[1]+1] not in walls):
walls.append([rand_wall[0], rand_wall[1]+1])
# Delete wall
for wall in walls:
if (wall[0] == rand_wall[0] and wall[1] == rand_wall[1]):
walls.remove(wall)
continue
# Check the right wall
if (rand_wall[1] != width-1):
if (maze[rand_wall[0]][rand_wall[1]+1] == "u" and maze[rand_wall[0]][rand_wall[1]-1] == "c"):
s_cells = surroundingCells(rand_wall)
if (s_cells < 2):
# Denote the new path
maze[rand_wall[0]][rand_wall[1]] = "c"
# Mark the new walls
if (rand_wall[1] != width-1):
if (maze[rand_wall[0]][rand_wall[1]+1] != "c"):
maze[rand_wall[0]][rand_wall[1]+1] = "w"
if ([rand_wall[0], rand_wall[1]+1] not in walls):
walls.append([rand_wall[0], rand_wall[1]+1])
if (rand_wall[0] != height-1):
if (maze[rand_wall[0]+1][rand_wall[1]] != "c"):
maze[rand_wall[0]+1][rand_wall[1]] = "w"
if ([rand_wall[0]+1, rand_wall[1]] not in walls):
walls.append([rand_wall[0]+1, rand_wall[1]])
if (rand_wall[0] != 0):
if (maze[rand_wall[0]-1][rand_wall[1]] != "c"):
maze[rand_wall[0]-1][rand_wall[1]] = "w"
if ([rand_wall[0]-1, rand_wall[1]] not in walls):
walls.append([rand_wall[0]-1, rand_wall[1]])
# Delete wall
for wall in walls:
if (wall[0] == rand_wall[0] and wall[1] == rand_wall[1]):
walls.remove(wall)
continue
# Delete the wall from the list anyway
for wall in walls:
if (wall[0] == rand_wall[0] and wall[1] == rand_wall[1]):
walls.remove(wall)
# Mark the remaining unvisited cells as walls
for y in range(height):
for x in range(width):
if (maze[y][x] == "u"):
maze[y][x] = "w"
# Set entrance and exit
for x in range(width):
if (maze[1][x] == "c"):
maze[0][x] = "c"
break
for x in range(width-1, 0, -1):
if (maze[height-2][x] == "c"):
maze[height-1][x] = "c"
break
# Print final maze
printMaze(maze)
woods = (width-2)*'🌴' + '⬜️' + '🌴' + '\n'
print(woods*5)
🌴⬜️🌵🌴🌴🌵🌴🌵🌴🌵🌵🌵🌵🌴🌵🌴🌵🌵🌵🌵🌵🌴🌵🌴🌴🌴🌵🌵🌵🌵🌵🌵🌵🌴🌴🌴🌴🌵🌴🌵 🌴⬜️⬜️🌵🌵⬜️⬜️🌴⬜️🌴🌴⬜️🌵⬜️🌴⬜️🌵⬜️⬜️⬜️🌵🌵⬜️⬜️⬜️🌵⬜️🌵⬜️🌵⬜️🌵🌵⬜️🌴🌵⬜️🌵⬜️🌴 🌴🌴⬜️🌴⬜️⬜️🌴🌴⬜️🌴⬜️⬜️⬜️⬜️⬜️⬜️🌴⬜️🌵⬜️🌴🌵🌵🌴⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️🌵🌵⬜️🌵⬜️🌴 🌵🌴⬜️🌴🌵⬜️⬜️🌴⬜️🌵🌴🌴🌴⬜️🌵🌵🌵🌴🌴⬜️🌵⬜️🌵🌴🌴🌴🌵🌴🌵⬜️🌴⬜️🌵⬜️🌵⬜️⬜️🌴⬜️🌵 🌴⬜️⬜️⬜️🌴🌵⬜️🌴⬜️🌴⬜️⬜️⬜️⬜️🌵⬜️🌵🌴⬜️⬜️⬜️⬜️🌵⬜️🌴⬜️⬜️🌴🌴🌵🌴⬜️🌴⬜️🌵🌵⬜️⬜️⬜️🌴 🌴🌴🌵⬜️🌵⬜️⬜️🌴⬜️🌴🌵🌵🌴⬜️⬜️⬜️🌵🌵🌴🌵🌴⬜️⬜️⬜️🌴🌵⬜️🌴⬜️🌵🌴🌴🌴⬜️⬜️🌵🌴🌵⬜️🌴 🌴⬜️🌴⬜️🌴⬜️🌴🌵⬜️🌴🌵⬜️🌵⬜️🌴🌴🌵⬜️⬜️🌵🌵🌴⬜️🌴🌴⬜️⬜️🌵⬜️🌵⬜️🌵⬜️⬜️🌵🌵⬜️🌵⬜️🌵 🌵⬜️⬜️⬜️⬜️⬜️🌵🌴⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️🌵🌵⬜️🌵⬜️🌴⬜️🌵⬜️⬜️🌵🌴⬜️🌵⬜️🌵🌴⬜️🌴🌴⬜️⬜️⬜️🌴 🌵🌵🌵🌵🌴⬜️⬜️🌵🌵🌵🌵🌴🌵⬜️🌴🌵🌴⬜️⬜️🌴⬜️🌴⬜️🌵⬜️🌵🌴⬜️⬜️🌵⬜️⬜️🌵⬜️⬜️🌴🌵🌴⬜️🌵 🌵🌴🌵⬜️⬜️⬜️🌵🌵🌵🌵⬜️🌵🌵⬜️🌴⬜️🌵🌴⬜️🌴⬜️🌵⬜️🌴⬜️⬜️🌵🌴⬜️🌴🌴⬜️🌴⬜️🌵🌴🌴⬜️⬜️🌴 🌴⬜️⬜️⬜️🌵⬜️⬜️🌴⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️🌴🌴⬜️🌴⬜️🌵⬜️⬜️⬜️🌴🌵⬜️⬜️🌵🌴⬜️⬜️⬜️⬜️⬜️🌴🌵⬜️🌴 🌴🌵⬜️🌴🌴🌴⬜️🌴🌴🌴🌴🌵🌵🌵🌵⬜️⬜️⬜️⬜️🌴⬜️🌴🌵🌵⬜️🌵🌴🌵⬜️🌴🌴⬜️🌴🌵🌵🌴🌵⬜️⬜️🌵 🌵🌴🌵🌵⬜️⬜️⬜️⬜️⬜️⬜️🌵⬜️🌵🌴🌴🌴⬜️🌴⬜️🌴⬜️🌵⬜️⬜️⬜️⬜️🌴🌴⬜️🌵🌵⬜️🌴⬜️🌴⬜️🌵🌵⬜️🌵 🌴🌴🌵🌵🌴🌵🌴🌵🌴⬜️🌵⬜️⬜️⬜️⬜️🌵🌴🌴⬜️🌵⬜️🌴🌴🌴🌵⬜️🌴🌵⬜️⬜️🌵⬜️🌴⬜️🌵⬜️⬜️🌵⬜️🌴 🌴🌵⬜️🌴⬜️🌵🌵🌵🌵⬜️🌵🌵🌵🌴⬜️⬜️🌵⬜️⬜️⬜️⬜️🌵🌵⬜️🌴⬜️⬜️🌴🌵⬜️🌵⬜️⬜️⬜️🌴🌴⬜️🌵⬜️🌵 🌵⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️🌴🌴🌴🌴⬜️🌵🌵🌴⬜️🌴🌵⬜️⬜️🌵🌴⬜️🌴🌴⬜️⬜️⬜️🌵🌵🌴⬜️⬜️🌴⬜️🌴 🌵⬜️🌵⬜️🌵⬜️🌵⬜️🌴🌵⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️🌵🌴🌵⬜️⬜️⬜️⬜️🌴🌵🌴🌴⬜️🌴⬜️🌴🌴⬜️🌵⬜️🌵 🌵🌴🌴⬜️🌵🌴🌴⬜️🌵🌵🌵🌴⬜️🌵🌴⬜️🌵🌴🌵⬜️⬜️⬜️⬜️⬜️🌵🌴⬜️⬜️🌵🌴⬜️⬜️🌴⬜️🌴🌵⬜️🌴⬜️🌵 🌵🌴🌵🌵🌴🌴🌵🌵🌵⬜️⬜️⬜️⬜️🌴⬜️⬜️🌵🌴🌴🌵⬜️🌵🌵🌴🌴🌵🌴⬜️🌴🌴⬜️🌴🌴⬜️🌵🌴⬜️⬜️⬜️🌴 🌴⬜️⬜️⬜️⬜️⬜️🌴🌵🌵🌴🌵🌴⬜️🌴⬜️🌴🌵⬜️⬜️🌴🌴🌵🌴🌵⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️🌴⬜️🌴🌴🌵🌴⬜️🌴 🌴🌵🌴🌵🌴⬜️🌴⬜️🌵🌴🌴⬜️⬜️🌵🌵🌴🌵🌵⬜️⬜️⬜️⬜️⬜️⬜️⬜️🌴🌵🌵🌴⬜️🌴⬜️⬜️⬜️⬜️🌵🌴⬜️⬜️🌵 🌵🌵🌵⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️🌵🌵⬜️⬜️⬜️⬜️⬜️🌴⬜️🌵🌴🌵⬜️🌵🌵⬜️🌵🌵🌴🌴🌴⬜️🌵🌵⬜️⬜️🌴🌵 🌵⬜️🌵🌴🌴🌵🌵⬜️🌵🌵🌵⬜️🌴🌵🌴🌵🌴🌵🌴🌴🌴🌵🌴🌴🌵🌴⬜️⬜️⬜️🌵🌵⬜️🌵⬜️⬜️🌵🌴⬜️⬜️🌵 🌴⬜️⬜️⬜️⬜️⬜️⬜️⬜️🌵🌴⬜️⬜️⬜️🌴⬜️🌵⬜️⬜️🌴⬜️⬜️⬜️⬜️🌵🌴⬜️⬜️🌴⬜️⬜️🌴⬜️🌴⬜️🌴🌵⬜️⬜️🌵🌵 🌴🌴🌵⬜️🌴⬜️🌴🌴🌵🌵🌴🌵🌵🌵⬜️🌵🌵⬜️🌴🌴🌵🌴⬜️⬜️🌴🌴🌴🌵🌵⬜️⬜️⬜️⬜️⬜️⬜️🌵🌵⬜️🌴🌵 🌵🌵⬜️⬜️🌵⬜️🌴🌵⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️🌵⬜️🌴⬜️🌴🌵⬜️🌵⬜️🌴🌵🌴🌵🌴⬜️🌴🌴⬜️⬜️⬜️🌵 🌵⬜️⬜️🌵🌴⬜️⬜️🌴🌴🌴🌵🌵🌵🌴🌴🌴🌴🌵⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️🌵⬜️⬜️⬜️🌵🌴⬜️🌵🌴 🌴🌵⬜️🌴⬜️⬜️🌴🌵🌴⬜️⬜️⬜️⬜️🌵🌵🌴🌵⬜️⬜️🌵🌵⬜️🌴🌴⬜️🌴🌵🌵🌵🌵⬜️🌵🌵⬜️🌵🌴⬜️⬜️⬜️🌴 🌵⬜️⬜️🌵⬜️🌵🌵⬜️⬜️⬜️🌵🌴⬜️⬜️⬜️⬜️⬜️⬜️🌵🌵⬜️⬜️🌴⬜️⬜️🌵⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️🌵⬜️🌵 🌵🌵🌵🌵🌵🌴🌵🌴🌴🌴🌴🌴🌵🌵🌵🌵🌴🌵🌵🌴🌴🌴🌵🌴🌴🌴🌵🌵🌵🌵🌴🌵🌵🌵🌴🌴🌴🌴⬜️🌵 🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴⬜️🌴 🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴⬜️🌴 🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴⬜️🌴 🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴⬜️🌴 🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴⬜️🌴
# Maze generator -- Randomized Prim Algorithm
## Imports
import random
from random import choice
## Functions
def printMaze(wall_tile, cell_tile, height, width):
for y in range(height):
for x in range(width):
if (maze[y][x] == "u"):
print(unvisited, end="")
elif (maze[y][x] == "c"):
print(cell_tile, end="")
else:
print(choice(wall_tile), end="")
print("")
# Find number of surrounding cells (c) of a random wall
def surroundingCells(rand_wall):
s_cells = 0
if (maze[rand_wall[0]-1][rand_wall[1]] == "c"): # cell below the random wall (y-1)
s_cells += 1
if (maze[rand_wall[0]+1][rand_wall[1]] == "c"): # cell above the random wall (y+1)
s_cells += 1
if (maze[rand_wall[0]][rand_wall[1]-1] == "c"): # cell left from random wall (x-1)
s_cells +=1
if (maze[rand_wall[0]][rand_wall[1]+1] == "c"): # cell right from random wall (x+1)
s_cells += 1
return s_cells # how many of the four surrounding cells are marked as "c"?
## Main code
# Init variables
# --------------------------
#wall_tile = "🌵🌴"
#cell_tile = "⬜️"
#height = 30
#width = 40
# --------------------------
wall = "w"
cell = "c"
unvisited = "u"
maze = []
# Denote all cells as unvisited
for y in range(height):
line = []
for x in range(width):
line.append(unvisited)
maze.append(line)
# Randomize starting point and set it a cell
starting_height = int(random.random()*height) # picks a random number in the range of the height
starting_width = int(random.random()*width) # same with width
# We need to make sure that we do not start on a cell that is on the edge of the maze:
if (starting_height == 0):
starting_height += 1 # if the cell is on the bottom edge of the maze, add 1
if (starting_height == height-1):
starting_height -= 1 # if the cell is on the top edge of the maze, minus 1
if (starting_width == 0):
starting_width += 1 # if the cell is on the left edge of the maze, add 1
if (starting_width == width-1):
starting_width -= 1 # if the cell is on the right edge of the maze, minus 1
# shoudnt we rewrite the code because the chance to get a 1 is now double as high? should it be something like:
# if starting_height == 0 : try again to pick a random number
# or: directly pick a random int(random.random()*len(height))-1
#??????????????????
# Mark it as cell and add surrounding walls to the list
maze[starting_height][starting_width] = cell
walls = []
walls.append([starting_height - 1, starting_width])
walls.append([starting_height + 1, starting_width])
walls.append([starting_height, starting_width - 1])
walls.append([starting_height, starting_width + 1])
# mark the surrounding cells as walls
maze[starting_height-1][starting_width] = "w"
maze[starting_height][starting_width - 1] = "w"
maze[starting_height][starting_width + 1] = "w"
maze[starting_height + 1][starting_width] = "w"
# While there are walls in the wall-list pick a random wall from the list
while (walls):
# Pick a random wall
rand_wall = walls[int(random.random()*len(walls))-1]
# Check if it is a left wall
if (rand_wall[1] != 0):
if (maze[rand_wall[0]][rand_wall[1]-1] == "u" and maze[rand_wall[0]][rand_wall[1]+1] == "c"):
# Find the number of surrounding cells
s_cells = surroundingCells(rand_wall)
if (s_cells < 2):
# mark the new path
maze[rand_wall[0]][rand_wall[1]] = "c"
# Mark the new walls
# Upper cell
if (rand_wall[0] != 0):
if (maze[rand_wall[0]-1][rand_wall[1]] != "c"):
maze[rand_wall[0]-1][rand_wall[1]] = "w"
if ([rand_wall[0]-1, rand_wall[1]] not in walls):
walls.append([rand_wall[0]-1, rand_wall[1]])
# Bottom cell
if (rand_wall[0] != height-1):
if (maze[rand_wall[0]+1][rand_wall[1]] != "c"):
maze[rand_wall[0]+1][rand_wall[1]] = "w"
if ([rand_wall[0]+1, rand_wall[1]] not in walls):
walls.append([rand_wall[0]+1, rand_wall[1]])
# Leftmost cell
if (rand_wall[1] != 0):
if (maze[rand_wall[0]][rand_wall[1]-1] != "c"):
maze[rand_wall[0]][rand_wall[1]-1] = "w"
if ([rand_wall[0], rand_wall[1]-1] not in walls):
walls.append([rand_wall[0], rand_wall[1]-1])
# Delete wall
for wall in walls:
if (wall[0] == rand_wall[0] and wall[1] == rand_wall[1]):
walls.remove(wall)
continue
# Check if it is an upper wall
if (rand_wall[0] != 0):
if (maze[rand_wall[0]-1][rand_wall[1]] == "u" and maze[rand_wall[0]+1][rand_wall[1]] == "c"):
s_cells = surroundingCells(rand_wall)
if (s_cells < 2):
# Denote the new path
maze[rand_wall[0]][rand_wall[1]] = "c"
# Mark the new walls
# Upper cell
if (rand_wall[0] != 0):
if (maze[rand_wall[0]-1][rand_wall[1]] != "c"):
maze[rand_wall[0]-1][rand_wall[1]] = "w"
if ([rand_wall[0]-1, rand_wall[1]] not in walls):
walls.append([rand_wall[0]-1, rand_wall[1]])
# Leftmost cell
if (rand_wall[1] != 0):
if (maze[rand_wall[0]][rand_wall[1]-1] != "c"):
maze[rand_wall[0]][rand_wall[1]-1] = "w"
if ([rand_wall[0], rand_wall[1]-1] not in walls):
walls.append([rand_wall[0], rand_wall[1]-1])
# Rightmost cell
if (rand_wall[1] != width-1):
if (maze[rand_wall[0]][rand_wall[1]+1] != "c"):
maze[rand_wall[0]][rand_wall[1]+1] = "w"
if ([rand_wall[0], rand_wall[1]+1] not in walls):
walls.append([rand_wall[0], rand_wall[1]+1])
# Delete wall
for wall in walls:
if (wall[0] == rand_wall[0] and wall[1] == rand_wall[1]):
walls.remove(wall)
continue
# Check the bottom wall
if (rand_wall[0] != height-1):
if (maze[rand_wall[0]+1][rand_wall[1]] == "u" and maze[rand_wall[0]-1][rand_wall[1]] == "c"):
s_cells = surroundingCells(rand_wall)
if (s_cells < 2):
# Denote the new path
maze[rand_wall[0]][rand_wall[1]] = "c"
# Mark the new walls
if (rand_wall[0] != height-1):
if (maze[rand_wall[0]+1][rand_wall[1]] != "c"):
maze[rand_wall[0]+1][rand_wall[1]] = "w"
if ([rand_wall[0]+1, rand_wall[1]] not in walls):
walls.append([rand_wall[0]+1, rand_wall[1]])
if (rand_wall[1] != 0):
if (maze[rand_wall[0]][rand_wall[1]-1] != "c"):
maze[rand_wall[0]][rand_wall[1]-1] = "w"
if ([rand_wall[0], rand_wall[1]-1] not in walls):
walls.append([rand_wall[0], rand_wall[1]-1])
if (rand_wall[1] != width-1):
if (maze[rand_wall[0]][rand_wall[1]+1] != "c"):
maze[rand_wall[0]][rand_wall[1]+1] = "w"
if ([rand_wall[0], rand_wall[1]+1] not in walls):
walls.append([rand_wall[0], rand_wall[1]+1])
# Delete wall
for wall in walls:
if (wall[0] == rand_wall[0] and wall[1] == rand_wall[1]):
walls.remove(wall)
continue
# Check the right wall
if (rand_wall[1] != width-1):
if (maze[rand_wall[0]][rand_wall[1]+1] == "u" and maze[rand_wall[0]][rand_wall[1]-1] == "c"):
s_cells = surroundingCells(rand_wall)
if (s_cells < 2):
# Denote the new path
maze[rand_wall[0]][rand_wall[1]] = "c"
# Mark the new walls
if (rand_wall[1] != width-1):
if (maze[rand_wall[0]][rand_wall[1]+1] != "c"):
maze[rand_wall[0]][rand_wall[1]+1] = "w"
if ([rand_wall[0], rand_wall[1]+1] not in walls):
walls.append([rand_wall[0], rand_wall[1]+1])
if (rand_wall[0] != height-1):
if (maze[rand_wall[0]+1][rand_wall[1]] != "c"):
maze[rand_wall[0]+1][rand_wall[1]] = "w"
if ([rand_wall[0]+1, rand_wall[1]] not in walls):
walls.append([rand_wall[0]+1, rand_wall[1]])
if (rand_wall[0] != 0):
if (maze[rand_wall[0]-1][rand_wall[1]] != "c"):
maze[rand_wall[0]-1][rand_wall[1]] = "w"
if ([rand_wall[0]-1, rand_wall[1]] not in walls):
walls.append([rand_wall[0]-1, rand_wall[1]])
# Delete wall
for wall in walls:
if (wall[0] == rand_wall[0] and wall[1] == rand_wall[1]):
walls.remove(wall)
continue
# Delete the wall from the list anyway
for wall in walls:
if (wall[0] == rand_wall[0] and wall[1] == rand_wall[1]):
walls.remove(wall)
# Mark the remaining unvisited cells as walls
for y in range(height):
for x in range(width):
if (maze[y][x] == "u"):
maze[y][x] = "w"
# Set entrance and exit
for x in range(width):
if (maze[1][x] == "c"):
maze[0][x] = "c"
break
for x in range(width-1, 0, -1):
if (maze[height-2][x] == "c"):
maze[height-1][x] = "c"
break
# Print final maze
printMaze("🌵🌴", "⬜️", 30, 40)
woods = (width-2)*'🌴' + '⬜️' + '🌴' + '\n'
print(woods*5, end='')
print("⬜️"*width)
printMaze("🔥", "⬜️", 30, 40)
mountains = (width-2)*'🔥' + '⬜️' + '🔥' + '\n'
print(mountains*5, end='')
print("⬜️"*width)
🌴⬜️🌵🌴🌴🌴🌵🌵🌵🌵🌵🌵🌵🌴🌵🌴🌴🌴🌴🌴🌴🌵🌵🌴🌴🌴🌵🌴🌴🌴🌵🌵🌴🌵🌵🌴🌵🌵🌴🌵 🌴⬜️⬜️⬜️⬜️🌴🌴⬜️⬜️⬜️🌴🌴⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️🌴🌴⬜️🌵🌵⬜️🌴🌴⬜️🌵 🌴🌴🌴🌵⬜️🌴🌴🌴🌴⬜️⬜️⬜️⬜️🌴🌴🌵⬜️🌵🌴🌵🌴🌴🌴🌴🌵🌵🌴🌴🌵⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️🌵⬜️🌴 🌴⬜️⬜️⬜️⬜️🌵⬜️🌴⬜️⬜️🌵🌵🌴🌵🌵🌵🌵🌵🌵⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️🌴🌵🌵🌴🌵⬜️🌴🌴⬜️🌴 🌵🌴🌵🌵⬜️⬜️⬜️⬜️⬜️🌴🌴⬜️⬜️⬜️⬜️⬜️⬜️⬜️🌴🌴🌵🌵🌴🌵🌴🌴🌵🌵🌵🌴🌵⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️🌴 🌴⬜️⬜️⬜️⬜️🌵⬜️🌵⬜️🌵🌴🌵🌴🌴⬜️🌵🌴⬜️🌵⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️🌴⬜️🌴⬜️🌵⬜️🌵🌴 🌵🌵🌴🌵🌵🌵🌵🌵🌵🌴⬜️🌵🌴🌵🌵🌵⬜️⬜️⬜️⬜️🌴🌴🌵🌴🌴🌴🌴🌴🌵🌴🌴⬜️🌵🌴🌵⬜️🌵⬜️⬜️🌴 🌴⬜️🌵🌵🌴🌵🌴⬜️🌴🌴⬜️🌵⬜️🌴🌵🌴🌴🌵🌵🌴🌵🌵🌴🌵⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️🌴🌴🌴⬜️🌵⬜️🌴🌵 🌵⬜️⬜️⬜️⬜️🌴⬜️⬜️🌵⬜️⬜️⬜️⬜️⬜️⬜️🌵🌵🌵⬜️🌴⬜️⬜️⬜️⬜️⬜️🌴🌵🌴⬜️🌴🌵🌴🌴⬜️⬜️⬜️🌴🌵🌵🌵 🌴🌴🌵🌴⬜️🌴🌴⬜️🌴🌴🌴🌵🌵🌴⬜️🌴⬜️🌵⬜️🌴🌵🌵🌵🌴🌵🌴🌴🌵🌴🌵🌴🌴🌵⬜️🌴⬜️⬜️⬜️⬜️🌴 🌵⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️🌴🌵⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️🌴⬜️🌵🌵🌵🌴 🌵🌵🌴🌵⬜️🌴🌵🌴⬜️🌵⬜️🌵⬜️🌵🌵⬜️🌵⬜️🌴🌵🌵🌵⬜️⬜️⬜️⬜️🌴⬜️🌵⬜️🌵🌵🌴⬜️🌵⬜️🌴🌵🌴🌴 🌴⬜️⬜️⬜️⬜️🌴🌴🌵🌴🌵🌴🌵🌴🌴🌵🌴🌴🌴🌵🌵🌴🌴🌵⬜️🌵⬜️🌴⬜️🌵⬜️🌴⬜️⬜️⬜️🌴⬜️⬜️⬜️⬜️🌵 🌴🌵🌵🌴🌵🌴⬜️🌵🌵⬜️🌵⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️🌴⬜️🌴⬜️🌴🌴🌵🌵🌵⬜️🌴⬜️🌵🌵🌴🌴 🌵🌴⬜️🌵🌴⬜️⬜️🌴🌵⬜️🌵🌵🌴🌵🌴🌴🌴🌴⬜️🌵🌵🌵🌴⬜️🌵⬜️🌵⬜️🌴⬜️⬜️⬜️⬜️⬜️🌴⬜️⬜️⬜️⬜️🌵 🌴⬜️⬜️🌵🌵🌵⬜️🌵🌴⬜️⬜️🌴🌴🌵⬜️⬜️⬜️⬜️⬜️🌴⬜️⬜️⬜️⬜️🌴⬜️🌴⬜️🌴🌵🌵⬜️🌴⬜️🌴⬜️🌴⬜️🌵🌵 🌵🌵⬜️⬜️⬜️⬜️⬜️⬜️🌵⬜️🌴🌵⬜️🌵🌵🌴🌵⬜️🌵🌴🌴🌴🌴⬜️🌵🌴🌵🌴🌴🌴🌴🌴🌵⬜️🌴⬜️🌴🌵🌵🌴 🌵⬜️⬜️🌵🌴🌴🌴⬜️⬜️⬜️⬜️🌵⬜️🌴⬜️🌵🌴🌴🌵⬜️⬜️⬜️⬜️⬜️🌵🌵⬜️⬜️⬜️⬜️🌴⬜️⬜️⬜️🌴🌵🌵🌵⬜️🌴 🌵🌴🌵🌵🌵🌵🌴🌴🌴🌴⬜️🌴⬜️🌴⬜️🌴⬜️🌵⬜️⬜️🌴🌵⬜️🌴🌵🌴🌵🌴🌴⬜️⬜️⬜️🌵⬜️🌵🌴⬜️⬜️⬜️🌵 🌴⬜️🌴⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️🌵⬜️🌴🌵⬜️⬜️🌵🌴⬜️🌴🌵🌴🌴⬜️🌴🌴⬜️⬜️⬜️⬜️🌴🌴🌴 🌵⬜️⬜️⬜️🌵🌴⬜️🌴🌴🌵⬜️🌴⬜️🌵⬜️🌵⬜️⬜️⬜️🌴🌴🌴⬜️🌵⬜️⬜️⬜️⬜️⬜️⬜️⬜️🌴⬜️⬜️🌵⬜️🌵🌴🌵🌴 🌴🌴⬜️🌵🌴🌵🌵🌵⬜️⬜️⬜️🌴⬜️🌵🌵🌵🌵⬜️🌴🌴⬜️⬜️⬜️🌴🌵⬜️🌵⬜️🌴⬜️🌵🌴⬜️🌵🌴⬜️⬜️⬜️⬜️🌴 🌵⬜️⬜️🌴🌵🌵🌵🌵⬜️🌴⬜️🌴🌴🌴⬜️⬜️⬜️⬜️🌴⬜️⬜️🌴🌵🌵🌴⬜️🌴⬜️🌵⬜️🌵🌴⬜️🌴🌴⬜️🌴🌵⬜️🌴 🌵🌵⬜️⬜️🌴🌵⬜️⬜️⬜️🌵🌴🌵🌴🌵🌵🌵🌵⬜️🌵🌴⬜️🌵🌴⬜️⬜️⬜️🌴⬜️🌵🌴🌵⬜️⬜️🌴🌴⬜️⬜️🌴⬜️🌵 🌴🌴⬜️🌴🌵🌵🌵🌵⬜️🌵🌴⬜️⬜️🌵⬜️🌵⬜️⬜️⬜️🌵🌵🌵🌵🌴🌵⬜️🌴🌴🌵⬜️⬜️⬜️🌵🌵⬜️⬜️🌴🌵⬜️🌵 🌴⬜️⬜️⬜️⬜️🌵🌴🌴🌴🌴🌴🌴⬜️⬜️⬜️⬜️⬜️🌴⬜️🌴🌵⬜️⬜️🌵⬜️⬜️🌵🌵⬜️⬜️🌴⬜️🌵🌴⬜️🌴🌵🌵🌵🌵 🌵🌴⬜️🌴⬜️🌴⬜️⬜️⬜️⬜️⬜️⬜️⬜️🌵🌴⬜️🌴🌵🌴🌵🌴🌵⬜️⬜️⬜️🌴🌵🌵🌵🌴🌴⬜️🌵🌵🌵🌴🌴⬜️🌵🌵 🌵🌴⬜️🌴⬜️🌴🌵⬜️🌴⬜️🌵🌴⬜️🌴⬜️⬜️⬜️🌴🌵🌴⬜️🌵🌴🌵⬜️⬜️⬜️🌴🌴⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️🌵 🌵⬜️⬜️🌵⬜️🌴⬜️⬜️🌴⬜️🌵⬜️⬜️🌴🌵⬜️🌵🌴⬜️⬜️⬜️⬜️⬜️⬜️⬜️🌵⬜️⬜️🌵⬜️🌴⬜️🌵🌵⬜️🌴⬜️🌵⬜️🌵 🌴🌴🌴🌴🌴🌵🌵🌴🌴🌵🌴🌵🌵🌵🌴🌵🌵🌵🌵🌵🌵🌵🌵🌴🌴🌵🌵🌵🌴🌵🌴🌵🌴🌵🌵🌵🌴🌴⬜️🌵 🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴⬜️🌴 🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴⬜️🌴 🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴⬜️🌴 🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴⬜️🌴 🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴🌴⬜️🌴 ⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️ 🔥⬜️🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥 🔥⬜️⬜️⬜️⬜️🔥🔥⬜️⬜️⬜️🔥🔥⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️🔥🔥⬜️🔥🔥⬜️🔥🔥⬜️🔥 🔥🔥🔥🔥⬜️🔥🔥🔥🔥⬜️⬜️⬜️⬜️🔥🔥🔥⬜️🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️🔥⬜️🔥 🔥⬜️⬜️⬜️⬜️🔥⬜️🔥⬜️⬜️🔥🔥🔥🔥🔥🔥🔥🔥🔥⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️🔥🔥🔥🔥🔥⬜️🔥🔥⬜️🔥 🔥🔥🔥🔥⬜️⬜️⬜️⬜️⬜️🔥🔥⬜️⬜️⬜️⬜️⬜️⬜️⬜️🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️🔥 🔥⬜️⬜️⬜️⬜️🔥⬜️🔥⬜️🔥🔥🔥🔥🔥⬜️🔥🔥⬜️🔥⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️🔥⬜️🔥⬜️🔥⬜️🔥🔥 🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥⬜️🔥🔥🔥🔥🔥⬜️⬜️⬜️⬜️🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥⬜️🔥🔥🔥⬜️🔥⬜️⬜️🔥 🔥⬜️🔥🔥🔥🔥🔥⬜️🔥🔥⬜️🔥⬜️🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️🔥🔥🔥⬜️🔥⬜️🔥🔥 🔥⬜️⬜️⬜️⬜️🔥⬜️⬜️🔥⬜️⬜️⬜️⬜️⬜️⬜️🔥🔥🔥⬜️🔥⬜️⬜️⬜️⬜️⬜️🔥🔥🔥⬜️🔥🔥🔥🔥⬜️⬜️⬜️🔥🔥🔥🔥 🔥🔥🔥🔥⬜️🔥🔥⬜️🔥🔥🔥🔥🔥🔥⬜️🔥⬜️🔥⬜️🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥⬜️🔥⬜️⬜️⬜️⬜️🔥 🔥⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️🔥🔥⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️🔥⬜️🔥🔥🔥🔥 🔥🔥🔥🔥⬜️🔥🔥🔥⬜️🔥⬜️🔥⬜️🔥🔥⬜️🔥⬜️🔥🔥🔥🔥⬜️⬜️⬜️⬜️🔥⬜️🔥⬜️🔥🔥🔥⬜️🔥⬜️🔥🔥🔥🔥 🔥⬜️⬜️⬜️⬜️🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥⬜️🔥⬜️🔥⬜️🔥⬜️🔥⬜️⬜️⬜️🔥⬜️⬜️⬜️⬜️🔥 🔥🔥🔥🔥🔥🔥⬜️🔥🔥⬜️🔥⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️🔥⬜️🔥⬜️🔥🔥🔥🔥🔥⬜️🔥⬜️🔥🔥🔥🔥 🔥🔥⬜️🔥🔥⬜️⬜️🔥🔥⬜️🔥🔥🔥🔥🔥🔥🔥🔥⬜️🔥🔥🔥🔥⬜️🔥⬜️🔥⬜️🔥⬜️⬜️⬜️⬜️⬜️🔥⬜️⬜️⬜️⬜️🔥 🔥⬜️⬜️🔥🔥🔥⬜️🔥🔥⬜️⬜️🔥🔥🔥⬜️⬜️⬜️⬜️⬜️🔥⬜️⬜️⬜️⬜️🔥⬜️🔥⬜️🔥🔥🔥⬜️🔥⬜️🔥⬜️🔥⬜️🔥🔥 🔥🔥⬜️⬜️⬜️⬜️⬜️⬜️🔥⬜️🔥🔥⬜️🔥🔥🔥🔥⬜️🔥🔥🔥🔥🔥⬜️🔥🔥🔥🔥🔥🔥🔥🔥🔥⬜️🔥⬜️🔥🔥🔥🔥 🔥⬜️⬜️🔥🔥🔥🔥⬜️⬜️⬜️⬜️🔥⬜️🔥⬜️🔥🔥🔥🔥⬜️⬜️⬜️⬜️⬜️🔥🔥⬜️⬜️⬜️⬜️🔥⬜️⬜️⬜️🔥🔥🔥🔥⬜️🔥 🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥⬜️🔥⬜️🔥⬜️🔥⬜️🔥⬜️⬜️🔥🔥⬜️🔥🔥🔥🔥🔥🔥⬜️⬜️⬜️🔥⬜️🔥🔥⬜️⬜️⬜️🔥 🔥⬜️🔥⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️🔥⬜️🔥🔥⬜️⬜️🔥🔥⬜️🔥🔥🔥🔥⬜️🔥🔥⬜️⬜️⬜️⬜️🔥🔥🔥 🔥⬜️⬜️⬜️🔥🔥⬜️🔥🔥🔥⬜️🔥⬜️🔥⬜️🔥⬜️⬜️⬜️🔥🔥🔥⬜️🔥⬜️⬜️⬜️⬜️⬜️⬜️⬜️🔥⬜️⬜️🔥⬜️🔥🔥🔥🔥 🔥🔥⬜️🔥🔥🔥🔥🔥⬜️⬜️⬜️🔥⬜️🔥🔥🔥🔥⬜️🔥🔥⬜️⬜️⬜️🔥🔥⬜️🔥⬜️🔥⬜️🔥🔥⬜️🔥🔥⬜️⬜️⬜️⬜️🔥 🔥⬜️⬜️🔥🔥🔥🔥🔥⬜️🔥⬜️🔥🔥🔥⬜️⬜️⬜️⬜️🔥⬜️⬜️🔥🔥🔥🔥⬜️🔥⬜️🔥⬜️🔥🔥⬜️🔥🔥⬜️🔥🔥⬜️🔥 🔥🔥⬜️⬜️🔥🔥⬜️⬜️⬜️🔥🔥🔥🔥🔥🔥🔥🔥⬜️🔥🔥⬜️🔥🔥⬜️⬜️⬜️🔥⬜️🔥🔥🔥⬜️⬜️🔥🔥⬜️⬜️🔥⬜️🔥 🔥🔥⬜️🔥🔥🔥🔥🔥⬜️🔥🔥⬜️⬜️🔥⬜️🔥⬜️⬜️⬜️🔥🔥🔥🔥🔥🔥⬜️🔥🔥🔥⬜️⬜️⬜️🔥🔥⬜️⬜️🔥🔥⬜️🔥 🔥⬜️⬜️⬜️⬜️🔥🔥🔥🔥🔥🔥🔥⬜️⬜️⬜️⬜️⬜️🔥⬜️🔥🔥⬜️⬜️🔥⬜️⬜️🔥🔥⬜️⬜️🔥⬜️🔥🔥⬜️🔥🔥🔥🔥🔥 🔥🔥⬜️🔥⬜️🔥⬜️⬜️⬜️⬜️⬜️⬜️⬜️🔥🔥⬜️🔥🔥🔥🔥🔥🔥⬜️⬜️⬜️🔥🔥🔥🔥🔥🔥⬜️🔥🔥🔥🔥🔥⬜️🔥🔥 🔥🔥⬜️🔥⬜️🔥🔥⬜️🔥⬜️🔥🔥⬜️🔥⬜️⬜️⬜️🔥🔥🔥⬜️🔥🔥🔥⬜️⬜️⬜️🔥🔥⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️🔥 🔥⬜️⬜️🔥⬜️🔥⬜️⬜️🔥⬜️🔥⬜️⬜️🔥🔥⬜️🔥🔥⬜️⬜️⬜️⬜️⬜️⬜️⬜️🔥⬜️⬜️🔥⬜️🔥⬜️🔥🔥⬜️🔥⬜️🔥⬜️🔥 🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥⬜️🔥 🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥⬜️🔥 🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥⬜️🔥 🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥⬜️🔥 🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥⬜️🔥 🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥⬜️🔥 ⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️
! jupyter nbconvert --execute --to html mazes.ipynb
[NbConvertApp] Converting notebook mazes.ipynb to html ^C