|
// Conoway's Game Of Life -- Watchy Implementation |
|
// Adaptation of |
|
// https://github.com/Stavrosfil/game-of-life-esp32/blob/master/src/main.cpp |
|
|
|
#include "lifegame.h" |
|
|
|
#define SCREEN_WIDTH 25 // OLED display width, in pixels |
|
#define SCREEN_HEIGHT 25 // OLED display height, in pixels |
|
|
|
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins) |
|
|
|
RTC_DATA_ATTR short int g[SCREEN_HEIGHT][SCREEN_WIDTH]; |
|
short int arrayCopy[SCREEN_HEIGHT][SCREEN_WIDTH]; |
|
RTC_DATA_ATTR bool isfirstshow = true; |
|
|
|
void createRandomMatrix(short int (&a)[SCREEN_HEIGHT][SCREEN_WIDTH]) { |
|
for (int i = 0; i < SCREEN_HEIGHT; i++) { |
|
for (int j = 0; j < SCREEN_WIDTH; j++) { |
|
g[i][j] = round((float)rand() / (float)RAND_MAX); |
|
} |
|
} |
|
} |
|
|
|
void gameOfLife(short int (&a)[SCREEN_HEIGHT][SCREEN_WIDTH]) { |
|
for (int i = 0; i < SCREEN_HEIGHT; i++) { |
|
for (int j = 0; j < SCREEN_WIDTH; j++) { |
|
arrayCopy[i][j] = a[i][j]; |
|
} |
|
} |
|
|
|
for (int i = 0; i < SCREEN_HEIGHT; i++) { |
|
for (int j = 0; j < SCREEN_WIDTH; j++) { |
|
int total = |
|
(a[i][(j - 1) % SCREEN_WIDTH] + a[i][(j + 1) % SCREEN_WIDTH] + |
|
a[(i - 1) % SCREEN_HEIGHT][j] + a[(i + 1) % SCREEN_HEIGHT][j] + |
|
a[(i - 1) % SCREEN_HEIGHT][(j - 1) % SCREEN_WIDTH] + |
|
a[(i - 1) % SCREEN_HEIGHT][(j + 1) % SCREEN_WIDTH] + |
|
a[(i + 1) % SCREEN_HEIGHT][(j - 1) % SCREEN_WIDTH] + |
|
a[(i + 1) % SCREEN_HEIGHT][(j + 1) % SCREEN_WIDTH]); |
|
|
|
|
|
if (a[i][j] == 0) { // cell is dead |
|
if (total == 3) { // exactly three neighbors |
|
arrayCopy[i][j] = 1; |
|
} |
|
} else if (a[i][j] == 1) { // cell is alive |
|
if (total < 2) { // fewer than two neigbors |
|
arrayCopy[i][j] = 0; |
|
} |
|
if (total > 3) { // greater than three neighbors |
|
arrayCopy[i][j] = 0; |
|
} |
|
} |
|
|
|
|
|
} |
|
} |
|
|
|
for (int i = 0; i < SCREEN_HEIGHT; i++) { |
|
for (int j = 0; j < SCREEN_WIDTH; j++) { |
|
a[i][j] = arrayCopy[i][j]; |
|
} |
|
} |
|
} |
|
|
|
void addGlider(int i1, int j1, short int (&a)[SCREEN_HEIGHT][SCREEN_WIDTH]) { |
|
int glider[3][3] = {{0, 0, 1}, {1, 0, 1}, {0, 1, 1}}; |
|
for (int i = 0; i < 3; i++) { |
|
for (int j = 0; j < 3; j++) { |
|
a[i1 + i][j1 + j] = glider[i][j]; |
|
} |
|
} |
|
} |
|
|
|
void WatchyLife::show() { |
|
if (isfirstshow) { |
|
createRandomMatrix(g); |
|
} else { |
|
gameOfLife(g); |
|
} |
|
|
|
isfirstshow = false; |
|
// Watchy::display.fillScreen(GxEPD_WHITE); |
|
|
|
for (int i = 0; i < SCREEN_HEIGHT; i++) { |
|
for (int j = 0; j < SCREEN_WIDTH; j++) { |
|
if (g[i][j] == 1) { |
|
Watchy::display.fillRect(j * 8, i * 8, 8, 8, GxEPD_BLACK); |
|
// Serial.println("1"); |
|
} else { |
|
// Serial.println("0"); |
|
Watchy::display.fillRect(j * 8, i * 8, 8, 8, GxEPD_WHITE); |
|
} |
|
} |
|
} |
|
} |
|
void WatchyLife::up() { createRandomMatrix(g); } |
|
void WatchyLife::down() { |
|
show(); |
|
Watchy::display.display(true); |
|
} |
|
void WatchyLife::menu() { |
|
addGlider(5,5,g); |
|
} |