radicz - 1 year ago 60
Python Question

# Conway's Game of Life - rules

below is my code for Conway's game of life. I am currently struggling with incorrect functionality - the cells are still reproducing instead of extinction or point of convergence. I think that something went wrong in rules function (I think, that particular rules are ok?), but I am unable to figure it out. If you have a clue what went wrong, I would appreciate your help. Thanks

``````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)
``````

Your mistake - you change values in cells in `grid` when you still need oryginal values to calculate other cells. You can't change values in oryginal `grid`. You have to put new values in new `new_grid` and replace grids at the end.

``````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()
pygame.display.set_caption('Game of Life')

self.screen = pygame.display.set_mode((WINDOWSIZE, WINDOWSIZE))

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()
``````