微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么我的 Conway's Game of Life 更新不正确?

如何解决为什么我的 Conway's Game of Life 更新不正确?

我目前正在调整 electronut 的“A simple Python matplotlib implementation of Conway's Game of Life”以在不使用 numpy 模块的情况下运行(不是出于任何原因,而是为了我自己的娱乐和练习)。我相信我遇到了 this issue,如其他帖子中描述的有关实施康威生命游戏的问题。 This is the result of my code so far. 我相信我的细胞比它们应该更新的更早;但是,我不明白我正在更新复制的网格上的单元格并在完全不同的函数中交换复制的网格这一事实。任何帮助将不胜感激,在这一点上,我更好奇是什么导致了这个问题,而不是我对此感到沮丧。这是我的代码

# based off of electronut's "A simple Python matplotlib implementation of Conway's Game of Life"
# https://gist.github.com/electronut/5836145

import matplotlib.pyplot as plt 
import matplotlib.animation as animation
import random as rnd

#init biz
cellCount = 100
ALIVE = 255
DEAD = 0

# states in which a cell can exist
states = [ALIVE,DEAD]

#generate initial grid
grid = [[rnd.choice(states) for i in range(cellCount)] for j in range(cellCount)]

#return a new grid for next generation
def nextGen():
    global grid
    newGrid = grid.copy()
    for i in range(cellCount):
        for j in range(cellCount):
            #calculate neighbor total
            total = (grid[(i-1)%cellCount][j] + grid[(i+1)%cellCount][j] + 
                grid[i][(j-1)%cellCount] + grid[i][(j+1)%cellCount] + 
                grid[(i-1)%cellCount][(j-1)%cellCount] + grid[(i+1)%cellCount][(j+1)%cellCount] +
                grid[(i+1)%cellCount][(j-1)%cellCount] + grid[(i-1)%cellCount][(j+1)%cellCount])/255
            if grid[i][j] == ALIVE:
                if (total < 2) or (total > 3):
                    newGrid[i][j] = DEAD
            else:
                if total == 3:
                    newGrid[i][j] = ALIVE
    return newGrid

#update global grid using next gen grid
def update(data):
    global grid
    new = nextGen()
    mat.set_data(new)
    grid = new
    return [new]

#matplotlib magic
fig,ax = plt.subplots()
mat = ax.matshow(grid)
ani = animation.FuncAnimation(fig,update,interval=100,save_count=50)
plt.show()

Game of life rules not working properly

解决方法

你遇到的大问题是这个声明:

newGrid = grid.copy()

list.copy() 不做深拷贝。 grid 是一个包含 100 个子列表的列表。当您进行该复制时,它会创建一个新列表,但该列表包含对与原始网格相同的 100 个子列表的引用。我建议你从一个空的 newgrid 开始并填写它。这是代码的相关部分。我将您的随机设置更改为滑块以证明它有效。

#generate initial grid
#grid = [[rnd.choice(states) for i in range(cellCount)] for j in range(cellCount)]
grid = [[0 for i in range(cellCount)] for j in range(cellCount)]
grid[10][10] = grid[10][11] = grid[10][12] = ALIVE
grid[11][12] = grid[12][11] = ALIVE

#return a new grid for next generation
def nextGen():
    newGrid = []
    for i in range(cellCount):
        newRow = []
        for j in range(cellCount):
            #calculate neighbor total
            total = (grid[(i-1)%cellCount][j] + grid[(i+1)%cellCount][j] +
                grid[i][(j-1)%cellCount] + grid[i][(j+1)%cellCount] +
                grid[(i-1)%cellCount][(j-1)%cellCount] + grid[(i+1)%cellCount][(j+1)%cellCount] +
                grid[(i+1)%cellCount][(j-1)%cellCount] + grid[(i-1)%cellCount][(j+1)%cellCount])//255
            if grid[i][j] == ALIVE:
                if (total < 2) or (total > 3):
                    newRow.append( DEAD )
                else:
                    newRow.append( ALIVE )
            else:
                if total == 3:
                    newRow.append( ALIVE )
                else:
                    newRow.append( DEAD )
        newGrid.append(newRow)
    return newGrid

请注意,除非您为全局分配一个新值,否则您不需要 global,您在此处不这样做。即便如此,您也可以考虑将 grid 作为参数传入,而不是使用全局变量。全局是邪恶的。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。