【问题标题】:Conway's Game of Life - rules康威的生命游戏 - 规则
【发布时间】:2016-11-24 11:32:18
【问题描述】:

下面是康威人生游戏的代码。我目前正在与不正确的功能作斗争 - 细胞仍在繁殖而不是灭绝或收敛点。我认为规则功能出了点问题(我认为,特定规则可以吗?),但我无法弄清楚。如果您知道出了什么问题,我将不胜感激。谢谢

import pygame
import sys
import random
from pygame.locals import *

FPS = 10
fpsClock = pygame.time.Clock()

WINDOWSIZE = 500
CELLSIZE = 5
assert WINDOWSIZE % CELLSIZE == 0, "win size must be a multiple of cell"


class Board():

    def __init__(self):

        pygame.init()
        pygame.display.set_caption('Game of Life')
        self.DISPLAYSURF = pygame.display.set_mode((WINDOWSIZE, WINDOWSIZE))
        self.grid = [[0] * (WINDOWSIZE // CELLSIZE) for i in range(WINDOWSIZE // CELLSIZE)]

    def draw(self):
        i = 0
        j = 0

        for x in range(0, WINDOWSIZE, CELLSIZE):
            for y in range(0, WINDOWSIZE, CELLSIZE):

                if self.grid[i][j] == 0:
                    pygame.draw.rect(
                    self.DISPLAYSURF, (20, 120, 20), Rect((x, y), (CELLSIZE, CELLSIZE)))

                else:
                    pygame.draw.rect(
                    self.DISPLAYSURF, (255, 255, 255), Rect((x, y), (CELLSIZE, CELLSIZE)))

                if j == (WINDOWSIZE // CELLSIZE) - 1:
                    j = 0

                else:
                    j = j + 1

            i = i + 1

    def randomize(self):
        for i in range(CELLSIZE, (WINDOWSIZE // CELLSIZE) - CELLSIZE):
            for j in range(CELLSIZE, (WINDOWSIZE // CELLSIZE) - CELLSIZE):

                if random.randint(0, 100) < 15:
                    self.grid[i][j] = 1


    def rules(self):
        for i in range(CELLSIZE, (WINDOWSIZE // CELLSIZE) - CELLSIZE):
            for j in range(CELLSIZE, (WINDOWSIZE // CELLSIZE) - CELLSIZE):

                neighbors = 0

                if self.grid[i][j] == 0:
                    neighbors = self.grid[i + 1][j] + self.grid[i - 1][j] + self.grid[i][j + 1] + self.grid[i][j - 1] + self.grid[i - 1][j - 1] + self.grid[i + 1][j + 1] + self.grid[i + 1][j - 1] + self.grid[i - 1][j + 1]

                    if neighbors == 3:
                        self.grid[i][j] = 1
                        continue
                    else:
                        self.grid[i][j] = 0

                if self.grid[i][j] == 1:
                    neighbors = self.grid[i + 1][j] + self.grid[i - 1][j] + self.grid[i][j + 1] + self.grid[i][j - 1] + self.grid[i - 1][j - 1] + self.grid[i + 1][j + 1] + self.grid[i + 1][j - 1] + self.grid[i - 1][j + 1]

                    if neighbors < 2:
                        self.grid[i][j] = 0

                    elif neighbors > 3:
                        self.grid[i][j] = 0

                    else:
                        self.grid[i][j] = 1


board = Board()
board.randomize()

while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()

    board.rules()
    board.draw()
    pygame.display.update()
    fpsClock.tick(FPS)

【问题讨论】:

  • 最大的错误 - 当您仍然需要原始值来计算其他单元格时,您更改了 grid 中单元格中的值。您不能更改 grid 中的值。您必须在新的new_grid 中添加新值并在最后替换网格。
  • 谢谢@furas,这正是我想要的……但你能澄清一下为什么我需要第二个网格吗?因为我无法向自己解释,为什么我的示例以某种方式起作用。
  • 您在计算期间更改 grid 中的值,因此当您为第二个(第三个等)单元格计算 neighbors 时,单元格中的值与开始时的值不同,您计算 @ 987654327@ 使用错误的值。您必须使用原始值计算所有 neighbors - 不被先前的计算修改。
  • 我整天都在想我的规则有问题。终于明白了。谢谢大佬!

标签: python arrays python-3.x pygame conways-game-of-life


【解决方案1】:

您的错误 - 当您仍然需要原始值来计算其他单元格时,您更改了 grid 中单元格中的值。您无法更改原始 grid 中的值。您必须在新的new_grid 中添加新值并在最后替换网格。

import pygame
import sys
import random

# --- constanst ---

FPS = 10
WINDOWSIZE = 500
CELLSIZE = 5

assert WINDOWSIZE % CELLSIZE == 0, "win size must be a multiple of cell"

# --- classes ---

class Board():

    def __init__(self):
        pygame.init()
        self.screen = pygame.display.set_mode((WINDOWSIZE, WINDOWSIZE))
        pygame.display.set_caption('Game of Life')

        self.grid = [[0] * (WINDOWSIZE // CELLSIZE) for i in range(WINDOWSIZE // CELLSIZE)]


    def draw(self):

        for i, x in enumerate(range(0, WINDOWSIZE, CELLSIZE)):
            for j, y in enumerate(range(0, WINDOWSIZE, CELLSIZE)):

                if self.grid[i][j] == 0:
                    color = (20, 120, 20)
                else:
                    color = (255, 255, 255)

                pygame.draw.rect(self.screen, color, pygame.Rect((x, y), (CELLSIZE, CELLSIZE)))


    def randomize(self):

        for i in range(CELLSIZE, (WINDOWSIZE // CELLSIZE) - CELLSIZE):
            for j in range(CELLSIZE, (WINDOWSIZE // CELLSIZE) - CELLSIZE):
                if random.randint(0, 100) < 15:
                    self.grid[i][j] = 1


    def rules(self):
        # create new grid
        new_grid = [[0] * (WINDOWSIZE // CELLSIZE) for i in range(WINDOWSIZE // CELLSIZE)]

        # put results in new grid
        for i in range(CELLSIZE, (WINDOWSIZE // CELLSIZE) - CELLSIZE):
            for j in range(CELLSIZE, (WINDOWSIZE // CELLSIZE) - CELLSIZE):

                neighbors = self.grid[i + 1][j] + self.grid[i - 1][j] + self.grid[i][j + 1] + self.grid[i][j - 1] + self.grid[i - 1][j - 1] + self.grid[i + 1][j + 1] + self.grid[i + 1][j - 1] + self.grid[i - 1][j + 1]

                if self.grid[i][j] == 0:
                    if neighbors == 3:
                        new_grid[i][j] = 1
                    else:
                        new_grid[i][j] = 0
                elif self.grid[i][j] == 1:
                    if neighbors < 2:
                        new_grid[i][j] = 0
                    elif neighbors > 3:
                        new_grid[i][j] = 0
                    else:
                        new_grid[i][j] = 1

        # replace grid
        self.grid = new_grid


    def mainloop(self):
        fps_clock = pygame.time.Clock()

        while True:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        pygame.quit()
                        sys.exit()

            self.rules()
            self.draw()
            pygame.display.update()

            fps_clock.tick(FPS)        

# --- main ---

board = Board()
board.randomize()
board.mainloop()

【讨论】:

    【解决方案2】:

    在迁移到下一代之前不要修改单元格!以下是您需要遵循的简单算法。详细实现和视频演示可以找here.

    1. 创建一个代表您的单元格的网格。
    2. 细胞可以是死的也可以是活的。所以有两个 CSS 类,一个是活着的,一个是死的。
    3. 找出单元格的邻居。
    4. 应用上述规则并确定细胞对于下一代是存活还是死亡。
    5. 存储需要移至下一代的单元格。
    6. 储存在下一代中无法存活或死亡的细胞。
    7. 迭代移动到下一代的细胞列表,并通过向它们添加活动的 css 类将它们标记为活动
    8. 遍历将在下一代中死亡的单元格列表,并通过向它们添加死亡 css 类将它们标记为死亡。
    9. 在一小段时间间隔后重新运行 3-8 的步骤。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-21
      • 1970-01-01
      • 1970-01-01
      • 2010-09-07
      • 2017-03-15
      • 1970-01-01
      相关资源
      最近更新 更多