[英]Why does my Game of Life simulation slow down to a crawl within seconds? Matplotlib to blame?
[英]Why does my Tkinter Game of Life Implementation slow down progressively?
編輯:
對於將來遇到此問題的任何人:
請檢查您是否有創建 object 實例的代碼塊,並在詢問類似內容之前先將其刪除。
** 問題開始:**
我想用 Tkinter 來實現康威的生命游戲。 我的代碼似乎確實有效,但每次我啟動應用程序時,它都會變慢,直到 canvas 每秒更新一次。
我已經研究過類似的問題,但這里的問題是,在每一個問題中,人們不斷創建矩形,這顯然會導致幀速率問題,但我在我的實現中改變了它(我用 ROWS*COLS 矩形初始化 canvas ,然后只改變它們的顏色)。
負責更新 canvas 的主要 function 是“startConway()” - function。 如您所見,我嘗試測量時間 (t0,t1,t2) 以查看是否有一個 for 循環導致問題,但即使 canvas 變慢,時間幾乎保持不變並且始終低於 20 毫秒。
關於 Tkinter 有什么我不知道的地方阻礙了我的進步嗎? 還是我的方法遠遠慢? 哪里可以改進?
如果您想嘗試一下,只需復制代碼,然后運行它。 在 canvas 上,單擊一些像素,然后最后開始 Conway 游戲,單擊黑色像素。
提前致謝。
這是代碼:
import tkinter as tk
import numpy as np
import time
import random
import copy
import math
# Set number of rows and columns
ROWS = 10
COLS = 10
ANIMATION_DELAY = 50
NEIGHBOUR_SEARCH_DELAY = 0
BORDER_PROB = 0.2
ITERATIONS_CONWAY = 1000
# Create a grid of None to store the references to the tiles
cells = [[None for _ in range(ROWS)] for _ in range(COLS)]
class Cell:
def __init__(self, col, row):
self.col = col
self.row = row
self.rect = None
self.text = None
createRectangle(self,"","","")
# extras for A_Star:
self.cost_g = 0
self.cost = 0
self.parent = None
self.dist_to_neighbours = []
def equals(self,cell):
return (self.col == cell.col and self.row == cell.row)
def changeText(self,txt,color):
c.itemconfig(self.text,text=txt,fill=color)
def changeRect(self,color):
c.itemconfig(self.rect, fill=color)
def toString(self):
return str(self.col) + "|" + str(self.row)
# extras for A_Star:
def getDist(self,cell):
return 1
def callback2(event):
# Calculate column and row number
col = int(event.x/col_width)
row = int(event.y/row_height)
clicked_cell = cells[col][row]
# If the tile is not filled, create a rectangle
if not c.itemcget(clicked_cell.rect,"fill") == "black":
clicked_cell.changeRect("black")
else:
startConway(ITERATIONS_CONWAY)
def startConway(iteration):
if iteration == 0:
return
alive = np.zeros([COLS,ROWS])
t0 = time.time()
for row in range(ROWS):
for col in range(COLS):
current_cell = cells[col][row]
neighbours = getAliveNeighbours(current_cell)
isAlive = c.itemcget(current_cell.rect,"fill") == "black"
willSurvive = isAlive and (neighbours == 2 or neighbours == 3)
willResurrect = not isAlive and neighbours == 3
if willSurvive or willResurrect:
alive[col][row] = 1
else:
alive[col][row] = 0
t1 = time.time()
for row in range(ROWS):
for col in range(COLS):
current_cell = cells[col][row]
isAlive = alive[col][row]
if isAlive:
current_cell.changeRect("black")
else:
current_cell.changeRect("white")
t2 = time.time()
root.after(ANIMATION_DELAY,startConway,iteration-1)
total = t1-t0
print("neighbour Loop: ", t1-t0)
print("draw Loop: ", t2-t1)
print("----------------------")
def getAliveNeighbours(coord):
count = 0
upper_left = Cell(coord.col - 1,coord.row - 1)
neighbours = []
for row in range(3):
for col in range(3):
new_col = (upper_left.col + col) % COLS
new_row = (upper_left.row + row) % ROWS
isStartingCell = (row == 1 and col == 1)
isAlive = c.itemcget(cells[new_col][new_row].rect,"fill") == "black"
if not isStartingCell and isAlive:
count = count + 1
return count
def createRectangle(cell,rect_color,txt,text_color):
cell.rect = c.create_rectangle(cell.col*col_width, cell.row*row_height, (cell.col+1)*col_width, (cell.row+1)*row_height, fill=rect_color)
cell.text = c.create_text(((cell.col*col_width + (cell.col+1)*col_width)/2, (cell.row*row_height + (cell.row+1)*row_height)/2), text=txt, fill=text_color)
def initializeCanvas(hasBorder):
for row in range(ROWS):
for col in range(COLS):
cells[col][row] = Cell(col,row)
if hasBorder and (row == 0 or col == 0 or col == COLS-1 or row == ROWS-1):
cells[col][row].changeRect("black")
root = tk.Tk()
c = tk.Canvas(root, width=500, height=500, borderwidth=5, background='white')
c.pack()
c.bind("<Button-1>", callback2)
c.update()
col_width = c.winfo_width()/COLS
row_height = c.winfo_height()/ROWS
initializeCanvas(False)
root.mainloop()
每次調用getAliveNeighbors
時,都會創建一個新的Cell
實例。 這會在 canvas 上創建一個新矩形。 您每 50 毫秒調用此 function 100 次(10 行乘以 10 列)。 因此,您每秒鍾都在創建 2,000 個新矩形。
一旦您在 canvas 上獲得數萬個對象,canvas 就會出現已知的性能問題,這將以每秒 2,000 個矩形的速度很快發生。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.