This question already has answers here:
Conway's Game of Life Update(Next Generation)
                                
                                    (2个答案)
                                
                        
                                5年前关闭。
            
                    
我正在尝试使用pygame在python中制作conway的生活游戏。我不知道为什么,但是生成的模式却遥遥无期。我已经看过一百万遍代码,看不到有什么问题。

这是其中几代人的截图


这是游戏的完整代码。

import pygame, sys
from pygame.locals import *
from random import randint
import numpy

#inititalize
pygame.init()
clock = pygame.time.Clock()

#constants
FPS = 10
BLACK = (0,0,0)
RED = (255,0,0)
GREY = (30,30,30)
SCREENX = 640
SCREENY = 480
CELLSIZE = 10
HEIGHT = SCREENY/CELLSIZE
WIDTH = SCREENX/CELLSIZE

#set up window
window = pygame.display.set_mode((SCREENX, SCREENY))
pygame.display.set_caption('Game of Life')
window.fill(BLACK)

#generate random seed
cells = numpy.zeros((WIDTH,HEIGHT), dtype=numpy.int)
for x in range(0,WIDTH):
    for y in range(0,HEIGHT):
        #0 is a dead cell, 1 is an alive cell
        cells[x][y] = randint(0,1)

def findNeighbors(grid, x, y):
    if 0 < x < len(grid) - 1:
        xi = (0, -1, 1)
    elif x > 0:
        xi = (0, -1)
    else:
        xi = (0, 1)

    if 0 < y < len(grid[0]) - 1:
        yi = (0, -1, 1)
    elif y > 0:
        yi = (0, -1)
    else:
        yi = (0, 1)

    for a in xi:
        for b in yi:
            if a == b == 0:
                continue
            yield grid[x + a][y + b]

def update(grid, x, y):
    #determine num of living neighbors
    neighbors = findNeighbors(cells,x,y)
    alive = 0
    for i in neighbors:
        if i == 1:
            alive+=1

    #if current cell is alive
    if grid[x][y] == 1:
        #kill if less than 2 or more than 3 alive neighbors
        if (alive < 2) or (alive > 3):
            return 0
        else:
            return 1
    #if current cell is dead
    elif grid[x][y] == 0:
        #make alive if 3 alive neighbors
        if alive == 3:
            return 1
        else:
            return 0

#main loop
while True:

    #check if user wants to exit
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

    #update cells
    for x in range(0,WIDTH):
        for y in range(0,HEIGHT):
            cells[x][y] = update(cells,x,y)

    #draw grid
    for x in range(0,SCREENX,CELLSIZE):
        for y in range(0,SCREENY,CELLSIZE):
            #if cell is alive
            if cells[x/CELLSIZE][y/CELLSIZE] == 1:
                #draw red square
                pygame.draw.rect(window, RED, [x, y, CELLSIZE, CELLSIZE])
            else:
                #draw black square
                pygame.draw.rect(window, BLACK, [x, y, CELLSIZE, CELLSIZE])
            #draw square border
            pygame.draw.rect(window, GREY, [x, y, CELLSIZE, CELLSIZE], 1)

    #draw updates
    pygame.display.update()

    #generations per second
    clock.tick(FPS)


我不认为问题出在findNeighbors函数上,因为我是从this stackoverflow答案得到的。因此,我认为问题出在更新功能上,但根据游戏规则,我看不到逻辑错误之处。

最佳答案

我怀疑这是问题所在:

cells[x][y] = update(cells,x,y)


您只有一个网格,而您仍在从中进行计算时将对其进行更新。 n + 1代仅应考虑n代的信息-而当前您混合了n和n + 1的信息。您最终将获得位于您上方和左侧的邻居的新值,以及位于您右侧和下方的邻居的旧值,因为尚未重新计算它们。

因此,例如,采用以下模式(其中#表示“有效”):

...
###
...


那应该去:

.#.
.#.
.#.


...但是实际上,您最终会(我认为):

.##
#.#
... // Bottom-middle only has one live neighbour at computation time


到我们计算右上角时,它有三个邻居。左中角在计算时有2个活邻居。中心有4个,右中间有2个。在计算时,底行没有任何三个邻居,因此它保持死状态。

通常,Conway的Life实现将为每一代计算一个全新的网格,或者在两个网格之间翻转,从而相互计算所有网格。

关于python - PyGame中的Conway的《生命游戏》无法生成正确的图案,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23553331/

10-12 20:22