shashtheash - 3 months ago 21

Python Question

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

`board`

`board`

`i`

`j`

`np.sum`

`nBlock[i-1:i+1,j-1:j+1]`

`nBlock[np.array([i,j])]`

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

plot.show()

plot.close()

def initializeBoard():

board = np.random.randint(2, size=(100, 100))

return board

board = initializeBoard()

printBoard(board)

def checkAlive():

if 1 not in board:

print("All cells are dead! Life is over!")

return 0

else:

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

printBoard(board)

play(board)

The array

`board`

`board`

Another odd thing I noticed is that if I remove the conditions in my

`for`

`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

`if...else`

Any and all help is appreciated :)

Answer

**Error**:

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.

**Solution**:

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.

**Also:**

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