2016-11-12 5 views
1

ниже - мой код игры жизни Конвей. В настоящее время я борюсь с неправильной функциональностью - ячейки все еще воспроизводятся вместо исчезновения или точки сходимости. Я думаю, что что-то пошло не так в функции правил (я думаю, что определенные правила в порядке?), Но я не могу понять это. Если вы поймете, что пошло не так, я был бы признателен за вашу помощь. БлагодаряИгра жизни Конвей - правила

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) 
+0

самая большая ошибка - вы изменяете значения в ячейках в 'grid', когда вам все еще нужны оригинические значения для вычисления других ячеек. Вы не можете изменять значения в 'grid'. Вы должны поместить новые значения в новый 'new_grid' и заменить решетки в конце. – furas

+0

Спасибо @furas, это то, что я хочу .. но могли бы вы уточнить, почему именно мне нужна вторая сетка? потому что я не мог объяснить себе, почему мой пример работает в некотором роде. – radicz

+0

вы меняете значения в 'grid' во время вычислений, поэтому, когда вы вычисляете« соседи »для второй (третьей и т. Д.) Ячейки, тогда у вас есть разные значения в ячейках, чем у вас в начале, и вы вычисляете« соседи »с использованием неправильных значений. Вы должны рассчитать все «соседи» с использованием оригиналистических значений, не модифицированных предыдущими вычислениями. – furas

ответ

0

Ваша ошибка - изменить значения в ячейках в grid, когда вам все еще нужно ORYGINAŁ значения для расчета других клеток. Вы не можете изменять значения в oryginal 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() 
0

Не модифицируйте ячейки, пока не перейдете к следующему поколению! Ниже приведен простой алгоритм. Вы можете найти подробную версию и видео-демонстрацию here.

  1. Создайте сетку, которая будет представлять ваши ячейки.
  2. Ячейка может быть мертвой или живой. Итак, у меня есть два класса css, один для живых и один для мертвых.
  3. Рисунок из соседей ячейки.
  4. Применить выше правила и выяснить, будет ли ячейка живым или мертвым для следующего поколения.
  5. Храните ячейки, которые необходимо перенести в следующее поколение.
  6. Храните ячейки, которые не выживут или не умрут в следующем поколении.
  7. Перейдите по списку ячеек, переходящих к следующему поколению, и пометите их как живые, добавив к ним живой класс css.
  8. Перейдите по списку ячеек, которые умрут в следующем поколении и отметят их мертвыми, добавив мертвый css класс к ним.
  9. Повторите шаги от 3-8 снова через небольшой промежуток времени.