This project is a modern C++ implementation of Conway’s Game of Life, designed specifically as a sandbox for experimenting with multithreading strategies. It includes:
- A clean separation between simulation state and execution strategy
- A pluggable IStepStrategy interface for swapping threading models
- A terminal-based ncurses UI for interactive editing and visualization
- A standalone library (libgameoflife) + simple front-end executable
This project wasn’t just about implementing Game of Life — it was created to explore and compare different ways to parallelize a cellular automaton in C++.
It allows experimentation with:
- Single-thread stepping
- Row-split multithreading
- Thread-pool–based stepping (optional extension)
- Future approaches (tiling, SIMD, work stealing, GPU offload)
By injecting different stepping strategies into the simulation engine, you can test performance, structure, scalability, and complexity across multiple models.
- Fully interactive ncurses-based ASCII UI
- Arrow-key cursor navigation
fto toggle a cell alive- Spacebar to pause/resume simulation
- Real-time animation
- Clean OOP design with dependency injection
- Modular CMake build with an optional Makefile wrapper
- Cross-platform (Linux, WSL, macOS)
| Component | Purpose |
|---|---|
Grid |
Stores cell states + neighbor counting |
Rule |
Defines B/S (Birth/Survival) logic (default: Conway B3/S23) |
GameOfLife |
Owns state and delegates stepping to a strategy |
IStepStrategy |
Interface for all stepping implementations |
SingleThreadStep |
Classic single-thread update |
RowThreadedStep |
Multi-thread update by row partitioning |
To make threading interchangeable, GameOfLife accepts a strategy like:
GameOfLife game(rows, cols, std::move(rule), std::move(strategy));This allows runtime selection:
./gameoflife 40 80 single
./gameoflife 40 80 rowsproject/
├── include/
│ └── gameoflife/
│ ├── GameOfLife.hpp
│ ├── Grid.hpp
│ ├── Rule.hpp
│ ├── ConwayRule.hpp
│ ├── StepStrategy.hpp
│ ├── SingleThreadStep.hpp
│ └── RowThreadedStep.hpp (optional)
├── src/
│ ├── main.cpp
│ ├── GameOfLife.cpp
│ ├── Grid.cpp
│ ├── ConwayRule.cpp
│ ├── SingleThreadStep.cpp
│ └── RowThreadedStep.cpp
├── CMakeLists.txt
├── Makefile
└── README.md
mkdir build
cd build
cmake ..
cmake --build .Build artifacts:
libgameoflife.agameoflife(ncurses ASCII frontend)
make # configure + build
make run # build + run
make clean # remove build directory
make debug # Debug config
make release # Release configDefault grid size (15×30):
./gameoflifeCustom size:
./gameoflife <rows> <cols> [strategy]Example:
./gameoflife 40 80 rows| Key | Action |
|---|---|
| Arrow Keys | Move cursor |
| f | Set selected cell to ALIVE |
| Space | Pause / Resume |
| q | Quit |
Alive cells render as O
Dead cells render as .
The cursor highlights the active cell.
A baseline stepper that computes the entire board in a single loop. Useful for correctness testing and timing comparisons.
Splits the grid horizontally:
Thread 0 → rows [0..N)
Thread 1 → rows [N..2N)
...
Each thread:
- Reads from current (read-only)
- Writes to next in its assigned row range
- Joins before buffer swap
Zero shared writes → zero locks.
Add new approaches by implementing:
class MyCoolStepStrategy : public IStepStrategy {
public:
void step(Grid& current, Grid& next, const Rule& rule) override;
};And inject it at runtime.
Possible extensions:
- Thread-pool stepping
- Tiled (chunk-based) work distribution
- NUMA-aware threading
- SIMD-accelerated neighbor counting
- GPU compute shaders or OpenCL
- Benchmark harness with timing output
If you're exploring C++ concurrency, this project is an excellent playground.
MIT License (optional)
