首页 > 解决方案 > 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 语句有效(很难理解程序的行为很奇怪)。

标签: pythonpygame

解决方案


规则的执行是正确的,但在康威的生命游戏中,你必须每回合创建一个新的空网格。新网格中的字段必须根据当前网格中的字段和演化规则来确定。

在 中创建一个新的空网格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_squaresgrid

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

推荐阅读