[英]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.