python - Game Of Life 游戏的简单版本行为不正确
问题描述
这是完整的代码。我遗漏了一些不必要的东西
import random
import pygame
FPS = 1
WIDTH, HEIGHT = 400, 400
RESOLUTION = 40
GRAY = (200, 200, 200)
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
WIN = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Game of Life")
def draw_grid(win, cols, rows):
for i in range(cols):
for j in range(rows):
x = i * RESOLUTION
y = j * RESOLUTION
pygame.draw.rect(win, GRAY, (x, y, RESOLUTION, RESOLUTION), 1)
def make_2d_array(cols, rows):
arr = []
for i in range(cols):
arr.append([])
for j in range(rows):
arr[i].append(0)
return arr
def count_neighbours(grid, x, y):
neighbourCount = 0
for i in range(-1, 2):
for j in range(-1, 2):
neighbourCount += grid[x + i][y + j]
return neighbourCount
def draw_squares(win, grid, cols, rows):
#nextA = make_2d_array(cols, rows)
nextA = grid
for i in range(len(grid)):
for j in range(len(grid[i])):
x = i * RESOLUTION
y = j * RESOLUTION
if grid[i][j] == 1:
pygame.draw.rect(win, WHITE, (x, y, RESOLUTION, RESOLUTION))
elif grid[i][j] == 0:
pygame.draw.rect(win, BLACK, (x, y, RESOLUTION, RESOLUTION))
for i in range(cols):
for j in range(rows):
if i == 0 or i == cols-1 or j == 0 or j == rows-1:
nextA[i][j] = grid[i][j]
else:
state = grid[i][j]
neighbours = count_neighbours(grid, i, j)
if state == 0 and neighbours == 3:
nextA[i][j] = 1
elif state == 1 and (neighbours < 2 or neighbours > 3):
nextA[i][j] = 0
else:
nextA[i][j] = state
grid = nextA
def main():
run = True
clock = pygame.time.Clock()
cols = int(WIDTH / RESOLUTION)
rows = int(HEIGHT / RESOLUTION)
grid = make_2d_array(cols, rows)
"""for i in range(cols):
for j in range(rows):
grid[i][j] = random.randint(0, 1)"""
#glider test
grid = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
while run:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
draw_squares(WIN, grid, cols, rows)
draw_grid(WIN, cols, rows)
pygame.display.update()
pygame.quit()
main()
我正在关注一个用 Java 或 JavaScript 编写的教程,但规则是相同的,应该可以工作,但不能。简化的规则应该是这样的:
if state == 0 and neighbours == 3:
nextA[i][j] = 1
elif state == 1 and (neighbours < 2 or neighbours > 3):
nextA[i][j] = 0
else:
nextA[i][j] = state
但是当我运行代码时,我很确定第一个 if 语句有效(很难理解程序的行为很奇怪)。
解决方案
规则的执行是正确的,但在康威的生命游戏中,你必须每回合创建一个新的空网格。新网格中的字段必须根据当前网格中的字段和演化规则来确定。
在 中创建一个新的空网格draw_squares
,但从函数返回新网格:
def draw_squares(win, grid, cols, rows):
# nextA = grid # <--- DELETE
nextA = make_2d_array(cols, rows) # <--- ADD
# [...]
return nextA # <-- return the new grid
通过将返回的新网格分配给以使新网格成为当前网draw_squares
格grid
:
grid = draw_squares(WIN, grid, cols, rows)
此外,邻居的计算是错误的。字段不是自身的邻居:
def count_neighbours(grid, x, y):
neighbourCount = 0
for i in range(-1, 2):
for j in range(-1, 2):
if i != 0 or j != 0:
neighbourCount += grid[x + i][y + j]
return neighbourCount