shashtheash shashtheash - 1 year ago 69
Python Question

Game of LIfe: Modifying array values in numpy while iterating with conditions

I am a Physics student with very basic knowledge of Python and I have been trying to look for a simple solution to this problem, but I have only been running around in circles. I am writing my own rendition for a program called "The Game of Life" (WikiPage). The rules are straightforward:

The Game consists of so called cells that live on a 2 dimensional grid. These cells evolve in cycles. The initial pattern of dead and live cells is the first generation. The second generation evolves from applying some simple rules simultaneously to all cells. The rules are:

Cells die if they dont have enough company (less than 2 cells neighboring)

Cells die of overpopulation if there are 4 or more cells neighboring.

A dead cell is reborn if there are (exactly) 3 cells neighboring.

This is a part of an assignment, but I am not looking for a spoon-fed solution. We are required to use numpy and arrays.

My approach was to generate an array
with an initial feed of random 1's and 0's. Then, in a function, I create another array with one row and one column greater than
which will store the new values and then feed it back. I iterate (I know its not pythonic to iterate over an array, so I am open to suggestions and alternatives) over the elements
and make a sum (
) of the subarray
. If the sum is greater than 4 or less than 4, then the element
becomes zero (cell dies), otherwise, it is 1 (cell lives, or is reborn).

The problem is, this doesn't work. The code is as follows:

import numpy as np
import matplotlib.pyplot as plot
import time as t
%matplotlib inline

def printBoard(board):
im = plot.imshow(board, cmap='Greys', interpolation='none')

def initializeBoard():
board = np.random.randint(2, size=(100, 100))
return board

board = initializeBoard()

def checkAlive():
if 1 not in board:
print("All cells are dead! Life is over!")
return 0
return board

def calculateNeighbours(board):
nBlock = np.zeros((102, 102))
nBlock[1:101, 1:101] = board

for i in range(1, 100):
for j in range(1, 100):
checksum = np.sum(nBlock[i-1:i+2, j-1:j+2])

nBlock[:,0] = 0
nBlock[0,:] = 0

if checksum == 4:
nBlock[np.array([i,j])] = 1
elif checksum > 4 or checksum < 4:
nBlock[np.array([i,j])] = 0

return nBlock

def play(board):
for i in range(1, 10):
neighbours = calculateNeighbours(board)

board = neighbours[1:101, 1:101]

board = checkAlive()



The array
doesn't get modified. It returns the same

Another odd thing I noticed is that if I remove the conditions in my
loop, the array is successfully modified. For example,

for i in range(0, 100):
for j in range(0, 100):
board[np.array([i,j])] = 1

gives me a matrix which has all elements changed to 1. So there is something about the
conditions which is not allowing me to manipulate the data in my array.

Any and all help is appreciated :)

Answer Source


Your major error is in your interface logic for checkAlive. You have no parameters to the routine; when you do find a live cell, you return the symbiont board, which play immediately assigns to its parameter board.

The board in play is a local variable: changing this does not change the global board you initialized. In contrast, since checkAlive has no local variable, what it returns is the global variable board, which is never changed, anywhere in the program.


Since checkAlive doesn't alter the board, don't return it. Instead, return a simple boolean. play can check this and terminate the program, if needed.


Your cell health algorithm is wrong in a couple of respects. Walk through the logic and repair. Most notably, you use a value of 4 to let a cell live; this is massively incorrect. 2 neighbours leave the cell in its current state; 3 neighbours make the cell live; any other number kills it.

Your current logic includes the cell itself in the count. This does not differentiate between a live cell with 3 friends and a dead cell with 4. As a result, you're creating some cells incorrectly, and you're killing off viable cells (live cell with 2 friends).

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download