// Conway's Game of Life - Teaching 2D Arrays
//
// processing version
// see: http://www.16kb.com/portfolio/display/automata/
import controlP5.*;
ControlP5 controlP5;
int playerScale = 10; // factor to magnify grid
int cols = 80; // number of cols in world
int rows = 55; // number of rows
int[][] world = new int[cols][rows]; // initialize 2D array that will house the game
int aliveFill = 128;
int backgroundFill = 0;
int systemReset = 0;
Knob speedKnob;
void setup() {
size(800,600);
smooth();
frameRate(10);
background(0);
translate(5,5); // shifts everything to the right and down
controlP5 = new ControlP5(this);
controlP5.addButton("reset",10,-5,560,80,20).setId(1);
speedKnob = controlP5.addKnob("speed",1,30,10,100,560,20);
randomizeBoard();
}
void draw () {
translate(5,5);
if (systemReset == 1) {
systemReset = 0;
randomizeBoard();
}
// check each cell
int num;
for (int x=0; x < cols; x++) { // loop through every column
for (int y=0; y < rows; y++) { // loop through every row
num = checkNeighbours(x,y);
if (world[x][y] == 0 && num == 3) { // bring cell to life
world[x][y] = 8; // 0 = dead, 8 dead, but alive next
drawCell(x, y, 1);
}
if ( world[x][y] == 1 && (num < 2 || num > 3) ) { // kill cell
world[x][y] = -1; // 1 = alive, -1 = alive, but dead next round
drawCell(x, y, 0);
}
}
}
// set all changing state codes (ie. -1 and 8)
for (int x=0; x < cols; x++) { // loop through every column
for (int y=0; y < rows; y++) { // loop through every row
if (world[x][y] == 8)
world[x][y] = 1;
if (world[x][y] == -1)
world[x][y] = 0;
}
}
} // end of draw
void reset(float theValue) {
println("a button event. "+theValue);
systemReset =1;
}
// draw a cell
void drawCell(int x, int y, int alive) {
if (alive == 1) {
fill(aliveFill);
ellipse(x*playerScale, y*playerScale, 8, 8);
} else {
fill(backgroundFill);
noSmooth();
ellipse(x*playerScale, y*playerScale, 8, 8);
smooth();
}
}
// check how neighbours a position has
int checkNeighbours(int x, int y) {
int neighbours = 0;
for (int dx=-1; dx<=1; dx++) {
for (int dy=-1; dy<=1; dy++) {
if (dy==0 && dx==0) // skip checking ourselves
continue;
if ((x+dx >= 0 && x+dx < cols) && (y+dy >= 0 && y+dy < rows) && (world[x+dx][y+dy] == 1 || world[x+dx][y+dy] == -1) ) {
neighbours++;
}
}
}
return neighbours;
}
void randomizeBoard() {
for (int x=0; x < cols; x++) { // loop through every column
for (int y=0; y < rows; y++) { // loop through every row
world[x][y] = int(random(2)); // place a 0 or 1 into the world
if (world[x][y] == 1) {
drawCell(x, y, 1); // if world holds a 1 then draw a circle
} else {
drawCell(x, y, 0); // if world holds a 1 then draw a circle
}
}
}
}
void speed(int value) {
frameRate(value);
}