A small C++17 implementation of Brian's Brain, a three-state cellular automaton. The simulation opens an X11 window, renders the grid in real time, and supports deterministic runs for testing and experimentation.

Brian’s Brain
A small C++17 implementation of Brian’s Brain, a three-state cellular
automaton. The simulation opens an X11 window, renders the grid in real time,
and supports deterministic runs for testing and experimentation.
Screenshots
These frames were captured from the running X11 application. Each uses a
different grid shape, frame rate, and deterministic seed.
Balanced600 x 600 · 12 FPS · seed 1234![]() |
Compact300 x 300 · 8 FPS · seed 42![]() |
Wide800 x 450 · 18 FPS · seed 2024![]() |
Tall450 x 700 · 14 FPS · seed 7![]() |
Recreate the examples with:
./build/brains-brain --width 600 --height 600 --fps 12 --seed 1234
./build/brains-brain --width 300 --height 300 --fps 8 --seed 42
./build/brains-brain --width 800 --height 450 --fps 18 --seed 2024
./build/brains-brain --width 450 --height 700 --fps 14 --seed 7
Requirements
- Linux with an X11 display
- A C++17 compiler
- GNU Make
- X11 development files
On Debian or Ubuntu:
sudo apt install build-essential libx11-dev
For optional screenshots or other X11 runs on a headless machine, install Xvfb:
sudo apt install xvfb
Quick start
Build and launch the default simulation:
make
./build/brains-brain
The default run uses a 300 x 300 grid, 100 generations, and 12 frames per
second. The initial state is randomized unless a seed is provided.
Controls
| Key | Action |
|---|---|
Space |
Pause or resume the simulation |
N |
Advance one generation while paused |
R |
Restart with a new random seed |
+ / - |
Increase or decrease the frame rate |
Q or Escape |
Quit |
Command-line options
Run ./build/brains-brain --help for the built-in usage message.
| Option | Default | Description |
|---|---|---|
--width N |
300 |
Grid width, from 1 to 2000 |
--height N |
300 |
Grid height, from 1 to 2000 |
--steps N |
100 |
Generations to simulate, from 1 to 1,000,000 |
--fps N |
12 |
Frame rate, from 1 to 240 |
--seed N |
Random | Unsigned seed for a reproducible initial grid |
--no-wait |
Off | Exit after the last generation instead of waiting for the window to close |
--headless |
Off | Run the simulation without opening an X11 window |
Example reproducible run:
./build/brains-brain \
--width 600 --height 600 --fps 20 --steps 500 --seed 1234 --no-wait
The --no-wait option still opens a window; it only changes what happens after
the final generation. For fully headless runs, use --headless:
./build/brains-brain --headless --steps 500 --seed 1234
Rules
Each cell has one of three states: passive, active, or semi-active.
- An active cell becomes semi-active on the next generation.
- A semi-active cell becomes passive on the next generation.
- A passive cell becomes active if and only if it has exactly two active neighbors.
The grid has finite boundaries. Neighbors outside the grid are treated as
passive, so edge and corner cells have fewer possible neighbors.
Passive cells are rendered black, active cells green, and semi-active cells
amber in the X11 view.
Development
make test # Build and run the unit tests
make lint # Syntax-check all application and test sources
make # Build the normal application
make debug # Build with debug symbols and no optimization
make sanitize # Run sanitizer checks, including a headless smoke test
make clean # Remove build artifacts
The normal, debug, and sanitizer binaries are written to build/,
build/debug/, and build/sanitize/ respectively. The GitHub Actions workflow
runs the test, lint, build, and sanitizer targets on every push and pull request.
Project layout
- brain.cpp and brain.h implement the automaton and grid operations.
- graphics_x11.cpp provides the X11 window and keyboard input.
- main.cpp parses options, runs the simulation, and renders frames.
- tests/test_brain.cpp covers state transitions and boundary behavior.
- .github/workflows/ci.yml defines the CI checks.
- CONTRIBUTING.md describes the local validation workflow.




