Game of Life
Level: Advanced 60–90 minConcepts: StateAlgorithms
Solutions: C# | TypeScript | Python
Implement Conway’s Game of Life, a cellular automaton that simulates the evolution of a population of cells based on simple rules. The game is played on a grid of cells, where each cell can be either alive or dead.
Rules
The rules of the game are:
- Any live cell with fewer than two live neighbors dies (underpopulation)
- Any live cell with two or three live neighbors lives on to the next generation
- Any live cell with more than three live neighbors dies (overpopulation)
- Any dead cell with exactly three live neighbors becomes a live cell (reproduction)
Requirements
- Create a grid of cells that can be initialized with a specific pattern
- Implement the rules to calculate the next generation
- Handle edge cases (cells at the boundaries of the grid)
- Support different grid sizes
- Provide a way to visualize the current state of the grid
Hint
Start by implementing the core rules for a single cell, then expand to handle the entire grid. Consider using a two-dimensional array or a more sophisticated data structure to represent the grid. Think about how to handle the edges of the grid - you could either wrap around (toroidal) or consider cells outside the grid as dead.
Bonus
- Implement different initial patterns (glider, blinker, etc.)
- Add the ability to save and load patterns
- Implement a graphical interface to visualize the evolution
- Add the ability to pause and resume the simulation
- Implement different rule variations (e.g., High Life, Day & Night)
Reference Walkthrough
Full C#, TypeScript, and Python implementations live at tddbuddy-reference-katas/game-of-life. Eighteen scenarios across empty/trivial grids, individual rule verification, still lifes (Block), oscillators (Blinker), spaceships (Glider), and grid queries — shared across all three languages — with an immutable Grid entity backed by a set of Cell value-type coordinates, and a GridBuilder for readable test setup.
- C# (.NET 8, xUnit, FluentAssertions) — walkthrough
- TypeScript (Node 20, Vitest, strict types) — walkthrough
- Python (3.11, pytest, frozen dataclass, frozenset) — walkthrough
This kata ships in Agent Full-Bake (F3) mode: one commit per language with the full domain design landing together. The walkthroughs read as design rationale — why the grid is a Set<Cell> instead of a 2D array (unbounded infinite plane, no boundary questions), why Grid is immutable (simultaneous rule application), why tick() uses a neighbor-count dictionary (work proportional to population, not plane). No collaborators are needed — GoL is pure transformation with no clock, no notifier, no capacity. The reference scopes to the eighteen core scenarios; the bonus items (graphical visualization, rule variations) are deliberately out of scope. See the repo’s Gears section for when middle gear is the right call.