check the edit, I wrote some code while watching The Coding Train on youtube.. the maze backtracking generator. The youtuber wrote the code in javascript and I tried to understand the code while writing in python. It seems he had to change the framerate because his program was so fast just to see the generating part. While mine after some 10ish squares it was already so slow. It cant be an hardware problem, I've got an i5-4690K CPU and a good matching GPU, it must be something in the code! But I can't find what it is.
I rewatched the episodes so I could see what was wrong, but it seems I wrote everything just fine.
from tkinter import *
import math
import random
import time
# initialization canvas
root = Tk()
canvas = Canvas(root, width=400, height=400, bg="#333333")
canvas.pack()
# some global variables
w = 40;
cols = math.floor(int(canvas["width"])/w)
rows = math.floor(int(canvas["height"])/w)
grid = []
current = None
class Cell():
line_color = "#AAAAAA"
visited_color = "green"
visited = False
rectangle = None
def __init__(self, i, j):
self.i = i
self.j = j
self.wall = [True, True, True, True] # top , right, bottom, left
def __repr__(self):
return "({}, {})".format(self.i, self.j)
def draw_lines(self):
x = self.i*w
y = self.j*w
if self.visited :
self.rectangle = canvas.create_rectangle(x, y, x+w, y+w, fill="purple", outline="")
canvas.update()
if self.wall[0]:
canvas.create_line(x, y, x+w, y, fill=self.line_color)
else:
canvas.create_line(x, y, x+w, y, fill="purple")
if self.wall[1]:
canvas.create_line(x+w, y, x+w, y+w, fill=self.line_color)
else:
canvas.create_line(x+w, y, x+w, y+w, fill="purple")
if self.wall[2]:
canvas.create_line(x, y+w, x+w, y+w, fill=self.line_color)
else:
canvas.create_line(x, y+w, x+w, y+w, fill="purple")
if self.wall[3]:
canvas.create_line(x, y, x, y+w, fill=self.line_color)
else:
canvas.create_line(x, y, x, y+w, fill="purple")
def checkNeighbors(self):
neighbors = []
top = None
bottom = None
left = None
right = None
if index(self.i, self.j-1) != -1:
top = grid[index(self.i, self.j-1)]
if index(self.i, self.j+1) != -1:
bottom = grid[index(self.i, self.j+1)]
if index(self.i-1, self.j) != -1:
left = grid[index(self.i-1, self.j)]
if index(self.i+1, self.j) != -1:
right = grid[index(self.i+1, self.j)]
if top is not None and top.visited is False:
neighbors.append(top)
if right is not None and right.visited is False:
neighbors.append(right)
if bottom is not None and bottom.visited is False:
neighbors.append(bottom)
if left is not None and left.visited is False:
neighbors.append(left)
if len(neighbors) > 0:
r = random.randint(0, len(neighbors)-1)
return neighbors[r]
else:
return None
def removeWalls(a, b):
x = a.i - b.i
y = a.j - b.j
if x != 0:
if x == 1:
a.wall[3] = False
b.wall[1] = False
else:
a.wall[1] = False
b.wall[3] = False
if y != 0:
if y == 1:
a.wall[0] = False
b.wall[2] = False
else:
a.wall[2] = False
b.wall[0] = False
def index(i, j):
if j < 0 or j > rows - 1 or i < 0 or i > cols - 1:
return -1
return j + i * cols
def setup():
global current
for i in range(rows):
for j in range(cols):
cell = Cell(i, j)
grid.append(cell)
current = grid[0]
next_one = None
def draw():
global current
global next_one
stack = []
almost = False
while True:
current.visited = True
for cell in grid:
cell.draw_lines()
next_one = current.checkNeighbors()
if next_one:
stack.append(current)
removeWalls(current, next_one)
current = next_one
elif len(stack) > 0:
cell = stack.pop()
current = cell
for cell in grid:
print(cell.visited)
setup()
draw()
root.mainloop()
I'm sorry to put all the code, but I think all of it is relevant for what comes to performance, haven't put any useful comments, sorry I'm trying to become a better programmer and change that bad habit
BIG EDIT: I tested to just draw my maze once I finished calculating it, and it takes less than a second, so I figure it has to be with the amount of widgets (lines) I'm creating..? How could I minimize the widgets so I could see the maze being created like I wanted to?
You draw lines even if they didn't change. Instead, draw only the changed cells.
Besides, you have endless loop. Even if stack contains no more elements, you don't stop. Here you should break the loop.
Here is an improvement:
def draw():
for cell in grid:
cell.draw_lines()
global current
global next_one
stack = []
almost = False
while True:
current.visited = True
next_one = current.checkNeighbors()
if next_one:
stack.append(current)
removeWalls(current, next_one)
current.draw_lines()
next_one.draw_lines()
current = next_one
elif len(stack) > 0:
cell = stack.pop()
current = cell
else:
break