From 52e71bfb639b2d53a3ea8e15577206ad79f20894 Mon Sep 17 00:00:00 2001 From: Chris Knight Date: Thu, 10 Sep 2020 20:34:38 -0700 Subject: [PATCH] draft proposal for community-contributed programs --- .../claud9999-life/life.ino | 121 ++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 examples/4. Community Contributions/claud9999-life/life.ino diff --git a/examples/4. Community Contributions/claud9999-life/life.ino b/examples/4. Community Contributions/claud9999-life/life.ino new file mode 100644 index 0000000..4b93de0 --- /dev/null +++ b/examples/4. Community Contributions/claud9999-life/life.ino @@ -0,0 +1,121 @@ +/** Example "Game of Life" program for the InkPlate 6 by Chris Knight + * https://github.com/claud9999 + */ + +#include + +Inkplate display(INKPLATE_1BIT); + +#define SCREEN_WIDTH 800 +#define SCREEN_HEIGHT 600 + +#define MIN_CELLSZ 8 +#define MAX_CELLSZ 40 + +// initialize dimensions to the minimum size cell, maximum size arrays +int cell_size = 0, cols = 0, rows = 0, + cell_maxage = 0, offset_x = 0, offset_y = 0; + +char grid_a[(SCREEN_WIDTH / MIN_CELLSZ) * (SCREEN_HEIGHT / MIN_CELLSZ)], + grid_b[(SCREEN_WIDTH / MIN_CELLSZ) * (SCREEN_HEIGHT / MIN_CELLSZ)]; +char *grid_curr = grid_a, *grid_next = grid_b, *grid_tmp = NULL, + cell_curr, cell_next; +int x = 0, y = 0, dx = 0, dy = 0, nx = 0, ny = 0, + neighbors = 0, cell_delta = 0, frame_count = 0; + +void randomize() { + cell_size = random(MIN_CELLSZ, MAX_CELLSZ + 1); + + // compute the (rounded-down) number of rows and columns + cols = SCREEN_WIDTH / cell_size; + rows = SCREEN_HEIGHT / cell_size; + + cell_maxage = (cell_size / 2) - 1; + // compute the "extra" space not covered by this grid, offset by half + offset_x = (SCREEN_WIDTH - cols * cell_size) / 2; + offset_y = (SCREEN_HEIGHT - rows * cell_size) / 2; + + display.clean(); + display.display(); + + display.clearDisplay(); + + // compute a random density... + int density = random(5,15); + + // and for that density, populate the initial grid + for(x = 0; x < cols; x++) { + for (y = 0; y < rows; y++) grid_curr[x + y * cols] = random(density) == 0; + } + + frame_count = 0; +} + +void setup() { + Serial.begin(115200); + display.begin(); + randomize(); +} + +void loop() { + cell_delta = 0; + for(x = 0; x < cols; x++) { + for(y = 0; y < rows; y++) { + // count neighboring cells + neighbors = 0; + for(dx = -1; dx < 2; dx++) { + for(dy = -1; dy < 2; dy++) { + if(dx == 0 && dy == 0) continue; // skip "me" + + nx = x + dx; if(nx < 0) nx = cols - 1; else if(nx >= cols) nx = 0; + ny = y + dy; if(ny < 0) ny = rows - 1; else if(ny >= rows) ny = 0; + + if(grid_curr[nx + ny * cols]) neighbors++; + }// end for(dy) + }// end for(dx) + + cell_curr = grid_curr[x + y * cols]; + cell_next = 0; + switch(neighbors) { + case 2: // alive with 2 neighbors remains alive + if(!cell_curr) break; + // else cell is alive drop through + case 3: // 3 neighbors == alive + cell_next = cell_curr + 1; + if(cell_next > cell_maxage) cell_next = cell_maxage; + } + + if(cell_next != 0 && cell_curr == 0 + || cell_next == 0 && cell_curr != 0) + cell_delta++; + + if(cell_next) { + // if this is a new cell, paint it black + if(cell_next == 1) + display.fillRect(x * cell_size + offset_x, y * cell_size + offset_y, + cell_size, cell_size, 1); + // otherwise paint the inside white depending on how old it is + else display.fillRect( + x * cell_size + cell_size / 2 - cell_next + offset_x, + y * cell_size + cell_size / 2 - cell_next + offset_y, + cell_next * 2, cell_next * 2, 0); + } else if (cell_curr) { + // otherwise it's died, paint the whole cell white + display.fillRect(x * cell_size + offset_x, y * cell_size + offset_y, + cell_size, cell_size, 0); + } + + grid_next[x + y * cols] = cell_next; + }//end for(y) + }//end for(x) + + // swap which grid is current + grid_tmp = grid_next; grid_next = grid_curr; grid_curr = grid_tmp; + + // the longer this goes, the more cells this has, + // the more change is required or we reset + if(cell_delta * cell_size < frame_count) randomize(); + else frame_count++; + + display.partialUpdate(); +}