DEV Community

Shahrouz Nikseresht
Shahrouz Nikseresht

Posted on

Day 69: Python Conway's Game of Life - Simulate One Step of Cellular Automata with Neighbor Scanning Magic

Welcome to Day 69 of the #80DaysOfChallenges journey! This intermediate challenge implements a single step simulation of Conway's Game of Life, the iconic cellular automaton where cells live or die based on neighbor rules, using nested loops for grid traversal and a new grid for state updates to avoid interference. It's a timeless algorithm from 1970 by John Conway, teaching matrix manipulation, neighbor counting, and simulation rules, foundational for game dev, AI patterns, or computational biology. If you're diving into grid-based algos or recreating life-like simulations, this "Python Game of Life" script demonstrates a function that's accurate, efficient for small grids, and easy to extend for multiple steps or visualizations.


💡 Key Takeaways from Day 69: Game of Life Step Function

This task features a function that creates a new grid, scans each cell's 8 neighbors, and applies Conway's rules for birth/survival/death. It's a classic double-grid simulation pattern: read from old, write to new. We'll detail: function with new grid init, nested loops for neighbor count and rules, and main with example grid print.

1. Function Design: New Grid and Dimensions

The game_of_life_step function takes a grid, returns next state:

def game_of_life_step(grid: list[list[int]]) -> list[list[int]]:
    """Return the next state of the grid after one simulation step."""
    rows = len(grid)
    cols = len(grid[0])

    next_grid = [[0] * cols for _ in range(rows)]   # new grid for next state
Enter fullscreen mode Exit fullscreen mode

Gets dimensions, creates identical 0-filled grid to avoid modifying original during scan.

2. Nested Loops: Neighbor Scan and Rules Application

Core double loop processes each cell:

    for r in range(rows):
        for c in range(cols):
            live_neighbors = 0

            # check all 8 neighboring cells
            for dr in (-1, 0, 1):
                for dc in (-1, 0, 1):
                    if dr == 0 and dc == 0:
                        continue                    # skip the cell itself

                    nr = r + dr
                    nc = c + dc

                    if 0 <= nr < rows and 0 <= nc < cols:
                        live_neighbors += grid[nr][nc]

            # apply Conway's rules
            if grid[r][c] == 1:
                if live_neighbors == 2 or live_neighbors == 3:
                    next_grid[r][c] = 1             # cell survives
                else:
                    next_grid[r][c] = 0             # cell dies
            else:
                if live_neighbors == 3:
                    next_grid[r][c] = 1             # cell becomes alive

    return next_grid
Enter fullscreen mode Exit fullscreen mode

Inner deltas (-1/0/1) check 8 neighbors, skip self, bound check before add. Rules: live with 2/3 neighbors survives, dead with 3 becomes live, else die. O(rows*cols) time.

3. Main Demo: Initial Grid and Next Print

Script defines grid, prints before/after:

grid = [
    [0, 1, 0],
    [0, 1, 0],
    [0, 1, 0],
]

print("Initial grid:")
for row in grid:
    print(row)

next_state = game_of_life_step(grid)

print("\nNext generation:")
for row in next_state:
    print(row)
Enter fullscreen mode Exit fullscreen mode

For blinker: flips to horizontal, then back. Simple print loop.


🎯 Summary and Reflections

This Game of Life step simulates cellular rules with double grid. It reinforced:

  • Neighbor deltas: Standard for grid 8-way scan.
  • Double grid: Prevents read-write conflicts.
  • Rule simplicity: 4 conditions cover all life/death.

Reflections: Add generations loop, toroidal wrap. Life patterns like glider fascinate.

Advanced Alternatives: Numpy for speed/large grids. Hash life for huge. Your Life pattern? Share!


🚀 Next Steps and Resources

Day 69 simulated life. In #80DaysOfChallenges? Multi-step? Post!

Top comments (0)