ASCII Game of Life in Zig !

Tristan DuretTristan Duret
3 min read

After 7 years of code, 2 of which professionally, one might think I would have already done it, but no... I was today years old when I made my first game of life project!

I wanted to explore Zig and become better at it, so I decided to play a bit with it.

Why Zig ?

Well, I tried C, Rust, and Nim, but C was too hard for me to want to keep coding with it until it wasn't anymore. Rust seemed nice, but I'm not a fan of the Something<> syntax, and it didn't click for me. Nim was my favorite one, but resources were hard to find. When I first tried Zig (0.9.0), I fell in love with the idea of not having any hidden control flow. I could see everything and understand anything just by looking at it long enough. The compiler is easy to use, and the comptime feature is very nice and intuitive; it just clicked.

Ziglings and the Zig Discord

I already had the basics down in C and understood the stack and heap, so it was fairly easy to pick up. However, to stay motivated to continue, I needed quick wins. In order to get my quick wins I did the [Ziglings Exercices](https://codeberg.org/ziglings/exercises/). I struggled with one of the exercises and was introduced to the Ziglang Discord server. I submitted a ticket with the exercise and some code samples (after checking for duplicates), and within 2 minutes, 3 people were explaining to me how slices and arrays are implemented and used in Zig.

The Game Of Life !

All motivated, I decided to build a game of life in the terminal, and I'm really proud of the result! I put margins all around a frame that I was drawing in order to not deal with the edges in my computations.

I struggled for two days because the neighbor count was correct, the logic was correct, but somehow a three # high horizontal bar would turn into a 2x3 C.
The culprit? I did not initialize my next_state to false, so it was undefined the first time and then kept the last computation as a base point.

    //...
    // Not actual Golang but the syntax highlight is near
    var current_index: usize = undefined;
    var neigbhour_count: usize = undefined;
    var next_state: bool = undefined;

    while (true) {
        // Changes buf 2 based on buff 1 data
        for (start_row..start_row + frame.height) |row| {
            for (start_col..start_col + frame.width) |col| {
                current_index = row * w.col + col;

                // The neighbour counts the right number and the right neighbour
                neigbhour_count = 0;
                for ((current_index - 1)..(current_index + 2)) |i| {
                    if (buffer[i - w.col] == @intFromEnum(chars.FILLED)) neigbhour_count += 1;
                    if (buffer[i + w.col] == @intFromEnum(chars.FILLED)) neigbhour_count += 1;
                    if (current_index == i) continue;
                    if (buffer[i] == @intFromEnum(chars.FILLED)) neigbhour_count += 1;
                }

                // This is the culprit
                next_state = false; // from here

                // The logic is the good one :3
                if (neigbhour_count < 2 or neigbhour_count > 3) {
                    next_state = false;
                } else if (neigbhour_count == 2 and buffer[current_index] == @intFromEnum(chars.FILLED)) {
                    next_state = true;
                } else if (neigbhour_count == 3) {
                    next_state = true;
                }

                buffer2[current_index] = if (next_state) @intFromEnum(chars.FILLED) else @intFromEnum(chars.EMPTY);
                // to here
            }
        }

Conclusion

There really isn't a conclusion except that Zig is easier to pick up than C and Rust. While writing the article, I noticed I could just have the from here to here as a one-liner. That's the type of thing I usually only get to do in my Python CodinGame sessions :3

buffer2[current_index] = if (neigbhour_count == 2 and
    buffer[current_index] == @intFromEnum(chars.FILLED) or
    neigbhour_count == 3) @intFromEnum(chars.FILLED) else @intFromEnum(chars.EMPTY);
0
Subscribe to my newsletter

Read articles from Tristan Duret directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Tristan Duret
Tristan Duret

I like to code in my spare time. I'd like to get better with wasm currently ! I love seeing new languages and frameworks. I at least know how to hello world on all the low level stuff in my tech stack and how to make a simple user CRUD + Search with the web things. I like learning stuff, it makes me feel smart and likely useful for most cases.