Tuesday, 24 September 2013

Conway's Game of life

Made Conway's famous Game of life in Processing, because I haven't been coding for a long time and need to get back into the swing of things...

Live cells are green, or eurgh if just born. Just dead cells are this green.

This is just a short gif...

And the messy code:

// univers
int cellSize = 4;
int cellsPerRow = 80;
int cellsPerCol = 80;
int margin = 20;

// horloge
int iterationInterval = 40; // millis
int lastIterationTime = millis();
boolean run = true;
boolean voisinsStep = true;

// cellules
int probabilityOfAliveAtStart = 10; // percent
int[][] cells;
int[][] cellsBuffer;
color cellColor[];
int deadCells;
int dyingCells;
int bornCells;
int liveCells;

//  messages
String[] messages;

void setup() {
  // définition de la taille
  size (cellsPerRow * (cellSize + 1) - 1 + margin*2,
        cellsPerCol * (cellSize + 1) - 1 + margin*2);
  
  // définition des couleurs
  stroke(128);
  cellColor = new color[4];
  cellColor[0] = color(0, 63, 0);    // morte
  cellColor[1] = color(63, 127, 0);  // mourante
  cellColor[2] = color(127, 127, 0); // née
  cellColor[3] = color(0, 255, 0);   // vive
  background(0);
  
  // remplissage des cellules
  cells = new int[cellsPerRow][cellsPerCol];
  cellsBuffer = new int[cellsPerRow][cellsPerCol];
  initializeCells();
  drawCells();
  
}


void draw() {
  // horloge
  if (millis() - lastIterationTime > iterationInterval && run == true) {
    lastIterationTime = millis();
    iterate();
    background(0);
    drawCells();
//    drawStack();
  }

  // grille
  for (int x = -1; x= probabilityOfAliveAtStart)
        cells[x][y] = 0;
      else cells[x][y] = 2;
    }
  }
}

void iterate() {
  /*
  born cell = 2
  live cell = 3
  dying cell = 1
  dead cell = 0
  */
  
  // buffer
  for (int x = 0; x < cellsPerRow; x++) {
    for (int y = 0; y < cellsPerCol; y++) {
      cellsBuffer[x][y] = cells[x][y];
    }
  }
  
  for (int x = 0; x < cellsPerRow; x++) {
    for (int y = 0; y < cellsPerCol; y++) {
      //println("Cell "+x+", "+y);
      // recensement des voisins
      int neighbours = 0;
      for (int xx = x - 1; xx <= x + 1; xx++) {
        for (int yy = y - 1; yy <= y + 1; yy++) {
          int xxx = xx;
          int yyy = yy;
          //  si on sort des limites on regarde de l'autre côté
          if (xx < 0) xxx = cellsPerRow - 1;
          if (yy < 0) yyy = cellsPerCol - 1;
          if (xx == cellsPerRow) xxx = 0;
          if (yy == cellsPerCol) yyy = 0;
          if (cellsBuffer[xxx][yyy] > 1 && (xx != x || yy != y))
            neighbours++;
        }
      }
      //println(neighbours+" voisins"); println();
      if (cells[x][y] > 1) {  // si vive
        if (neighbours < 2 || neighbours > 3) cells[x][y] = 1;
        else cells[x][y] = 3;
      }
      else { // si morte
        if (neighbours == 3) cells[x][y] = 2;
        else cells[x][y] = 0;
      }
    }
  }
}

void drawCells() {
  for (int x = 0; x < cellsPerRow; x++) {
    for (int y = 0; y < cellsPerCol; y++) {
      fill(cellColor[(cells[x][y])]);
      noStroke();
      rect(margin + x*(cellSize + 1), margin + y*(cellSize + 1), cellSize, cellSize);
    }
  }
}

int[] countCells(String output) {
  deadCells = dyingCells = bornCells = liveCells = 0;
  for (int x = 0; x < cellsPerRow; x++) {
    for (int y = 0; y < cellsPerCol; y++) {
      if (cells[x][y] == 0) deadCells++;
      if (cells[x][y] == 1) dyingCells++;
      if (cells[x][y] == 2) bornCells++;
      if (cells[x][y] == 3) liveCells++;
    }
  }
  if (output == "print") {
    deadCells += dyingCells;
    liveCells += bornCells;
    println(liveCells+" live cells ("+bornCells+" born)");
    println(deadCells+" dead cells ("+dyingCells+" dying)");
    println("Total: "+(liveCells+deadCells));
  }
  int[] a = {deadCells, dyingCells, bornCells, liveCells};
  return a; 
}

void drawStack() {
  int[] a = countCells("array");
  //  born
  int barYH = a[2]/(cellsPerCol*cellsPerRow)*(height - margin*2);
  fill(cellColor[2]);
  rect (width - margin - 10, height - margin,
        10, -a[2]);
  fill(cellColor[3]);
  rect (width - margin - 10, height - margin - a[2],
        10, -a[3]);
  fill(cellColor[1]);
  rect (width - margin, height - margin,
        10, -a[1]);
}

void keyPressed() {
  if (key == ' ') {
    if (run == true) {
      run = false;
      println("Pause");
    }
    else {
      run = true;
      println("Run");
    }
  }
  if (key == 'R' || key == 'r') {
    background(0);
    initializeCells();
    iterate();
    drawCells();
    drawStack();
  }
  if (key == 'c' || key == 'C') {
    countCells("print");
  }
}

For some reason, Blogger adds a </width> tag at the end of the code that should indeed be removed...

No comments:

Post a Comment