Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Conway's Game Of Life using Python?
Conway's Game of Life is a cellular automaton created by British mathematician John Conway in 1970. It simulates the evolution of a colony of biological organisms on a two-dimensional grid consisting of "living" and "dead" cells.
Rules of Conway's Game of Life
The game follows four simple rules that determine whether a cell lives or dies in the next generation ?
Overpopulation: A living cell dies if it has more than three living neighbors
Survival: A living cell survives if it has two or three living neighbors
Underpopulation: A living cell dies if it has fewer than two living neighbors
Reproduction: A dead cell becomes alive if it has exactly three living neighbors
Implementation Steps
The implementation follows these key steps ?
- Initialize an empty universe (grid)
- Fill the universe with a random seed pattern
- Calculate each cell's survival based on neighbor count
- Apply rules simultaneously to all cells
- Repeat for desired number of generations
Installation
Install the required libraries using pip ?
pip install numpy matplotlib
Complete Implementation
Here's a complete implementation of Conway's Game of Life with visualization ?
import numpy as np
import matplotlib.pyplot as plt
import argparse
import time
class Board(object):
def __init__(self, size, seed='Random'):
if seed == 'Random':
self.state = np.random.randint(2, size=size)
self.engine = Engine(self)
self.iteration = 0
def animate(self):
i = self.iteration
im = None
plt.title("Conway's Game of Life")
while True:
if i == 0:
plt.ion()
im = plt.imshow(self.state, vmin=0, vmax=2, cmap=plt.cm.gray)
else:
im.set_data(self.state)
i += 1
self.engine.applyRules()
print('Life Cycle: {} Birth: {} Survive: {}'.format(
i, self.engine.nBirth, self.engine.nSurvive))
plt.pause(0.01)
yield self
class Engine(object):
def __init__(self, board):
self.state = board.state
def countNeighbors(self):
state = self.state
n = (state[0:-2,0:-2] + state[0:-2,1:-1] + state[0:-2,2:] +
state[1:-1,0:-2] + state[1:-1,2:] + state[2:,0:-2] +
state[2:,1:-1] + state[2:,2:])
return n
def applyRules(self):
n = self.countNeighbors()
state = self.state
birth = (n == 3) & (state[1:-1,1:-1] == 0)
survive = ((n == 2) | (n == 3)) & (state[1:-1,1:-1] == 1)
state[...] = 0
state[1:-1,1:-1][birth | survive] = 1
nBirth = np.sum(birth)
self.nBirth = nBirth
nSurvive = np.sum(survive)
self.nSurvive = nSurvive
return state
def main():
ap = argparse.ArgumentParser(add_help=False)
ap.add_argument('-h', '--height', help='Board Height', default=256)
ap.add_argument('-w', '--width', help='Board Width', default=256)
args = vars(ap.parse_args())
bHeight = int(args['height'])
bWidth = int(args['width'])
board = Board((bHeight, bWidth))
for _ in board.animate():
pass
if __name__ == '__main__':
main()
Simple Example
Here's a simpler version to understand the core logic ?
import numpy as np
def count_neighbors(grid):
"""Count living neighbors for each cell"""
neighbors = np.zeros_like(grid)
rows, cols = grid.shape
for i in range(rows):
for j in range(cols):
for di in [-1, 0, 1]:
for dj in [-1, 0, 1]:
if di == 0 and dj == 0:
continue
ni, nj = (i + di) % rows, (j + dj) % cols
neighbors[i, j] += grid[ni, nj]
return neighbors
def update_grid(grid):
"""Apply Conway's rules"""
neighbors = count_neighbors(grid)
new_grid = np.zeros_like(grid)
# Apply the four rules
for i in range(grid.shape[0]):
for j in range(grid.shape[1]):
if grid[i, j] == 1: # Living cell
if neighbors[i, j] in [2, 3]:
new_grid[i, j] = 1 # Survives
else: # Dead cell
if neighbors[i, j] == 3:
new_grid[i, j] = 1 # Born
return new_grid
# Example: Blinker pattern
grid = np.array([[0, 1, 0],
[0, 1, 0],
[0, 1, 0]])
print("Initial state:")
print(grid)
for generation in range(3):
grid = update_grid(grid)
print(f"\nGeneration {generation + 1}:")
print(grid)
Initial state: [[0 1 0] [0 1 0] [0 1 0]] Generation 1: [[0 0 0] [1 1 1] [0 0 0]] Generation 2: [[0 1 0] [0 1 0] [0 1 0]] Generation 3: [[0 0 0] [1 1 1] [0 0 0]]
Output
When running the complete implementation, you'll see console output showing the evolution ?
Life Cycle: 1 Birth: 7166 Survive: 10621 Life Cycle: 2 Birth: 7930 Survive: 8409 Life Cycle: 3 Birth: 7574 Survive: 8756 Life Cycle: 4 Birth: 7114 Survive: 8406 Life Cycle: 5 Birth: 7005 Survive: 8126 ...
The graphical display will show an animated grid where black pixels represent living cells and white pixels represent dead cells. The patterns will continuously evolve, creating fascinating shapes like gliders, oscillators, and still lifes.
Conclusion
Conway's Game of Life demonstrates how simple rules can create complex, emergent behavior. The Python implementation uses NumPy for efficient array operations and matplotlib for visualization, making it easy to observe the beautiful patterns that emerge from the cellular automaton.
