Skip to content

Instantly share code, notes, and snippets.

@Mineinjava
Created September 22, 2021 04:21
Show Gist options
  • Save Mineinjava/d478471796d2ce171518abc1c812a002 to your computer and use it in GitHub Desktop.
Save Mineinjava/d478471796d2ce171518abc1c812a002 to your computer and use it in GitHub Desktop.
Watchy-Life

Watchy-Life

Adaptation of Conoway's game of life for Watchy-Screen

This code assumes a couple of things:

  1. You have a shared.h file with a MainScreen function that returns to the main screen. If you don't, you will need to adjust the lifegame.h
  2. You are putting these files into a src/Screens directory (see where the default screens go in Watchy-Screen

Much of the logic in this code is taken from here. Thus, most of the comments are incorrect.

Known Bugs:

  • spawning a glider does not work

Enjoy!

// 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);
}
#include "Shared.h"
#include "Screen.h"
class WatchyLife : public Screen {
void back() {MainScreen();};
void show();
void up();
void down();
void menu();
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment