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.
import numpy as np
import matplotlib.pyplot as plot
import time as t
im = plot.imshow(board, cmap='Greys', interpolation='none')
board = np.random.randint(2, size=(100, 100))
board = initializeBoard()
if 1 not in board:
print("All cells are dead! Life is over!")
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
for i in range(1, 10):
neighbours = calculateNeighbours(board)
board = neighbours[1:101, 1:101]
board = checkAlive()
for i in range(0, 100):
for j in range(0, 100):
board[np.array([i,j])] = 1
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).