# Principled Programming / Tim Teitelbaum / Chapter 13. Cellular Automata. # 13.1 Top-level Code Structure # 13.2 Data Representation # 13.3 Display # 13.4 Update # 13.5 Game of Life class Sim: """A cellular automaton simulation. The Game of Life. # Methods. main(cls) -> None # See also. Chapter 13 of Principled Programming """ M: int = 5 """M is the height of the Universe.""" N: int = 20 """N is the width of the Universe.""" old: list[list[bool]] = [] """old is the present state of the Universe.""" next: list[list[bool]] = [] """next is the upcoming generation of the Universe, in preparation.""" LAST_GEN: int = 40 """LAST_GEN is last generation to be simulated.""" generation: int = 0 """generation is the number of the present generation.""" @classmethod def main(cls) -> None: """Simulate a cellular automaton.""" # Create the initial Universe and display it. Sim.initialize() Sim.display() # Simulate and display LAST_GEN additional generations. for Sim.generation in range(1, Sim.LAST_GEN+1): Sim.next_generation() Sim.display() @classmethod def initialize(cls) -> None: """Create the initial Universe.""" # Initialize old and new Universes as M-by-N arrays of False. Sim.old = [[False for _ in range(0, Sim.N)] for _ in range(0, Sim.M)] Sim.next = [[False for _ in range(0, Sim.N)] for _ in range(0, Sim.M)] # Glider Sim.old[0][1] = True Sim.old[1][2] = True Sim.old[2][0] = True Sim.old[2][1] = True Sim.old[2][2] = True @classmethod def display(cls) -> None: """Display Universe old[][] as an M-by-N grid.""" print( "Generation: ", Sim.generation ) for r in range(0, Sim.M): for c in range(0, Sim.N): if Sim.old[r][c]: print("X", end='') else: print("_", end='') print() @classmethod def next_generation(cls) -> None: """Update old Universe to be the next generation.""" # Determine each state of next[][] as F(old[][] states). for r in range(0, Sim.M): for c in range(0, Sim.N): # Let live_neighbors be # of alive cells around old[r][c]. live_neighbors = 0 for dr in range(-1, 2): for dc in range(-1, 2): if not((dr == 0) and (dc == 0)) and ( Sim.old[(r + dr ) % Sim.M][(c + dc) % Sim.N] ): live_neighbors += 1 #.Set next[r][c] based on old[r][c] and liveNeighbors. if Sim.old[r][c]: # Currently live. if live_neighbors==2 or live_neighbors==3: Sim.next[r][c] = True else: Sim.next[r][c] = False else: # Currently dead. if live_neighbors==3: Sim.next[r][c] = True else: Sim.next[r][c] = False # Swap old[][] and next[][] Universes. temp = Sim.old; Sim.old = Sim.next; Sim.next = temp # Chapter 13 Cellular Automata # 13.1 Top-level Code Structure # 13.2 Data Representation # 13.3 Display # 13.4 Update # 13.5 Game of Life Sim.main() # Invoke the main method of class Sim.