簡體   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