For learning purpose I've started creating my implementation of Conway's Game of Life. I've used numpy to store big array, contating dead and alive cells, then I've apllied Conway's rules, to create mechanics of cells life. To manage grid, and graphics I used pygame module. After many reviews, and rewriting code in many ways, I can't find out what's wrong with it, so I decided to ask you. For example I've tried to make a glider, (as code shows), but he dies after 3 loop cycles. I'd be appreciate for help and tips. Can you help me find out why the cells aren't reproducing? Thanks in advance. Code:
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()
I think you have a couple of subtle bugs in the way you implement Conway's rules. See my comments in the code for details:
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
With these edits the glider should glide :)