The Beauty of Math - Conway's Game of Life Art

9,028

94

29

Introduction: The Beauty of Math - Conway's Game of Life Art

I've never been in good relationship with math. Especially with high school math. I don't think I'm alone with this problem, am I right? :)

But I cannot deny the importance of mathematics, and when I have the opportunity, I use its results shamelessly. The same is in this article where I decided to present you an attempt to visualize some art created by math and simulated on an Arduino Pro Mini microcontroller module. For this I used a game created by a Cambridge mathematician, John Conway. It's about Conway’s Game of Life.

The first appearance of this concept was in an article by Martin Gardner in the Scientific American (october 1970) - MATHEMATICAL GAMES - The fantastic combinations of John Conway's new solitaire game "life". It is not a game in the strict sense of the word but it is a so-called cellular automaton, a mathematical structure, an observer creates the start structure and follows the structure evolution without any further intervention. This kind of mathematical structures began to be researched since the 1940's when the concept was invented by von Neumann, but only with the appearance of the article in the Scientific American this concept came to the public's attention.

Since then, more and more discoveries have been made in this field, more and more research, and if you search the Internet, you will be completely spoiled when you will see the latest findings in this field of mathematical research. Moreover... WIth this “game” you can simulate complex biological, chemical, social processes… and this cellular automaton can also have applications in computing and cryptography. Insane!

Ok ok

As I have told you, since I don't have too much affinity with math, it is too high for me but I want to show you that math can be beautiful. With a 16x16 RGB LED display available, I'll try to visualize the artificial world from Conway's Game of Life and other ''Life Like" worlds.

Step 1: What Is the Game?

Let's see, first of all, what this game is.

Everything happens in a two-dimensional grid of squares where we start from randomly arranged squares (cells). There may be more or less cells. Each cell can have more or fewer neighbors either horizontally or vertically or on the two diagonals, maximum eight neighbors, as in the picture below.

The following move, state, generation, is established according to three simple rules (in the images there are only some examples not every possible configuration):

If a cell is dead (non-existent on the grid) and has exactly 3 neighbors it will become alive (birth);

If the cell has 2 or 3 neighbors it will live on (it will survive);

In all other cases: less than 2 neighbors (loneliness) or more than three neighbors (overcrowding) the cell will die (will disappear from the grid);

Of course the rules apply at the same time to all cells of a certain generation (before any of the rules are applied). This rule is thus written B3/S23 (birth at 3 neighbors, survival at 2 and 3 neighbors) We will see later that there are many other interesting worlds with other rules.

Step 2: Software

For the software implementation I have adapted Jason Coon’s code, you can find it here on github.

For displaying color effects I used a few color palettes from cpt_city.

After the initialization of some variables and a "cell" class that stores the properties of the 256 possible cells, there are some functions I used in the program:

  • random initialization of the generation Zero - randomFillWorld;
  • calculation of the number of neighbors for a cell in the grid - neighbors;
  • calculation of the order number of the RGB LED in the display matrix - XY;
  • random choice of a new color palette - chooseNewPalette;
  • in the setup function, the random number generator and the display are initialized
  • in the loop function every 256 iterations, the display is deleted, a new generation is initialized, a new color palette is displayed, the cells of generation 0 are displayed, the calculations for the new generation are made, these calculations are saved, and the cycle is resumed.

I have uploaded the source code to github, I hope you will not have problems using it. Some observations:

  • I could not used Jason Coon’s original code due to the memory limitations of the Arduino Pro Mini module, the original code is for teensy 3.1;
  • The rules for calculating the new generation of cells can be changed and the color effects in this way can be drastically changed; Also some initial variables (density, fading_step) can be changed, other color palettes can be used and the color effects will be different in this way also;
  • The display I used is quite small, with a 32x32 pixel display for example, the effects can be much more interesting, of course with another microcontroller (maybe ESP32), with a web control interface, so this project can even become a real art object, a point of attraction of a working or living space :)

Step 3: Hardware

The electronic components used are: an Arduino Pro Mini module, four 8x8 RGB WS2812 arrays and a 5v 1A power supply. The electronic scheme is very simple, you can see it above in the first diagram.

If you decide to increase the number of RGB arrays, say to 16 ( ie a 32x32 pixel display) then you should use a microcontroller module with larger RAM (an Arduino Mega or ESP12) and also a larger power supply: 2.5 - 3A. The RGB LED matrices could be arranged as shown in the second diagram above.

All this electronics can be mounted in a box as in my instructable about chess on the arduino. An interesting plus can be brought if you slightly move away the display from the smoked plexiglas sheet and the paper piece, the LED light will become more blurred and the effect of the changing color patterns will be more organic, more natural, you can see this in the video materials at the next step. In the photos below you can see the Arduino Chess Master display used for this demo :)

Wooden photo frame, smoked plexiglas, piece of paper, plastic frame (10mm height) for moving away the electronic board from the display (as in the second photo).

Title

Step 4: Conclusions

After uploading the software you can play with the birth and survival rules. There are theoretically 218 = 262144 possible Life-like rules, only some of them was studied extensively, many rules are still waiting to be discovered :) These rules can have different notations. I will use the so called Golly/RLE format where the rules are in the form Bx/Sy. The x number next to B ("Born") means how many neighbors are needed for a cell to become (or remain) alive, the y number next to S ("Survive") means how many neighbors are needed for a cell to survive in the next generation. So Conway's Game of Life notation would be in this case B3/S23. From Mirek Wojtowicz Cellular Automata explorer's site I choose seven other rules beside Conway's basic rule, in the source code on github you can see how I coded these rules in the software (simply uncomment the new rule and comment the previous rule used to experiment with them).

Finally you can look at the video materials bellow to see how everything works (turn on closed captions for info).

Non blurred display, four rules

Same rules, but blurred display (with the electronic board mounted away from the displays plexiglas sheet)

Blurred, four other rules

Made with Math Contest

First Prize in the
Made with Math Contest

Be the First to Share

    Recommendations

    • Colors of the Rainbow Contest

      Colors of the Rainbow Contest
    • Toys & Games Contest

      Toys & Games Contest
    • Explore Science Challenge

      Explore Science Challenge

    29 Comments

    0
    matlock51
    matlock51

    Question 1 year ago

    Hi. I looked at you code and wonder if it is possible to use just one WS2812 matrix instead of four or more. Thanks. Really nice instructable!

    0
    andrei.erdei
    andrei.erdei

    Answer 1 year ago

    Yes you can. If you use only one 8x8 matrix and the rest remain the same you must modify a few lines in the code:
    change
    const uint8_t MatrixWidth = 16;
    const uint8_t MatrixHeight = 16;
    to
    const uint8_t MatrixWidth = 8;
    const uint8_t MatrixHeight = 8;
    ----
    const uint8_t bMatrixWidth = 2;
    const uint8_t bMatrixHeight = 2;
    to
    const uint8_t bMatrixWidth = 1;
    const uint8_t bMatrixHeight = 1;
    ------
    #defineNUM_LEDS (256)
    to
    #defineNUM_LEDS (64)

    that's all.
    0
    matlock51
    matlock51

    Reply 1 year ago

    Hi Andrei,

    Before making the changes I tried to compile your program on an Arduino Uno and got compilation errors. I installed FastLED.h by Daniel Garcia V3.3.3. There seems to be issues within FastLED when the program tries to compile. Should I use another version of FastLED such as the neo matrix version? Thanks for your help.

    0
    matlock51
    matlock51

    Reply 1 year ago

    Hi again,

    Well everything now compiles and uploads. The problem seems to be with the chipset designation. You have set the chipset in your program to WS2811. I tried this and it just gives a static display with a few LEDS lit. My chipset is WS2812B. When I define the chipset to WS2812B, I get a static pattern of a few LEDs again. Now I am really confused. Is it possible that the code can't run with a single 8x8 matrix? Any advice would help. Thanks

    0
    andrei.erdei
    andrei.erdei

    Reply 1 year ago

    I compiled with FastLED 3.3.3, Arduino IDE 1.8.12, Arduino UNO and source from github without any problem. I have ws2812b matrix also.
    64 pixels are not quite enough for Game of Life. Cells quickly dies sometimes. My initial settings are good for a 16x16 matrix. You can try for example density=40 and fading_step=4. But you can try other set of rules for cellular automaton for example 'Replicator' (comment the lines of Conway's rules and uncomment 'Replicator' rules).
    I attached an image with the program running. You can see that from 4 matrixes (this is the construction I used for my instructable) only one is active.

    IMG_20200426_112820.jpg
    0
    matlock51
    matlock51

    Reply 1 year ago

    Hi Andrei,
    I am now running Arduino 1.8.12 and fastLed 3.3.3. No matter what I do I get a static display that never changes. Some of the LEDS are very bright, some are dim. The program goes through the loop (I put on a loop counter to watch on the serial monitor and the display never changes). I've tried Arduino pins 2-7 with no difference. I assume digital PWM pin 2 is set to this value in the fastLED code - but it doesn't seem to make much difference which PWM pin I use. Could this be an issue running the UNO versus the Pro MIni?
    I've also tried Replicator. The LED's never fade. If I cut the power to the matrix, and reset the Arduino, I get the same configuration of static LEDS. I just ordered another WS2812B 8x8 matrix just to be sure it's not a hardware issue. I've tried the program setting the #define CHIPSET to WS2811, WS2812, WS2812B with same behavior. Sorry for this long thread. I'd really like to get your pgm running on 8x8

    0
    andrei.erdei
    andrei.erdei

    Reply 1 year ago

    I understand you frustration and I really want to help. So.
    I don't have an UNO for testing but I'm sure that the code should work fine.
    Why don't you try a simple test code before something complicated?
    This code lights up one by one the leds from the matrix:

    #define FASTLED_INTERRUPT_RETRY_COUNT 0
    #include "FastLED.h"
    #define NUM_LEDS 64
    CRGB leds[NUM_LEDS];
    #define LED_PIN 2 // digital pin 2
    #define COLOR_ORDER GRB
    #define CHIPSET WS2811
    #define BRIGHTNESS 80
    int i;
    void setup() {
    //FastLED.addLeds, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setDither(fullbrightness < 255);
    FastLED.addLeds
    (leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
    FastLED.setBrightness( BRIGHTNESS );
    }
    void loop() {
    for (i = 0; i < NUM_LEDS; i++) {
    leds[i] = CRGB::Red;
    FastLED.show();
    delay(250);
    leds[i] = CRGB::Black;
    FastLED.show();
    delay(250);
    }
    delay (1000);
    }
    Is this working ok?
    How are you powering your matrix? From Arduino UNO's power? Consider powering the matrix from a separate power source.

    0
    matlock51
    matlock51

    Reply 1 year ago

    Hi Andrei,
    I am using a separate 5v power supply. I get same results using test code (static display - a bunch of LEDs lit) on the Arduino Uno and on the Mega with the digital pin set to 52. The only thing that comes to mind is that the WS2812B I have is either faulty or incompatible. I should get new display from a different supplier on Wednesday so I'll test again and get back to you either way. Thanks for your patience!

    0
    andrei.erdei
    andrei.erdei

    Reply 1 year ago

    No problem :)
    if I can I'll help you.
    By the way do you have any info about this matrix that is causing you problems?

    0
    matlock51
    matlock51

    Reply 1 year ago

    Hi Andrei,
    Is it possible to modify the code so that all 'alive' pixels are white and after each iteration to change them (after a short time delay) to black? In other words no color, no fading, just 'white' for alive and 'black' pixels. Thanks for considering this question.

    0
    matlock51
    matlock51

    Reply 1 year ago

    It looks great! Thanks! By the way I put in a flag to check when there are no more births and deaths (end of generation i). Since some of the games are very short, this eliminates a long wait before beginning the next game. The only issue is where the live cells cycles between two states. It need further code to detect that steady state condition. To eliminate this issue of the cycle lasting forever I just kept the last if statement but set the number to a compromise (say 75) rather that 256. Thanks again for all your help!

    0
    andrei.erdei
    andrei.erdei

    Reply 1 year ago

    I'm glad you were successful.
    Best regards!

    0
    andrei.erdei
    andrei.erdei

    Reply 1 year ago

    Of course. That's why I posted the code on github, to be forked and freely modified. But with your proposal you miss the whole point of the project: you give up the usage of color palettes of the FASTLed library, you give up the color effects and if you don't want colors why use an RGB led matrix? I googled for you and found some projects that work as you wish:
    https://www.instructables.com/id/8x8LED-game-of-li...
    https://fossbytes.com/conways-game-life-arduino-le...
    http://thehumblecode.com/blog/how-to-create-the-ga...
    http://brownsofa.org/blog/2010/12/30/arduino-8x8-https://www.reddit.com/r/arduino/comments/25gxsn/m...

    0
    matlock51
    matlock51

    Reply 1 year ago

    Hi Andrei,
    Please don't think that I didn't appreciate your artistic implementation of game of life using fastLED. I did and have modified the code according to your instructions and have a beautiful running display. My interest in doing a white implementation came from the palette example in github - fastLED examples. One of the sequences is a band of white and black moving across the screen. I was thinking of implementing something like this example in the game of life.

    0
    andrei.erdei
    andrei.erdei

    Reply 1 year ago

    Cold you take me to that example? I want to see what is all about :)

    0
    matlock51
    matlock51

    Reply 1 year ago

    Go to github.com/fastLED. Download fastLED and extract all. There are a number of folders. One of them is "examples". Open it and look for 'ColorPalette'. Open it. The file is 'ColorPalette.ino". You'll find the white/black example near the bottom of the file.

    0
    andrei.erdei
    andrei.erdei

    Reply 1 year ago

    If you want you can define a black and white stripes color palette exactly how it is defined in that example and add it to see how it looks.

    0
    andrei.erdei
    andrei.erdei

    Reply 1 year ago

    You can try this steps:
    - add at the end of the code the function:

    void SetupBlackAndWhiteStripedPalette()
    {

    // 'black out' all 16 palette entries...
    fill_solid( currentPalette, 16, CRGB::Black);
    // and set every fourth one to white.
    currentPalette[0] = CRGB::White;
    currentPalette[4] = CRGB::White;
    currentPalette[8] = CRGB::White;
    currentPalette[12] = CRGB::White;
    }
    - call this function in setup() after 'Serial.begin(9600);' line
    SetupBlackAndWhiteStripedPalette();
    - comment the line that change the color palette
    //chooseNewPalette();
    How it looks?...

    0
    matlock51
    matlock51

    Reply 1 year ago

    Hi Andrei,
    I sent you the Amazon link to the 8x8 matrix I used. You will not believe this!!! The silkscreen on the backside of the board is mis-printed. dout is actually din. Now by using dout as din everything works perfectly. This kind of thing has never happened to me - so it was the last thing I checked. Sorry for all the time you spent trying to get me up and running. Best Regards, Gary