[英]Trying to fix a problem with finding neighbors in Conway's Game of Life
我試圖在 python 中使用 Tkinter 重現 Conway 的生命游戲,但在檢查鄰居時卡住了。 我似乎找不到解決我的問題的方法。 如果一個細胞是活的,則使用 numpy 存儲它,0 表示死細胞,1 表示活細胞。 function “get_neighbours” 檢查單元格是否不在角落或旁邊,並返回每個單元格擁有的鄰居數量。 function“重新計算”基本上是用 0 和 1 制作一個新的棋盤,然后替換原來的棋盤並重新繪制所有內容。 但是與已經存在的游戲相比,進度是不同的。
import tkinter as tk
import numpy as np
win = tk.Tk()
WIDTH = 500
HEIGHT = 500
vs = 10
absvs = vs
cells = np.zeros((WIDTH//vs, HEIGHT//vs), dtype=int)
cells_new = np.zeros((WIDTH//vs, HEIGHT//vs), dtype=int)
def get_neighbours(x, y):
total = 0
if x > 0:
total += cells[x - 1, y]
if x > 0 and y > 0:
total += cells[x - 1, y - 1]
if y > 0:
total += cells[x, y - 1]
if x > 0 and y < (HEIGHT // absvs - 1):
total += cells[x - 1, y + 1]
if x < (WIDTH // absvs - 1):
total += cells[x + 1, y]
if x < (WIDTH // absvs - 1) and y < (HEIGHT // absvs - 1):
total += cells[x + 1, y + 1]
if y < (HEIGHT // absvs - 1):
total += cells[x, y + 1]
if x > 0 and y < (HEIGHT // absvs - 1):
total += cells[x - 1, y + 1]
return total
def recalculate():
global cells, cells_new
for y in range(HEIGHT//absvs):
for x in range(WIDTH//absvs):
temp = get_neighbours(x, y)
if (temp == 2 and cells[x, y] == 1) or (temp == 3 and cells[x, y] == 1):
cells_new[x, y] = 1
elif temp == 3 and cells[x, y] == 0:
cells_new[x, y] = 1
elif temp < 2 or temp > 3:
cells_new[x, y] = 0
cells = cells_new
canvas.delete("all")
create_stage()
redraw_cell()
def slider_changer(e):
global vs
canvas.delete("all")
vs = w.get()
create_stage()
redraw_cell()
def create_cell(e):
global cells
tx = e.x // vs
ty = e.y // vs
x = tx * vs
y = ty * vs
canvas.create_rectangle(x, y, x + vs, y + vs, fill="gray")
cells[tx, ty] = 1
print(get_neighbours(tx, ty))
def redraw_cell():
for x in range(WIDTH//vs):
for y in range(HEIGHT//vs):
if cells[x, y] == 1:
canvas.create_rectangle(x * vs, y * vs, x * vs + vs, y * vs + vs, fill="gray")
def create_stage():
for x in range(WIDTH//vs):
canvas.create_line(x*vs, 0, x*vs, HEIGHT)
for y in range(HEIGHT//vs):
canvas.create_line(0, y*vs, WIDTH, y*vs)
canvas = tk.Canvas(width = WIDTH, height = HEIGHT, bg = "white")
canvas.pack()
w = tk.Scale(win, from_=10, to=50, orient="horizontal", command = slider_changer, length = 500)
w.pack()
w2 = tk.Button(win, text = "PRESS ME!!!", command = recalculate)
w2.pack()
create_stage()
canvas.bind("<Button-1>", create_cell)
win.mainloop()
您的代碼中存在以下問題:
在get_neighbours
中,最后一個if
塊與第四個if
塊相同,因此有一個鄰居被計算了兩次,而另一個鄰居根本沒有被計算(在x + 1
和y - 1
處的那個)。 所以替換這個:
if x > 0 and y < (HEIGHT // absvs - 1): total += cells[x - 1, y + 1]
和:
if x < (WIDTH // absvs - 1) and y > 0: total += cells[x + 1, y - 1]
在recalculate
最后對cells
的分配會讓你失去兩個 arrays 之一。現在兩個cells
和new_cells
引用完全相同的數組1 。 這意味着下一次迭代將無法正確計算。 相反,您應該將cells_new
的內容復制到cells
。 所以更換:
cells = cells_new
和:
cells = cells_new.copy()
在recalculate
if...elif..elif
構造(在雙循環內)不處理temp == 2 and cells[x, y] == 1
的情況,因此cells_new[x, y]
可能不是應該重置為0。 事實上,這個結構的最后一部分不應該有條件; 對於先前檢查未處理的所有狀態,它應該是一個包羅萬象的對象。 所以更換:
elif temp < 2 or temp > 3: cells_new[x, y] = 0
和:
else: cells_new[x, y] = 0
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.