Печать

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

«Conway's Game of Life» - клеточный автомат Джона Конвея имеет следующие правила: в пустой клетке появляется жизнь только тогда, когда рядом с ней имеется ровно три живых клетки. Клетка не меняет своего состояния когда рядом с ней имеется ровно две живые клетки. Во всех других случаях клетки умирают, т. е. становятся пустыми.

SSD1306 128x64 I2C

Схема подключения 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;
}