【问题标题】:Game of life neighbours issue生活游戏邻居问题
【发布时间】:2018-02-25 08:41:07
【问题描述】:

我正在尝试在 python 中创建我的Game of life 代码,但是当它检查活着的邻居时,它似乎有问题。我已经尝试解决它 2 天,但我仍然不知道我错过了什么。 这是分解成片段的代码。

from random import randrange
from tkinter import *
from time import sleep
root = Tk()
canv = Canvas(width = 800, height = 800)
canv.pack()

def value():
    if randrange(16) == 0:
        return 1
    else:
        return 0 

我在 tkinter 中设置了画布并创建了一个函数来确定单元格的状态,因此每个单元格都有 1/x 的机会首先活着。

def pprint(lst):
    for row in lst:
        print(row)

我在尝试调试时创建了一个漂亮的打印函数。

def nb(life,row,col):
    count = 0
    #print(x,y)
    #print(life[x][y])
    for r in [row-1, row, row+1]:
        for c in [col-1,col,col+1]:
            if life[r][c] == 1:
                count += 1
    if life[row][col] == 1:
        count -= 1
    #print(count,end=" ")
    return count

这个函数应该返回一个单元格拥有的存活邻居的数量。 (整个代码的调试留下的注释)

def ud(life,life2,size,box):        
    #print(life)        
    while True:
        try:
            for row in range(1,size+1):
                for col in range(1,size+1):
                    #print(row,col)
                    a = nb(life,row,col)
                    print("[{0},{1}]".format(row,col), end =" ")
                    print(a, end=" ")
                    
                    if ((1<a) and (a<4)):
                        life2[row][col] = 1
                        canv.itemconfig(box[row-1][col-1], fill ="black")
                                                    
                    else:
                        life2[row][col] = 0
                        canv.itemconfig(box[row-1][col-1], fill ="white")
                print("")                         
            print("ok")
            #print(life2[19][19])
            root.update()
            pprint(life)
            #sleep(5)

            life = life2
            sleep(800/size**2)
            print("")
        except:
            break

这是主要的更新功能。它应该为 life 2d 数组中的每个单元格运行 nb 函数,并确定它在 life2 中的值。 “box”是一个二维数组,其中包含视觉网格上每个单元格的矩形 tkinter id。 (是的,打印功能也是用来调试的。)

#######
size = 10
w = 10
box = [[canv.create_rectangle(y*w,x*w,y*w+10,x*w+10) for y in range(size)] for x in range(size)]
life = [[value() for y in range(size)] for x in range(size)]
life2 = [[0 for y in range(size+2)] for x in range(size+2)]
for i in range(1,size+1):
    life2[i] = [0] + life[i-1] + [0]
#life = life2

pprint(life)
root.update()
ud(life2,life2,size,box)

del box
del life
del life2

我创建了 box 变量(w = 单元格的宽度)并生成随机的活单元格。然后我为“life”创建一个“0”帧(这样程序在角落处时不会在 nb 检查时中断。而且我知道我可以使用 try/except)。然后我用参数启动 ud 函数(大小 = 一行中的单元格数;两个生命矩阵参数都是 life2,因为理论上第二个将被完全重写)

那么程序有什么问题呢?

【问题讨论】:

  • 您告诉我们的所有问题都是“它似乎有问题”。以什么方式?你是否得到了意想不到的结果?如果是这样,你得到了什么,你期望什么?

标签: python python-3.x conways-game-of-life


【解决方案1】:

def ud(life,life2,size,box): 内的这一行 life = life2 使得 lifelive2 都命名/指向相同的数据。您需要深拷贝life2 并让life 指向绝对独立的数据。

深拷贝,因为您的 life2 包含其他列表,如果您只是 浅拷贝 通过执行 live = life2[:] 您仍然会遇到同样的问题 - live 会这样有唯一的 refs 可以在其内部列出,但内部列表的 refs 指向的数据仍将被共享。您使用import copy & copy.deepcopy(...) 进行深度复制。


重命名

import copy
print()
a = [[1,3,5],[2,4,6]]
b = a  # second name, same data
a[0] = [0,8,15]    # replaces the ref on a[0] with a new one, b == a 
a[1][2] = 99       # modifies a value inside the 2nd list ref, b == a
print (a,"=>",b)   # b is just another name for a

输出

# nothing got preserved, both identical as b ist just another name for a
([[0, 8, 15], [2, 4, 99]], '=>', [[0, 8, 15], [2, 4, 99]])

浅拷贝

a = [[1,3,5],[2,4,6]]
b = a[:]  # shallow copy
a[0] = [0,8,15]       # replaces one ref with a new one (only in a)
a[1][2] = 99          # modifies the value inside 2nd list, same ref in a&b
print (a,"=>",b)

输出

# b got "unique" refs to the inner lists, if we replace one in a 
# this does not reflect in b as its ref is unique. chaning values 
# inside a inner list, will be reflected, as they are not uniqe
([[0, 8, 15], [2, 4, 99]], '=>', [[1, 3, 5], [2, 4, 99]])

深拷贝

a = [[1,3,5],[2,4,6]]
b = copy.deepcopy(a)  # deep copy
a[0] = [0,8,15]       # only a modified
a[1][2] = 99          # only in a modified
print (a,"=>",b)

输出

# completely independent - b shares no refs with former a, all got new'ed up
([[0, 8, 15], [2, 4, 99]], '=>', [[1, 3, 5], [2, 4, 6]])

如果您将上面的print 替换为

print(id(a), id(a[0]), id(a[1]), id(b), id(b[0]), id(b[1]))

您会得到 a 的唯一 ID 的输出,它与 b 的唯一 ID 及其内容一样:

重命名

`a`: 139873593089632, 139873593146976, 139873593072384 
`b`: 139873593089632, 139873593146976, 139873593072384

`a`: 139873593229040, 139873593089632, 139873593146040
`b`: 139873593227168, 139873593088552, 139873593146040

`a`: 139873593253968, 139873593227168, 139873593072384
`b`: 139873593229040, 139873593089632, 139873593254112

【讨论】:

    猜你喜欢
    • 2019-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多