Conways Game of Life

Tags: short, artistic, simulation

Conway’s Game of Life is a cellular automata simulation that follows simple rules to create interesting patterns. It was invented by mathematician John Conway in 1970 and popularized by Martin Gardner’s “Mathematical Games” column in Scientific American. Today, it’s a favorite among programmers and computer scientists, though it’s more an interesting visualization than a true “game.” The two-dimensional board has a grid of “cells,” each of which follows three simple rules:

Living cells with two or three neighbors stay alive in the next step of the simulation. Dead cells with exactly three neighbors become alive in the next step of the simulation. Any other cell dies or stays dead in the next step of the simulation.

The living or dead state of the cells in the next step of the simulation depends entirely on their current state. The cells don’t “remember” any older states. There is a large body of research regarding the patterns that these simple rules produce. Tragically, Professor Conway passed away of complications from COVID-19 in April 2020. More information about Conway’s Game of Life can be found at https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life, and more information about Martin Gardner at https://en.wikipedia.org/wiki/Martin_Gardner.

conways_game_of_life.py
 1"""Conway's Game of Life, by Al Sweigart al@inventwithpython.com
 2The classic cellular automata simulation. Press Ctrl-C to stop.
 3More info at: https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life
 4This code is available at https://nostarch.com/big-book-small-python-programming
 5Tags: short, artistic, simulation"""
 6
 7import copy, random, sys, time
 8
 9# Set up the constants:
10WIDTH = 79   # The width of the cell grid.
11HEIGHT = 20  # The height of the cell grid.
12
13# (!) Try changing ALIVE to '#' or another character:
14ALIVE = 'O'  # The character representing a living cell.
15# (!) Try changing DEAD to '.' or another character:
16DEAD = ' '   # The character representing a dead cell.
17
18# (!) Try changing ALIVE to '|' and DEAD to '-'.
19
20# The cells and nextCells are dictionaries for the state of the game.
21# Their keys are (x, y) tuples and their values are one of the ALIVE
22# or DEAD values.
23nextCells = {}
24# Put random dead and alive cells into nextCells:
25for x in range(WIDTH):  # Loop over every possible column.
26 for y in range(HEIGHT):  # Loop over every possible row.
27     # 50/50 chance for starting cells being alive or dead.
28     if random.randint(0, 1) == 0:
29         nextCells[(x, y)] = ALIVE  # Add a living cell.
30     else:
31         nextCells[(x, y)] = DEAD  # Add a dead cell.
32
33while True:  # Main program loop.
34 # Each iteration of this loop is a step of the simulation.
35
36 print('\n' * 50)  # Separate each step with newlines.
37 cells = copy.deepcopy(nextCells)
38
39 # Print cells on the screen:
40 for y in range(HEIGHT):
41     for x in range(WIDTH):
42         print(cells[(x, y)], end='')  # Print the # or space.
43     print()  # Print a newline at the end of the row.
44 print('Press Ctrl-C to quit.')
45
46 # Calculate the next step's cells based on current step's cells:
47 for x in range(WIDTH):
48     for y in range(HEIGHT):
49         # Get the neighboring coordinates of (x, y), even if they
50         # wrap around the edge:
51         left  = (x - 1) % WIDTH
52         right = (x + 1) % WIDTH
53         above = (y - 1) % HEIGHT
54         below = (y + 1) % HEIGHT
55
56         # Count the number of living neighbors:
57         numNeighbors = 0
58         if cells[(left, above)] == ALIVE:
59             numNeighbors += 1  # Top-left neighbor is alive.
60         if cells[(x, above)] == ALIVE:
61             numNeighbors += 1  # Top neighbor is alive.
62         if cells[(right, above)] == ALIVE:
63             numNeighbors += 1  # Top-right neighbor is alive.
64         if cells[(left, y)] == ALIVE:
65             numNeighbors += 1  # Left neighbor is alive.
66         if cells[(right, y)] == ALIVE:
67             numNeighbors += 1  # Right neighbor is alive.
68         if cells[(left, below)] == ALIVE:
69             numNeighbors += 1  # Bottom-left neighbor is alive.
70         if cells[(x, below)] == ALIVE:
71             numNeighbors += 1  # Bottom neighbor is alive.
72         if cells[(right, below)] == ALIVE:
73             numNeighbors += 1  # Bottom-right neighbor is alive.
74
75         # Set cell based on Conway's Game of Life rules:
76         if cells[(x, y)] == ALIVE and (numNeighbors == 2
77             or numNeighbors == 3):
78                 # Living cells with 2 or 3 neighbors stay alive:
79                 nextCells[(x, y)] = ALIVE
80         elif cells[(x, y)] == DEAD and numNeighbors == 3:
81             # Dead cells with 3 neighbors become alive:
82             nextCells[(x, y)] = ALIVE
83         else:
84             # Everything else dies or stays dead:
85             nextCells[(x, y)] = DEAD
86
87 try:
88     time.sleep(.1)  # Add a 1 second pause to reduce flickering.
89 except KeyboardInterrupt:
90     print("Conway's Game of Life")
91     print('By Al Sweigart al@inventwithpython.com')
92     sys.exit()  # When Ctrl-C is pressed, end the program.

https://inventwithpython.com/bigbookpython/project13.html