#weeklycoding 2025W13 life

First instance of my weekly coding:

Implementation of Conway's Game of Life with two twists to make it more interesting to look at:
* new cells are shown in green, dying cells in red
* new cells fade in, dying cells fade out

Animation of multiple generations of Conway's game of life

Java code below is for Processing 4.3.3


int cols = 20;
int rows = 20;
int[][] present = new int[cols][rows];
int[][] future  = new int[cols][rows];
int[][] delta   = new int[cols][rows];
int dist;
int step = 0;

void setup() {
  int col, row;
  
  size(800, 800);
  dist = width / rows;
  frameRate(60);
  colorMode(RGB, 255);
  background(0);

// Random pattern - comment this to use the Glider below
  for (col = cols/4; col < cols*3/4; col++) {
    for (row = rows/4; row < rows*3/4; row++) {
      present[col][row] = int(random(2));;
    }
  }
  
// Glider  
  //present[1][1] = 1;
  //present[2][1] = 1;
  //present[3][1] = 1;
  //present[3][2] = 1;
  //present[2][3] = 1;
  
  for (col = 0; col < cols; col++) {
    for (row = 0; row < rows; row++) {
      delta[col][row] = present[col][row]; 
    }
  }
}

int wraprow(int row) {
  if (row == -1)   return rows-1;
  if (row == rows) return 0;
  return row;
}

int wrapcol(int col) {
  if (col == -1)   return cols-1;
  if (col == cols) return 0;
  return col;
}

int countNeighbors(int[][] cells, int col, int row) {
  int neighbors = 0, i, j;
  
  for (i=-1; i<=1; i++) {
    for (j=-1; j<=1; j++) {
      if (i!=0 || j!=0) {
        neighbors += cells[wrapcol(col+i)][wraprow(row+j)];
      }
    }
  }
  return neighbors;
}

void drawCell(int col, int row, int cellColor) {
  fill(cellColor);
  rect(row*dist, col*dist, dist, dist);  
}

void calculateFuture() { 
  int col, row, neighbors;
 
  for (col = 0; col < cols; col++) {
    for (row = 0; row < rows; row++) {
      neighbors = countNeighbors(present, col, row);
      if (neighbors == 2) {
        future[col][row] = present[col][row];
      } else {
        if (neighbors == 3) {
          future[col][row] = 1; 
        } else {
          future[col][row] = 0; 
        }
      }
    }
  }
}

void calculateDelta() { 
  int col, row;
 
  for (col = 0; col < cols; col++) {
    for (row = 0; row < rows; row++) {
      if (present[col][row] == 0 && future[col][row] == 1) {
        delta[col][row] = 1;
      } else {
        if (present[col][row] == 1 && future[col][row] == 0) {
          delta[col][row] = -1;
        } else {
          delta[col][row] = 0;
        }  
      }
      
      present[col][row] = future[col][row]; 
    }
  }
}

void drawDelta() {
  int whiteLevel;
  
  for (int col = 0; col < cols; col++) {
    for (int row = 0; row < rows; row++) {
      if (delta[col][row] != 0) {
        if (step >= 128) {
          whiteLevel = step - 128;
        } else {
          whiteLevel = 0;
        }
        if (delta[col][row] > 0) {
          fill(whiteLevel*2, step, whiteLevel*2);
        } 
        if (delta[col][row] < 0) {
          fill(255 - whiteLevel * 2, 255 - step, 255 - step);
        } 
        rect(row*dist, col*dist, dist, dist); 
      }
    }
  }
}

void draw() {

  if (step > 255) { 
  
    calculateFuture();
    calculateDelta();
    
    delay(1000);
  
    step = 0;
    
  } else {
    
    drawDelta();
    
    step++;   
  }
}