Conway's Game of Life rendered in the terminal, written entirely in C.
- C 92%
- Makefile 7%
- Nix 1%
|
|
||
|---|---|---|
| demo | ||
| docs | ||
| include | ||
| src | ||
| .gitattributes | ||
| .gitignore | ||
| flake.lock | ||
| flake.nix | ||
| LICENSE.md | ||
| Makefile | ||
| README.md | ||
crobgol
Conway's Game of Life terminal simulation (Unicode) in action
Table of Contents
- What is crobgol?
- Features
- Quick Start
- Requirements
- Make Options
- Command Line Options
- Optimizations
- License
What is crobgol?
The name was made like this: C Robkoo's Game Of Life
It is a high-performance terminal-based Conway's Game of Life simulator written entirely in C
Features
- Optimized grid implemenation that uses bit operations and a bitmap to store game data
- Adjustable grid size and frame rate
- Unicode and ASCII rendering modes
- benchmark built-in
- Custom CLI argument parser
Quick start
Build from source
git clone https://codeberg.org/Robkoo/crobgol
cd crobgol
# compile and run
make &∓& make run
# OR with parallel compilation
make -jj$(nproc) &∓& make run
If you have Nix with flakes available, you can also run the project directly:
$ nix run git+https://codeberg.org/Robkoo/crobgol.git
Use pre-built binaries
- head over to the releases and download the correct archive for your OS
Requirements
Linux
- C23 compiler (gcc)
- GNU make utility
Windows
- MSYS2 UCRT64 shell installed (install from msys2.org)
- the following dependencies installed:
pacman -S mingw-w64-ucrt-x86_64-gcc \
mingw-w64-ucrt-x86_64-make
Make options overview
Note
The default option is
release
| Option | Description |
|---|---|
| release | Optimized build with -O3 |
| debug | Build with debug symbols (-Og -g) |
| debug-sanitizer | Same as debug but with ASan |
| flags | Build with a ton of flags to warn about basically everything |
| clean | Entirely removes the build directory |
| run | Runs the binary without any arguments |
| package-linux | Package the project for Linux |
| package-windows | Package the project for Windows |
Command line options overview
Note
You can run the executable with
--helpfor an overview right in your terminal.
| Option | Takes value | What kind of value | Default | Description |
|---|---|---|---|---|
| -f, --fps | Yes | Number | 15 | How many FPS the simulation will have |
| -w, --width | Yes | Number | 80 | The width of the grid, in terminal cells |
| -h, --height | Yes | Number | 24 | The height of the grid, in terminal cells |
| -a, --ascii | No | ---- | false | Passing this flag will use ASCII characters for rendering rather than Unicode |
| --help | No | ---- | ---- | Prints a help message |
| --bench | Yes | Number | 1000 | Run benchmarks with the value as the iteration count. If you do not pass this flag, no benchmarks will be ran |
Examples
# Run at 30 FPS with larger grid
./bin/crobgol -f 30 -w 120 -h 40
# Run with ASCII characters
./bin/crobgol --ascii
# Run benchmark with 10000 iterations
./bin/crobgol --bench 10000
Optimizations
1) Bitmap instead of char*
- The initial implementation (
struct grid_t) used acharto store each cell's value, which takes up 8 bits per cell. - The new implementation (
struct grid_new_t) uses a bitmap, which stores each cell's value inside a single bit. - This is a whopping 8x memory reduction in the data structure. For example, for a
100x100grid, the initial implementation would've used 10,000 bytes of space, while the new one would use 1,256 bytes of memory.
2) Optimized function for computing next generation
- The initial implementation of the function
ComputeNextGeneration(...)contains function call overhead (calls functions to get cell's value, set cell's value and get neighbor count). The neighbor count function also calls some functions, further increasing the overhead. - The new implementation of the function
BitmapComputeNextGeneration(...)inlines these functions, so they're directly inside this function. It also uses efficient bit operations>>t;>,&, etc. - Based on my testing, the new implementation is about 3x-4x FASTER than the initial implementation. You can test it for yourself by running the executable with the option
--bench, whereer> is your desired amount of iterations to test the functions.er>
License
- GPLv3 (see License)