I'm trying to replicate Conway's Game of Life in Python. The rules of this simulation and a properly working version of it can be found here: https://bitstorm.org/gameoflife/
In my version, when I randomly assign cells to being alive at the start, it appears to behave properly, with the classic amourphous blobs of cells expanding over the screen.
However, when I replicate the "glider gun" arrangement (which can also be seen on the linked website), the cells are not updating properly: the structures decay slightly and then the movement of the cells remains stagnant.
This leads me to believe I have a logical error in my code - any help would be appreciated!
This is the section of my code within my Cell
class that updates
its survival based on its neighbors
(the eight cells surrounding it):
def update(self, neighbors):
numAliveNeighbors = 0
for neighbor in neighbors:
if neighbor.isAlive:
numAliveNeighbors+=1
if numAliveNeighbors <= 1 or numAliveNeighbors >=4:
self.isAlive = False
elif not self.isAlive and numAliveNeighbors is 3:
self.isAlive = True
This is the section of my code that finds all of the neighbors
of every cell
and calls the update
method on them:
for row in range(len(cells)):
for column in range(len(cells[row])):
neighbors = []
for tempRow in range (row-1, row + 2):
for tempColumn in range (column-1, column + 2):
if tempRow >= 0 and tempRow < len(cells):
if tempColumn >= 0 and tempColumn < len(cells[tempRow]):
if not(tempRow is row and tempColumn is column):
neighbors.append(cells[tempRow][tempColumn])
cells[row][column].update(neighbors)
You're doing in-place updates; that is, you update each cell individually. What you need to do is create a cloned grid and each time you update a cell on an iteration, update the cloned grid, then set the game board to the cloned grid. Otherwise, cells are going to be updated based on the current iteration, which doesn't make sense.
What you could do is something like this:
def isAlive(alive, neighbours):
return (alive and 2 <= neighbours <= 3) or (not alive and neighbours == 3)
def update(cells):
grid = [[0] * len(row) for row in cells]
for row in range(len(cells)):
for col in range(len(cells[row])):
neighbours = 0
for tr in range(row - 1, row + 2):
for tc in range(col - 1, col + 2):
if (tr != row or tr != col) and cells[tr][tc]:
neighbours += 1
grid[row][col] = isAlive(cells[row][col], neighbours)
return grid
Then you can call cells = update(cells)
in a loop.