Skip to content

Instantly share code, notes, and snippets.

@triplrrr
Created November 5, 2020 19:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save triplrrr/5183bc37132c53bdd6948693efa640b5 to your computer and use it in GitHub Desktop.
Save triplrrr/5183bc37132c53bdd6948693efa640b5 to your computer and use it in GitHub Desktop.
Script that generates a solvable maze using Kruskal's algorithm
#!/usr/bin/python3
# Usage:
# python3 kruskal.py [WIDTH] [HEIGHT]
# If neither WIDTH nor HEIGHT is provided, a default width and height of 8 is used.
# If only WIDTH is provided, it is ued for both width and height. Extra arguments
# are ignored.
import sys
from random import choice
if len(sys.argv) == 2:
w = int(sys.argv[1])
h = w
elif len(sys.argv) >= 3:
w = int(sys.argv[1])
h = int(sys.argv[2])
else:
w, h = 8, 8
class Maze:
def __init__(self, w, h):
self.w = w
self.h = h
self.cells = []
set_counter = 1
for y in range(self.h):
self.cells.append([])
for x in range(self.w):
self.cells[y].append(set_counter)
set_counter += 1
self.edges = dict()
for y in range(self.h):
for x in range(self.w):
if x < self.w - 1:
self.edges[((x,y), (x+1,y))] = True
if y < self.h - 1:
self.edges[((x,y), (x,y+1))] = True
self.steps = 0
def get_cell(self, c):
return self.cells[c[1]][c[0]]
def set_cell(self, c, v):
self.cells[c[1]][c[0]] = v
def apply_set(self, s1, s2):
for x in range(self.w):
for y in range(self.h):
if self.get_cell((x, y)) == s2:
self.set_cell((x, y), s1)
def is_connected(self, c1, c2):
return self.get_cell(c1) == self.get_cell(c2)
def is_valid_maze(self):
s = self.get_cell((0,0))
for x in range(self.w):
for y in range(self.h):
if self.get_cell((x, y)) != s:
return False
return True
def generate(self):
used = []
while not self.is_valid_maze():
edge = choice(list(set(self.edges.keys()) - set(used)))
used.append(edge)
if not self.is_connected(edge[0], edge[1]):
self.edges[edge] = False
self.apply_set(self.get_cell(edge[0]), self.get_cell(edge[1]))
self.steps += 1
def __str__(self):
disp = []
for y in range(2 * self.h - 1):
disp.append([])
for x in range(2 * self.w - 1):
if (x % 2 == 1) and (y % 2 == 1):
disp[y].append("+")
elif (x % 2 == 1) and (y % 2 == 0) and self.edges[(((x-1)/2,y/2),((x+1)/2,y/2))]:
disp[y].append("|")
elif (x % 2 == 0) and (y % 2 == 1) and self.edges[((x/2,(y-1)/2),(x/2,(y+1)/2))]:
disp[y].append("---")
else:
if x % 2 == 0:
if y % 2 == 0 and x/2 == self.w - 1 and y/2 == self.h - 1:
disp[y].append(" E ")
elif y % 2 == 0 and x/2 == 0 and y/2 == 0:
disp[y].append(" S ")
else:
disp[y].append(" ")
else:
disp[y].append(" ")
for i in range(len(disp)):
disp[i] = "".join(["|"] + disp[i] + ["|"])
return "\n".join(['+' + ('-' * (4 * self.w - 1)) + '+'] + disp + ['+' + ('-' * (4 * self.w - 1)) + '+'])
m = Maze(w, h)
m.generate()
print(f'{m.w}x{m.h}')
print("Steps:", m.steps)
print(m)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment