From e32f90d4afe25f1be6eeea42187bad0c8298268d Mon Sep 17 00:00:00 2001 From: radex Date: Mon, 15 Apr 2024 23:13:11 +0200 Subject: [PATCH] game of life proof of concept --- firmware/src/life.cpp | 66 +++++++++++++++++++++++++++++++++++++++++++ firmware/src/main.cpp | 33 ++++++++++++++++++++-- 2 files changed, 96 insertions(+), 3 deletions(-) create mode 100644 firmware/src/life.cpp diff --git a/firmware/src/life.cpp b/firmware/src/life.cpp new file mode 100644 index 0000000..2687f22 --- /dev/null +++ b/firmware/src/life.cpp @@ -0,0 +1,66 @@ +#include +#include + +#define CELLS_X 40 +#define CELLS_Y 40 +#define CELL_COUNT (CELLS_X * CELLS_Y) + +bool cells[CELL_COUNT] = {0}; + +#define XY(x, y) (x + y * CELLS_Y) + +void life_setup() { + // set up initial state + cells[XY(2, 1)] = true; + cells[XY(3, 2)] = true; + cells[XY(1, 3)] = true; + cells[XY(2, 3)] = true; + cells[XY(3, 3)] = true; +} + +void life_step() { + bool new_cells[CELL_COUNT] = {0}; + + for (int y = 0; y < CELLS_Y; y++) { + for (int x = 0; x < CELLS_X; x++) { + int neighbors = 0; + bool wasLive = cells[XY(x, y)]; + + for (int dy = -1; dy <= 1; dy++) { + for (int dx = -1; dx <= 1; dx++) { + if (dx == 0 && dy == 0) { + continue; + } + + int check_y = y + dy; + int check_x = x + dx; + + if (check_y >= 0 && check_y < CELLS_Y) { + if (check_x >= 0 && check_x < CELLS_X) { + if (cells[XY(check_x, check_y)]) { + neighbors++; + } + } + } + } + } + + if (wasLive && neighbors < 2) { + // dies by underpopulation + } else if (wasLive && (neighbors == 2 || neighbors == 3)) { + // continues to live + new_cells[XY(x, y)] = true; + } else if (wasLive && neighbors > 3) { + // dies by overpopulation + } else if (!wasLive && neighbors == 3) { + // reproduces + new_cells[XY(x, y)] = true; + } else { + // still dead, jim + } + } + } + + // copy + memcpy(cells, new_cells, sizeof(cells)); +} diff --git a/firmware/src/main.cpp b/firmware/src/main.cpp index 746f936..ff0b7d1 100644 --- a/firmware/src/main.cpp +++ b/firmware/src/main.cpp @@ -52,6 +52,10 @@ uint8_t brightnessPhaseDelays[] = {1, 10, 30, 100}; uint8_t framebuffer[ROW_COUNT * COL_COUNT] = {0}; void main2(); +void life_setup(); +void life_step(); +extern bool cells[ROW_COUNT * COL_COUNT]; + void setup() { Serial.begin(115200); Serial.println("Hello worldd!"); @@ -91,9 +95,20 @@ void setup() { // launch core1 // NOTE: For some reason, without delay, core1 doesn't start? - delay(500); - multicore_reset_core1(); - multicore_launch_core1(main2); + // delay(500); + // multicore_reset_core1(); + // multicore_launch_core1(main2); + + // setup_audio(); + + life_setup(); + + // copy cells to framebuffer + for (int y = 0; y < ROW_COUNT; y++) { + for (int x = 0; x < COL_COUNT; x++) { + framebuffer[y * ROW_COUNT + x] = cells[y * ROW_COUNT + x] ? 255 : 0; + } + } } void loop2(); @@ -137,6 +152,18 @@ void loop() { lastRenderedFrameIndex = frameIndex; } + // game of life step + auto now = millis(); + if (now - frameLastChangedAt > 100) { + frameLastChangedAt = now; + life_step(); + for (int y = 0; y < ROW_COUNT; y++) { + for (int x = 0; x < COL_COUNT; x++) { + framebuffer[y * ROW_COUNT + x] = cells[y * ROW_COUNT + x] ? 255 : 0; + } + } + } + // hide output outputEnable(ROW_OE, false);