繁体   English   中英

在PyGame中Conways生命游戏

[英]Conways Game of Life in PyGame

所以我读到了Conways Game of Life并试图用PyGame实现它。

我试图让它面向对象。 它的工作方式是我有一个单元格实例列表,然后检查它们有多少邻居,然后根据它们的邻居保持活着或死亡。 然后这个过程重复进行。

问题是,当我用一些已知的起始模式(例如在下面的代码(CELL_MAP)中)测试它时,它不会按照应有的方式工作。

我一遍又一遍地阅读代码,我真的没有得到我在这里缺少的东西。 我发布了下面的全部代码,因为我不知道我的错误在哪里,但我非常感谢有人会指出我正确的方向。

提前致谢!

import pygame

class Cell:
    def __init__(self, live, xcor, ycor):
        self.alive = live
        self.x = xcor
        self.y = ycor
        self.neighbours = 0

def checkNeighbours(self, cellList):
    for cell in cellList:
        #left
        if cell.x == self.x-1 and cell.y == self.y and cell.alive == True:
            self.neighbours += 1        
        #right
        elif cell.x == self.x+1 and cell.y == self.y and cell.alive == True:
            self.neighbours += 1 
        #upleft
        elif cell.x == self.x-1 and cell.y == self.y-1 and cell.alive == True:
            self.neighbours += 1     
        #up
        elif cell.x == self.x and cell.y == self.y-1 and cell.alive == True:
            self.neighbours += 1 
        #upright
        elif cell.x == self.x+1 and cell.y == self.y-1 and cell.alive == True:
            self.neighbours += 1     
        #downleft
        elif cell.x == self.x-1 and cell.y == self.y+1 and cell.alive == True:
            self.neighbours += 1     
        #down
        elif cell.x == self.x and cell.y == self.y+1 and cell.alive == True:
            self.neighbours += 1 
        #downright
        elif cell.x == self.x+1 and cell.y == self.y+1 and cell.alive == True:
            self.neighbours += 1 

def breed(self):
    if self.alive == False and self.neighbours == 3:
        #dead cell ressurects if neighbours equals 3
        self.alive = True
    elif self.alive and self.neighbours < 2:
        #die from loneliness
        self.alive = False
    elif self.alive and self.neighbours == 2:
        #stay alive
        pass
    elif self.alive and self.neighbours == 3:
        #stay alive
        pass
    elif self.alive and self.neighbours > 3:
        #die from overpopulation
        self.alive = False

def render(self, display):
    if self.alive:
        pygame.draw.rect(display, (0,0,0), [self.x*10, self.y*10, 10, 10])
    elif self.alive == False:
        pygame.draw.rect(display, (0,0,255), [self.x*10, self.y*10, 10, 10])




WID = 33
HEI = 20            
CELL_MAP = [[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,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,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,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,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,1,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,1,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,1,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,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,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,0,0,0,0,0,0,0],
            [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,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,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,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,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,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,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]]

CELL_LIST = []

xc = -1
yc = -1
for yList in CELL_MAP:
    yc += 1
    for x in yList:
        xc += 1
        if x == 0:
            #create dead cell
            newCell = Cell(False, xc, yc)
            CELL_LIST.append(newCell)
        elif x == 1:
            #create alive cell
            newCell = Cell(True, xc, yc)
            CELL_LIST.append(newCell)
    xc = -1



#pygame init

pygame.init()
(width, height) = (WID*10, HEI*10)

pygame.display.set_caption('Game of Life')

screen = pygame.display.set_mode((width, height))

#game loop

def gameLoop():
    gameLoop = True 

    while gameLoop:
        #check for exit
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                gameLoop = False
                pygame.quit()               

        #render cells
        for cell in CELL_LIST:
            cell.render(screen)    

        #check neighbours
        for cell in CELL_LIST:
            cell.checkNeighbours(CELL_LIST)

        pygame.display.flip()

        #breed
        for cell in CELL_LIST:
            cell.breed()

        pygame.time.wait(5)

    quit()

if __name__ == "__main__":
    gameLoop()

我没有安装pygame,所以我无法运行你的代码。 但是,导致错误的错误是,在确定下一代是否存活或死亡后,您不会将单元的邻居计数重置为零。 因此,在每一代中,每个小区的新邻居计数都被添加到先前累积的邻居计数中。 你可能应该在.breed方法中重置。

这是该方法的更紧凑版本:

def breed(self):
    self.alive = self.neighbours == 3 or self.alive and self.neighbours == 2
    self.neighbours = 0

我还有一些关于你的代码的评论。

checkNeighbours方法是非常低效的:每个细胞,它会扫描整个网格寻找一个小区的邻居! 一个简单的替代方法是将您的单元格存储在2D列表中,以便快速找到单元格的邻居。


这是构建CELL_LIST比您的代码目前更紧凑的方式:

CELL_LIST = []
for y, row in enumerate(CELL_MAP):
    for x, v in enumerate(row):
        CELL_LIST.append(Cell(v == 1, x, y))

这与列表理解相同:

CELL_LIST = [Cell(bool(v), x, y)
    for y, row in enumerate(CELL_MAP)
        for x, v in enumerate(row)
]

但正如我之前所说,将CELL_LIST 2D列表可能是一个好主意:

cell_list = [[Cell(bool(v), x, y) for x, v in enumerate(row)]
    for y, row in enumerate(CELL_MAP)]

你的CELL_MAP不是将Life模式放入程序的便捷方式,但我想它可以用于测试目的。 看看我本月早些时候写的一个替代方案的答案

最终,您应该让您的程序能够读取许多Life程序使用的常见RLE格式

您可能还想查看我编写的使用Numpy: numpy_life.py的中等效率版本。 与我链接的其他版本一样,它在Linux终端中显示输出,但两个版本都应该很容易适应pygame或其他GUI框架。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM