maze clusters creator & growing tree algorithm

This commit is contained in:
Xevion
2019-10-14 12:48:05 -05:00
parent b5e691172f
commit cd70c32f85
4 changed files with 250 additions and 0 deletions

View File

@@ -0,0 +1,102 @@
import random
class Mover:
def __init__(self, x, y):
self.x, self.y = x, y
self.active = True
global grid
self.current = grid[x][y]
self.hue = random.randint(0, 360)
def tick(self):
global grid
if not grid[self.current.x][self.current.y].visited:
grid[self.x][self.y].active = True
grid[self.current.x][self.current.y].visited = True
grid[self.current.x][self.current.y].hue = self.hue
neighbors = self.current.getNeighbors()
if neighbors:
neighbor = random.choice(neighbors)
neighbor = grid[neighbor[0]][neighbor[1]]
neighbor.parent = self.current
openBetween(self.current.x, self.current.y, neighbor.x, neighbor.y)
self.current = neighbor
else:
if self.current.parent:
self.current = self.current.parent
class Cell:
def __init__(self, x, y):
self.x, self.y = x, y
self.visited = False
self.hue = -1
self.active, self.bottom, self.right = False, True, True
self.parent, self.visited = None, None
def getNeighbors(self):
neighbors = []
global grid, offsets
for pos, offset in enumerate(offsets):
neighbor = (self.x + offset[0], self.y + offset[1])
if cellExists(neighbor):
if not grid[neighbor[0]][neighbor[1]].visited:
neighbors.append(neighbor)
return neighbors
def render(self):
global divX, divY
translate(divX * self.x, divY * self.y)
if self.visited:
noStroke()
fill(self.hue, 360, 360)
rect(1, 1, divX - 1, divY - 1)
# if self.active:
# self.active = False
# noStroke()
# fill(0, 360, 0)
# rect(1, 1, divX - 1, divY - 1)
if self.right:
line(divX, 0, divX, divY)
if self.bottom:
line(0, divY, divX, divY)
resetMatrix()
def openBetween(x1, y1, x2, y2):
global offsets
# Down, Right, Left, Up
if not cellExists((x1, y1)) or not cellExists((x2, y2)):
return
offset = (x2 - x1, y2 - y1)
if offset == offsets[0]:
grid[x1][y1].bottom = False
elif offset == offsets[1]:
grid[x1][y1].right = False
elif offset == offsets[2]:
grid[x2][y2].right = False
elif offset == offsets[3]:
grid[x2][y2].bottom = False
def cellExists(coordinate):
x, y = coordinate
return not (x < 0 or x >= columns or y < 0 or y >= rows)
def setup():
size(750, 750)
colorMode(HSB, 360)
global divX, divY, columns, rows, grid, movers, offsets
columns, rows = 100, 100
divX, divY = width / float(columns), height / float(rows)
grid = [[Cell(x, y) for y in range(rows)] for x in range(columns)]
# Down, Right, Left, Up
offsets = [(0, 1), (1, 0), (-1, 0), (0, -1)]
movers = [Mover(random.randint(0, columns-1), random.randint(0, rows-1)) for _ in range(columns * rows / 1000)]
frameRate(99999)
def draw():
global grid, movers
background(204)
for _ in range(50):
for mover in movers:
mover.tick()
for row in grid:
for cell in row:
cell.render()

View File

@@ -0,0 +1,2 @@
mode=Python
mode.id=jycessing.mode.PythonMode

View File

@@ -0,0 +1,144 @@
import random, time
class Cell:
def __init__(self, x, y):
self.x, self.y = x, y
self.right, self.bottom, self.visited, self.live = True, True, False, False
# Identify the neighbors of the cell
def neighbors(self):
global offsets
neighbors = []
for offset in offsets:
neighbor = (self.x + offset[0], self.y + offset[1])
if not valid(neighbor):
continue
if grid[neighbor[0]][neighbor[1]].visited:
continue
neighbors.append(neighbor)
return neighbors
# Render the single cell
def render(self):
global divX, divY
translate(self.x * divX, self.y * divY)
# Drawing Cell Background
# Visited, Unvisited, Highlighted
if self.live:
fill(244, 117, 117)
elif self.visited:
fill(255)
else:
fill(204)
noStroke()
rect(0, 0, divX, divY)
# Drawing Cell Lines
stroke(0)
fill(255)
strokeWeight(2.5)
if self.bottom:
line(0, divY, divX, divY)
if self.right:
line(divX, 0, divX, divY)
resetMatrix()
# Open walls between two cells on the grid
def openWalls(x1, y1, x2, y2):
global offsets
# Bottom, Right, Left, Top
offset = (x2 - x1, y2 - y1)
if offset == offsets[0]:
grid[x1][y1].bottom = False
if offset == offsets[1]:
grid[x1][y1].right = False
if offset == offsets[2]:
grid[x2][y2].right = False
if offset == offsets[3]:
grid[x2][y2].bottom = False
# Validates whether a coordinate is valid with the curret columns and rows set
def valid(coordinate):
global columns, rows
return not (coordinate[0] < 0 or coordinate[0] >= columns or coordinate[1] < 0 or coordinate[1] >= rows)
# Generates a new grid and cellList (with start) for the maze generation.
# Serves mostly to ease the process of regenerating a maze without restarting the Sketch
def generate(xx=None, yy=None):
global columns, rows, offsets
# Bottom, Right, Left, Top
offsets = [(0, 1), (1, 0), (-1, 0), (0, -1)]
columns, rows = 50, 50
global grid, divX, divY
divX, divY = width / float(columns), height / float(rows)
grid = [[Cell(x, y) for y in range(rows)] for x in range(columns)]
global switch
switch = True
global cellList
cellList = []
if xx != None and yy != None:
start = pixelToCoordinates(xx, yy)
else:
start = (random.randint(0, columns-1), random.randint(0, rows-1))
cellList.append(start)
def pixelToCoordinates(x, y):
return int(x / float(divX)), int(y / float(divY))
def setup():
size(750, 750)
generate()
# Runs the cell.render() action on every cell
def render():
background(0)
for row in grid:
for cell in row:
cell.render()
def tick():
for _ in range(columns + rows):
if len(cellList) > 0:
global switch
if switch:
# most recent
# index = len(cellList) - 1
# select = cellList[index]
# oldest
index = 0
select = cellList[0]
else:
# most random
index = random.randint(0, len(cellList)-1)
select = cellList[index]
neighbors = grid[select[0]][select[1]].neighbors()
if len(neighbors) < 1:
grid[select[0]][select[1]].live = False
cellList.pop(index)
else:
new = random.choice(neighbors)
openWalls(select[0], select[1], new[0], new[1])
grid[new[0]][new[1]].visited = True
grid[new[0]][new[1]].live = True
cellList.append(new)
else:
# time.sleep(2)
return
def draw():
global switch
switch = not switch
render()
# if len(cellList) == 0:
# generate()
tick()
def mouseClicked():
generate(mouseX, mouseY)

View File

@@ -0,0 +1,2 @@
mode=Python
mode.id=jycessing.mode.PythonMode