我最近看到了John Conway的Game of Life,并决定用Python编写代码。 所以我做到了,但它不能正常工作。
例如,我水平连续有 3 个活细胞。 如果它正常工作,它会从连续 3 个活细胞振荡到一列中的 3 个活细胞,但它不会这样做。
我当前的代码是这样的:
# ("O" == dead cell, "X" == live cell)
# generation 1:
OOO
XXX
OOO
# generation 2:
OOO
OOO
OOO
它应该做的是:
# (O == dead cell, X == live cell)
# generation 1:
OOO
XXX
OOO
# generation 2:
OXO
OXO
OXO
我不知道代码 gremlin 生活在哪个区域,所以我只是在下面发布了整个代码。
import os
import time
# RULES OF LIFE
# 1. Any live cell with less than two live neighbours dies, as if caused by under-population.
# 2. Any live cell with two or three live neighbours lives on to the next generation.
# 3. Any live cell with more than three live neighbours dies, as if by overcrowding.
# 4. Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.
def seed():
board[12][11] = "X"
board[12][12] = "X"
board[12][13] = "X"
def display():
for row in board:
print("".join(row))
def update():
for row in range(0, len(board)):
for column in range(0, len(board[row])):
neighbors = 0
for r in range(-1, 2):
for c in range(-1, 2):
if r != 0 and c != 0:
try:
if board[r][c] == "X":
neighbors += 1
except IndexError:
pass
if board[row][column] == " ": # dead cell
if neighbors == 3: # RULE 4.
temp_board[row][column] = "X"
elif board[row][column] == "X": # live cell
if neighbors < 2: # RULE 1.
temp_board[row][column] = " "
elif neighbors == 2 or neighbors == 3: # RULE 2.
pass
elif neighbors > 3: # RULE 3.
temp_board[row][column] = " "
HEIGHT = 25
WIDTH = 25
board = [[" " for column in range(0, WIDTH)] for row in range(0, HEIGHT)]
temp_board = list(board)
seed()
while True:
display()
update()
board = list(temp_board)
time.sleep(1)
os.system("cls")
我错过了什么?
我发现了三个错误,可能还有更多。以下是我发现的内容的摘要。我将在下面更详细地解释这些:
- 检查相邻单元格时需要包括偏移量。
- 检查相邻单元格时,您需要包括周围的单元格,而不仅仅是与中心单元格对角线的单元格。
- 您需要对开发板进行深度复制。
必要的偏移量
您在此处开始设置代码以处理偏移量:
for r in range(-1, 2):
for c in range(-1, 2):
但是,您永远不会将偏移添加到原始值。从本质上讲,您只是在检查网格的前几个空间。因此,您需要将if board[r][c] == "X"
更改为 if board[row+ r][column + c] == "X"
.
包括所有周围的单元格
您编写了代码来检查周围的单元格(如上所示的 for 循环),并且您知道需要免除单元格本身的测试。您使用此代码排除单元格本身:
if r != 0 and c != 0
但是,只要偏移变量 r
和 c
为零,则此条件将失败。这发生在单元格的上方、下方、右侧和左侧。您需要将条件更改为以下内容:
if (r != 0) or (c != 0) # Parenthesis added for readability, not functionality
这样,如果任何一个偏移量不为零,您将检查相应的单元格。
使用深拷贝
像temp_board = list(board)
这样的赋值会对相同的数据进行新的引用。从本质上讲,它与为同一变量分配一个额外的名称相同。因此,当您在update
功能中更新开发板时,您不是在更新开发板的临时副本,而是通过备用名称更新开发板本身。然后,当进行后续测试时,电路板的状态发生了变化。
要在python中进行深度复制,您需要向文件添加import copy
,然后将当前的复制尝试替换为temp_board = copy.deepcopy(board)
之类的代码。