Game of Life Rules
The Game of Life is a cellular automaton on a 2D grid where each cell has state s ∈ {0,1}. Evolution depends only on the state of its 8 neighbors.
N(x,y) = Σ s(x+dx, y+dy)
where (dx,dy) ∈ {-1,0,1}² \ {(0,0)}
R1 - Underpopulation
If s(x,y)=1 and N(x,y) < 2, then s'(x,y)=0. A live cell with fewer than 2 neighbors dies.
R2 - Survival
If s(x,y)=1 and N(x,y) ∈ {2,3}, then s'(x,y)=1. A live cell with 2 or 3 neighbors survives.
R3 - Overpopulation
If s(x,y)=1 and N(x,y) > 3, then s'(x,y)=0. A live cell with more than 3 neighbors dies.
R4 - Reproduction
If s(x,y)=0 and N(x,y)=3, then s'(x,y)=1. A dead cell with exactly 3 neighbors becomes alive.
In B/S notation, Conway is expressed as B3/S23.
Mathematical concepts
Transition function
The global rule is a deterministic function T: {0,1}^(Z²) -> {0,1}^(Z²) that operates in parallel across the whole space.
s'(x,y) = T(s(x,y), N(x,y))
T(1, n) = 1 if n ∈ {2,3}
T(0, n) = 1 if n = 3
T(*, n) = 0 otherwise
Turing completeness
The Game of Life is Turing-complete: it can simulate any Turing machine. This was demonstrated with Glider Guns acting as logical gates.
Entropy and density
The optimal initial density is around 37%. Densities below 10% or above 60% tend to collapse quickly.
ρ(t) = |{(x,y) : s_t(x,y)=1}| / (W × H)
Pattern types
- Still life: static patterns that do not change.
- Oscillator: patterns with period
P >= 2 that return to their initial state.
- Spaceship: patterns that move across the grid.
Moore neighborhood
The 8 neighbors form the Moore neighborhood with radius 1. It is the standard neighborhood for the Game of Life, unlike the Von Neumann neighborhood with 4 neighbors.
Technical stack
Canvas API 2D
Rendering uses ImageData to write pixels directly into the buffer, avoiding thousands of drawRect calls per cell.
Typed Arrays
State is stored in Uint8Array with a current/next double buffer. Cells are indexed as:
i(x, y) = y × cols + x
requestAnimationFrame
The loop decouples updates and rendering. The simulation advances at the configured Gen/s while the canvas remains responsive.
Double buffering
All changes are computed into a secondary buffer before replacing the primary state. This guarantees each generation uses state t, not a partial mix of t and t+1.