Python реализация игры жизни Конвея - PullRequest
0 голосов
/ 07 февраля 2019

В целях обучения я начал создавать свою реализацию игры жизни Конвея.Я использовал NumPy для хранения большого массива, связывая мертвые и живые клетки, затем применил правила Конвея, чтобы создать механику жизни клеток.Для управления сеткой и графикой я использовал модуль pygame.После многих обзоров и переписывания кода разными способами, я не могу понять, что с ним не так, поэтому я решил спросить вас.Например, я попытался сделать планер (как показывает код), но он умирает после 3 циклов цикла.Буду признателен за помощь и советы.Можете ли вы помочь мне выяснить, почему клетки не размножаются?Заранее спасибо.Код:

import pygame
import numpy as np

BLACK = (0, 0, 0)
GREEN = (0, 255, 0)
N = 195
WIDTH = 10
HEIGHT = 10

grid = np.zeros(shape=(N, N), dtype=np.int32)
glider = np.array([[0, 0, 1],
                       [1, 0, 1],
                       [0, 1, 1]])
grid[3:6, 3:6] = glider

pygame.init()

WINDOW_SIZE = [980, 980]
screen = pygame.display.set_mode(WINDOW_SIZE)

pygame.display.set_caption("GAME OF LIFE")

done = False

clock = pygame.time.Clock()

while not done:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True
    for row in range(N):
        for column in range(N):
            color = BLACK
            if grid[row][column] == 1:
                color = GREEN
            pygame.draw.rect(screen, color,
                             [WIDTH * column,
                              HEIGHT * row,
                              WIDTH,
                              HEIGHT])

    newGrid = grid.copy()
    for i in range(N):
        for j in range(N):
            total = grid[(i-1) % N:(i+1) % N, (j-1) % N:(j+1) % N].sum() - grid[i, j]
            if grid[i, j] == 1:
                if(total < 2) or (total > 3):
                    newGrid[i, j] = 0
                else:
                    if total == 3:
                        newGrid[i, j] = 1
    grid = newGrid

    clock.tick(60)
    pygame.display.flip()

pygame.quit()

Ответы [ 2 ]

0 голосов
/ 07 февраля 2019

Я думаю, у вас есть пара тонких ошибок в том, как вы реализуете правила Конвея .Смотрите мои комментарии в коде для деталей:

for i in range(N):
    for j in range(N):
        # I changed the range of the extent of the sum, note +2 rather than +1 !
        total = grid[(i-1) % N:(i+2) % N, (j-1) % N:(j+2) % N].sum() - grid[i, j]
        if grid[i, j] == 1:
            if(total < 2) or (total > 3):
                newGrid[i, j] = 0
            # allow for survival in case of total = 2 or 3 (this could be dropped though)
            else:
                newGrid[i, j] = 1
        # allow for reproduction if cell is empty
        else:
            if total == 3:
                newGrid[i, j] = 1

С этими изменениями планер должен скользить:)

0 голосов
/ 07 февраля 2019

Возможно, предложение else в цикле newGrid имеет слишком большой отступ?Поскольку на данный момент сетка идет только от 1 до 0, а не от 0 до 1. И это, вероятно, из-за разбиения массива: [(i-1)% n: (i + 1)% n].Существует 2 проблемы:

  1. это относится только к индексу до (i + 1)% n, поэтому оно не включает (i + 1)% n.
  2. он не переворачивается так, как вы ожидаете, поэтому, например, [9: 1] не переходит с 9 на 10 до 0 и останавливается до 1. Он просто возвращает пустой список.

Вот трюк

a.take(range(-1,2),mode='wrap', axis=0).take(range(-1,2),mode='wrap',axis=1)

из этого поста Оберните срез вокруг краев двумерного массива в numpy .Я изменил код ниже с помощью этого трюка.

import pygame
import numpy as np

BLACK = (0, 0, 0)
GREEN = (0, 255, 0)
N = 195
WIDTH = 10
HEIGHT = 10

grid = np.zeros(shape=(N, N), dtype=np.int32)
glider = np.array([[0, 0, 1],
                       [1, 0, 1],
                       [0, 1, 1]])
grid[3:6, 3:6] = glider

pygame.init()

WINDOW_SIZE = [980, 980]
screen = pygame.display.set_mode(WINDOW_SIZE)

pygame.display.set_caption("GAME OF LIFE")

done = False

clock = pygame.time.Clock()

while not done:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True
    for row in range(N):
        for column in range(N):
            color = BLACK
            if grid[row][column] == 1:
                color = GREEN
            pygame.draw.rect(screen, color,
                             [WIDTH * column,
                              HEIGHT * row,
                              WIDTH,
                              HEIGHT])

    newGrid = grid.copy()
    for i in range(N):
        for j in range(N):
            total = grid.take(range(i-1,i+2),mode='wrap', axis=0).take(range(j-1,j+2),mode='wrap',axis=1).sum() - grid[i, j]
            if grid[i, j] == 1:
                if(total < 2) or (total > 3):
                    newGrid[i, j] = 0
            else:
                if total == 3:
                    newGrid[i, j] = 1
    grid = newGrid

    clock.tick(60)
    pygame.display.flip()

pygame.quit()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...