John Conway's Game of Life


I just finished a recreation of the Game of Life for Arduboy.
You can randomly generate the grid and see what happens.
You can Edit the grid yourself and experiment.
You can control the Speed of the simulation.
You can change the rules for when a cell gets “born” and when it gets to “survive”.

In the game screen press A to freeze the simulation and A again to simulate frame by frame then press B to simulate at normal speed.

In the game screen press B to open the menu.

In the menu press UP / DOWN to scroll through the options and A or LEFT / RIGHT to select an option


It was the “blink” with cells dead or alive, right?
Oh, yes. Somehow I was going through possible things to write as program, but then I skipped this thing.
Well, you get this one.

Hmmm…is your laptop a DELL?
Perhaps XPS or Inspiron?

Man I like the screen you made up.
I bet that is a 4 * 4 cell, so you would have a 16 * 32 grid.
Same as my SNAKE game…

1 Like

What licence is this published under?

I could easily get you ~400 bytes of RAM back,
but I’d want to be sure that it’s open source first so I know I’m allowed to do that.


Congratulations on becoming another Victor Frankenstein :grin:


People are free to do whatever they want with it :wink:

1 Like

I have a Dell XPS. good eye

1 Like

I still think it would be best to have a proper licence.

If you want a ‘do what you want’ sort of licence, then the Unlicence is a good option.
It voids all warranty and liability (as is standard for a licence), permits people to use the code privately or commercially and allows the code to be modified and distributed without constraint.

1 Like

I have changed the link to a repository with an unlicense.


I haven’t checked to see whether I’ve accidentally broken anything yet, but (assuming it works) a simple template class an 90 extra bytes of progmem ends up saving you 430 bytes of RAM.

I’m pretty certain that more could be saved by changing the cursor logic so that the cursor acts as a tile index and the drawing logic multiplies by 4.
That would simplify the cursor logic.

Also this sort of thing:

(((cursorX + 4) % 128) + 128) % 128

Is slightly redundant because using % 128 essentially undoes the + 128.

For example, say cursorX starts as 128:

(((128 + 4) % 128) + 128) % 128
((132 % 128) + 128) % 128
(4 + 128) % 128
132 % 128
1 Like

I use that weird calculation because of negative numbers.
The way i have come to know modulu -8 % 28 = 20.
However in C++ -8 % 28 = -8.
(((cursorX + 4) % 128) + 128) % 128 this handles cursrorX even when it leaves the screen to the left side and wraps around to the right.

I also tested the changes you made and it seems that the iteration to the next frame doesent work properly and when i go to edit one cell it turns on more than one cell.
Moving the courser also rarely moved every cell half a cell in the y direction but i do not know exactly how to recreate that bug.

Thanks for trying to save me some bytes though as I think thats one of the areas where I still have to learn alot.

I was able to save ~100 bytes by changing most of the menu to a bitmap and removing tinyfont. I have updated the code with the full functionality.

Couldn’t you use the absolute ( abs() ) function?

I dont really understand where i can use abs().

Sorry … I misread your example. You probably cannot use abs().

1 Like

Because he have to warp around, so using abs() will BREAK things.

XPS :yum:. Year… 2015?
I don’t like the newest XPS they put up on their lineup. Too curvy and stuff.
I am probably going to get a Precision sometime later and use it for like…20 years.

For one second I was looking at your photo and the other second I looked ay my own keyboard (which was a 2012 XPS L321X (left broken by my dad and fixed my me), and they looked ALMOST IDENTICAL.)

Laptop keyboards are similar to SOME DEGREE, but still are possible.

But I also know that my 2013 Inspiron 5323(the broken one left by my mom and I fixed) look the same, so I wasn’t sure.
I might follow what you are talking about here, since it sounds fun.

The cursor isn’t a using datatype that handles negative numbers.
You currently have it set as byte (a.k.a. uint8_t), which is an unsigned datatype.
So actually it wouldn’t be -8 % 28, it would be 248 % 28 which is 24.

Some languages take the sign of the dividend, some take the sign of the divisor.
C++ takes the sign of the dividend, which is the more common approach.
The reason it’s more common is because it allows (((a / b) * b) + (a % b)) == a.

Presumably you’re used to one of the languages that do it the other way, like Python or Ruby.

I’ll check later.
There’s only one place where I touched the cursor code though,
which was toggling a cell on/off.
I haven’t touched it anywhere else, so I don’t know how my changes could have caused the other bugs.
Are you sure they aren’t present in the original?

The courser coordinates originally were integers in my code so i had to handle negative numbers untill i noticed that a byte would be enough. So i dont really need that expression anymore.

As for the bugs i have tested both and they behave very different.

I have placed only the diagonal line in the editor all other cells have been activated by themselves

I just got time to have another look at it and I found the problem.
I forgot to mask off the lower bit in getBit so it was looking at too many bits.

I’ve now nuked my fork, reforked and reapplied the changes.

448 bytes of ram saved through using a custom bit array class instead of an array of bool.

On top of that I made a bunch of other edits to reduce memory.

I’m not sure if you’ll like all of the changes, so I’ve made two branches, one with all the changes and one that only includes the less disruptive changes.

All changes:

Less disruptive changes:

With all the changes counted, the changes save 346 bytes of progmem and 452 bytes of RAM.
(I could probably manage more space savings if I could do some even more radical things like altering how the cursor works.)

1 Like