#include <Arduino.h> #include "display.h" #include "gameoflife.h" #include "network.h" #include "utils.h" // https://github.com/Stavrosfil/game-of-life-esp32 int g[SCREEN_HEIGHT][SCREEN_WIDTH]; int arrayCopy[SCREEN_HEIGHT][SCREEN_WIDTH]; bool runGame = true; bool gameOver = false; int gameEra = 0; int currentTick; int finalTicks; int cellsAliveNow; int cellsAliveBefore; int noEvolutionTicks; const uint scoreScreenTimeout = 5000; unsigned long currentMillis; void setupGameOfLife() { gameOver = false; gameEra++; currentTick = 0; finalTicks = 0; cellsAliveBefore = 0; noEvolutionTicks = 0; randomSeed(analogRead(34)); createRandomMatrix(g); for (int i = 0; i < 10; i++) { addGlider(random(SCREEN_HEIGHT), random(SCREEN_WIDTH), g); } logLine("Starting Game " + String(gameEra)); } void createRandomMatrix(int (&a)[SCREEN_HEIGHT][SCREEN_WIDTH]) { for (int i = 0; i < SCREEN_HEIGHT; i++) { for (int j = 0; j < SCREEN_WIDTH; j++) { a[i][j] = random(100) < 25 ? 1 : 0; } } } void gameOfLife(int (&a)[SCREEN_HEIGHT][SCREEN_WIDTH]) { cellsAliveNow = 0; currentTick++; 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] == 1) { if (total < 2 || total > 3) { arrayCopy[i][j] = 0; } } else if (total == 3) { arrayCopy[i][j] = 1; cellsAliveNow++; } } } 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, int (&a)[SCREEN_HEIGHT][SCREEN_WIDTH]) { // 010 // 001 // 111 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 gameLoop() { if (runGame == false) { return; } gameOfLife(g); if (gameOver) { int brightness = constrain(floor(255 * (1 - ((float)(millis() - currentMillis) / (float)scoreScreenTimeout * 2))), 0, 255); gameBrightness(brightness); if (millis() - currentMillis > scoreScreenTimeout) { resetGame(); } } else // not gameOver { if (currentTick % 2) { // char msg[80]; // sprintf(msg, "Tick: %4d, Cells now: %4d, before: %4d - No evolution since: %3d", currentTick, cellsAliveNow, cellsAliveBefore, noEvolutionTicks); // logLine(msg); cellsAliveBefore = cellsAliveNow; } if (cellsAliveNow >= cellsAliveBefore - 5 && cellsAliveNow <= cellsAliveBefore + 5) { noEvolutionTicks++; } else { noEvolutionTicks = 0; } if (noEvolutionTicks > noEvolutionTicksLimit) { finalTicks = currentTick - noEvolutionTicksLimit; currentMillis = millis(); showEndScreen(finalTicks); gameOver = true; } } } void resetGame() { setupGameOfLife(); clearDisplay(); }