Conway's Game of Life - игра Жизнь (Клеточный автомат) Джона Конвея придуманная в 1970 году имеет множество форков. Классические правила игры Жизнь Конвея, коротко, можно записать формулой B3/S23. Где B — рождение, S — сохранение. Цифрами обозначено количество соседей.
«Conway's Game of Life» - клеточный автомат Джона Конвея имеет следующие правила: в пустой клетке появляется жизнь только тогда, когда рядом с ней имеется ровно три живых клетки. Клетка не меняет своего состояния когда рядом с ней имеется ровно две живые клетки. Во всех других случаях клетки умирают, т. е. становятся пустыми.

Схема подключения LED дисплея SSD1306 I2C очень простая, поэтому её здесь не привожу. У дисплея всего 4 вывода, из них 2 питание от 3,3 до 5 Вольт. Подключите вывод SDA на плате дисплея к выводу A4, а вывод SCK к выводу A5 на плате Arduino. Будем использовать аппаратный I2C интерфейс микроконтроллера ATMega 328 со стандартной для среды Arduino IDE библиотекой Whare и библиотекой ADi_SSD1306I2C128x64, загруженной с GitHub.
#include <Wire.h>
#include <ADi_SSD1306I2C128x64.h>
#define X 16    /* ширина экрана */
#define Y 8     /* высота экрана*/
#define XP 32   /* ширина поля */
#define YP 16   /* высота поля*/
bool state[2][XP][YP];
bool k = 0;     /* чётность */
ADi_SSD1306I2C128x64 oled;
void setup() {
  Wire.begin();
  Wire.setClock(400000);
  oled.ledIni();
  oled.clear();
  /* пульсар СР 48-56-72  */
  state[0][14][7] = 1;
  state[0][15][7] = 1;
  state[0][16][7] = 1;
  state[0][17][7] = 1;
  state[0][18][7] = 1;
  state[0][18][8] = 1;
  state[0][14][8] = 1;
}
void loop() {
  prnt();
  delay (200);
  play();
  k = !k;
}
void prnt () {
  for (int y = 0; y < Y; y++) {
    for (int x = 0; x < X; x++) {
      unsigned char block[8] {0, 0, 0, 0, 0, 0, 0, 0};
      for (int z = 0; z < 4; z++) {
        if (state[k][x * 2 + (z > 1)][y * 2 + !(z % 2)] == 1) {
          block[1 + 4 * (z > 1)] += 14 + 210 * !(z % 2);
          block[2 + 4 * (z > 1)] += 10 + 150 * !(z % 2);
          block[3 + 4 * (z > 1)] += 14 + 210 * !(z % 2);
        }
      }
      oled.out(block);
    }
  }
}
void play() {
  /* Правило B3/S23 клетка рождается, если у неё три соседа, и выживает, если у неё два или три соседа */
  bool buf[XP][YP];
  for (int x = 0; x < XP; x++) {
    for (int y = 0; y < YP; y++) {
      int count = counter(k, x, y);
      if (count == 3) state[!k][x][y] = 1;
      else if (count == 2) state[!k][x][y] = state[k][x][y];
      else state[!k][x][y] = 0;
    }
  }
}
int counter(int k, int x, int y) {
  return state[k][x][tube(y - 1)] + state[k][tor(x + 1)][tube(y - 1)] + state[k][tor(x + 1)][y] + state[k][tor(x + 1)][tube(y + 1)] + state[k][x][tube(y + 1)] + state[k][tor(x - 1)][tube(y + 1)] + state[k][tor(x - 1)][y] + state[k][tor(x - 1)][tube(y - 1)];
}
int tor(int x) {
  x < 0 ? x = XP - 1 : 0;
  x == XP ? x = 0 : 0;
  return x;
}
int tube(int y) {
  y < 0 ? y = YP - 1 : 0;
  y == YP ? y = 0 : 0;
  return y;
}