繁体   English   中英

试图解决在康威的生命游戏中寻找邻居的问题

[英]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 + 1y - 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 之一。现在两个cellsnew_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

1几个网站没有帮助,包括 https://www.geeksforgeeks.org/how-to-copy-numpy-array-into-another-array/ 和 https://www.askpython.com/python-modules /numpy/numpy-copy,错误地断言将一个 numpy 数组赋值给另一个数组会生成一个副本。 那不是真的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM