I have created The Game of Life in Python and Pygame. The Game of Life was first devised by the British mathematician John Conway in 1970. It is a zero-player game, meaning that its evolution is determined by its initial state. It is Turing complete and can simulate a universal constructor or any other Turing machine.
The Game of Life is a two-dimensional grid consisting of cells, each with one of two possible stages, alive or dead. Each cell interacts with its eight neighboring cells. Each step in time, the following happens:
- Any live cell with fewer than two live neighbours dies, as if by underpopulation
- Any live cell with two or three live neighbours lives on to the next generation
- Any live cell with more than three live neighbours dies, as if by overpopulation
- Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction
Link to my Python version of Conway's Game of Life.
Source code:
1 """Game of life | Sondre Nesje 2020"""
2
3 import sys
4 from random import randint
5
6 import pygame
7
8 #Screen settings
9 FPS = 10
10 SCREEN_WIDTH = SCREEN_HEIGHT = 600
11
12 #Cell settings
13 CELL_SIZE = 3
14 CELL_WIDTH = int(SCREEN_WIDTH / CELL_SIZE)
15 CELL_HEIGHT = int(SCREEN_HEIGHT / CELL_SIZE)
16
17 #Grid size
18 GRID_WIDTH = int(SCREEN_WIDTH / CELL_SIZE)
19 GRID_HEIGHT = int(SCREEN_HEIGHT / CELL_SIZE)
20
21 #Chance to make a cell at the beginning.
22 #In percent (%)
23 CELL_CHANCE = 20
24
25 #Color settings
26 BACKGROUND_COLOR = (128, 0, 128)
27 CELL_COLOR = (255, 255, 0)
28
29 def main():
30 """Main game function"""
31 global FPS_CLOCK, SCREEN, CELLS
32
33 pygame.init()
34 FPS_CLOCK = pygame.time.Clock()
35 SCREEN = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
36 pygame.display.set_caption("Game of life | Sondre Nesje 2020")
37
38 CELLS = create_cells()
39
40 run_game()
41
42 def run_game():
43 """The main loop for the game"""
44 global CELLS
45
46 while True:
47 check_events()
48
49 update_cells()
50
51 update_screen()
52
53 def check_events():
54 """Respond to events"""
55 for event in pygame.event.get():
56 if event.type == pygame.QUIT:
57 sys.exit()
58
59 def create_cells():
60 """Create a set of alive cells"""
61
62 cells = set()
63
64 for column in range(CELL_WIDTH):
65 for row in range(CELL_HEIGHT):
66
67 #The cell's x and y coordinates
68 cell_x = column * CELL_SIZE
69 cell_y = row * CELL_SIZE
70 cell = (cell_x, cell_y)
71
72 if CELL_CHANCE > randint(0, 100):
73 cells.add(cell)
74
75 return cells
76
77 def update_cells():
78 """Update the state of the cells"""
79 global CELLS
80
81 #One set for new cells for the next generation,
82 #and one for dead neighbor cells
83 new_cells = set()
84 dead_neighbor_cells = set()
85
86 for cells_alive in (True, False):
87
88 #Go through both living cells and dead neighbor cells
89 if cells_alive:
90 cells = CELLS.copy()
91 else:
92 cells = dead_neighbor_cells.copy()
93
94 for cell in cells:
95
96 #A set of neighbor cells
97 neighbor_cells = check_neighbor_cells(cell)
98
99 #A variable for live neighbor cells
100 live_cell_neighbors = 0
101
102 #Count neighboring cells
103 #and make a set of dead neighbor cells
104 for neighbor_cell in neighbor_cells:
105 if neighbor_cell in CELLS:
106 #Count how many neighboring cells are alive
107 live_cell_neighbors += 1
108 elif cells_alive:
109 #Create a set of dead neighbor cells,
110 #but only if the main cell is alive
111 dead_neighbor_cells.add(neighbor_cell)
112
113 #Cellular automaton rule
114 if cells_alive and 2 <= live_cell_neighbors <= 3:
115 #The cell survives
116 new_cells.add(cell)
117 elif not cells_alive and live_cell_neighbors == 3:
118 #The cell comes alive
119 new_cells.add(cell)
120 #else:
121 # The cell dies, or remains dead
122
123 CELLS = new_cells.copy()
124
125 def check_neighbor_cells(cell):
126 """Function to check for neighbor cells"""
127
128 #The cell's x and y coordinates
129 cell_x = cell[0]
130 cell_y = cell[1]
131
132 #Make a set of neighbor cells
133 neighbor_cells = {
134 tuple((cell_x - 1 * CELL_SIZE, cell_y - 1 * CELL_SIZE)),
135 tuple((cell_x + 0 * CELL_SIZE, cell_y - 1 * CELL_SIZE)),
136 tuple((cell_x + 1 * CELL_SIZE, cell_y - 1 * CELL_SIZE)),
137 tuple((cell_x - 1 * CELL_SIZE, cell_y + 0 * CELL_SIZE)),
138 tuple((cell_x + 1 * CELL_SIZE, cell_y + 0 * CELL_SIZE)),
139 tuple((cell_x - 1 * CELL_SIZE, cell_y + 1 * CELL_SIZE)),
140 tuple((cell_x + 0 * CELL_SIZE, cell_y + 1 * CELL_SIZE)),
141 tuple((cell_x + 1 * CELL_SIZE, cell_y + 1 * CELL_SIZE))}
142
143 return neighbor_cells
144
145 def update_screen():
146 """Update the screen, and flip to the new screen"""
147
148 SCREEN.fill(BACKGROUND_COLOR)
149
150 #Draw each alive cells
151 for cell in CELLS:
152 living_cell = pygame.Rect(cell[0], cell[1], CELL_SIZE, CELL_SIZE)
153 pygame.draw.rect(SCREEN, CELL_COLOR, living_cell)
154
155 #Make the most recently drawn screen visible.
156 pygame.display.flip()
157
158 FPS_CLOCK.tick(FPS)
159
160 if __name__ == "__main__":
161 #Run the game.
162 main()
163