/* built with Studio Sketchpad:
* https://sketchpad.cc
*
* observe the evolution of this sketch:
* https://studio.sketchpad.cc/sp/pad/view/ro.SfVsIFyZeST/rev.3425
*
* authors:
* Ruben Nijveld
* license (unless otherwise specified):
* creative commons attribution-share alike 3.0 license.
* https://creativecommons.org/licenses/by-sa/3.0/
*/
// Press space or p to start the simulation, press space or p again to pause
// Use the mouse to activate cells (you can click + drag to activate more)
// Rules: http://en.wikipedia.org/wiki/Conway's_Game_of_Life
int CELLS_X = 40;
int CELLS_Y = 40;
int CELL_X_SIZE;
int CELL_Y_SIZE;
boolean isPause;
boolean changed;
int frame;
int PROCESS_EVERY = 4;
int prevMouseX;
int prevMouseY;
CellList cells;
void setup() {
// settings for processing
background(255);
size(400, 400);
frameRate(60);
rectMode(CORNER);
strokeWeight(1);
strokeCap(PROJECT);
strokeJoin(MITER);
// game settings and variables
CELL_X_SIZE = round(width / CELLS_X);
CELL_Y_SIZE = round(height / CELLS_Y);
cells = new CellList();
isPause = true;
changed = true;
frame = 0;
}
void draw() {
if(frame >= PROCESS_EVERY) {
frame = 0;
}
if(!isPause && frame == 0) {
cells.update();
}
if(changed || frame == 0) {
cells.draw();
changed = false;
}
if(mousePressed && (mouseX != prevMouseX || mouseY != prevMouseY)) {
cells.getcell(
floor(mouseX / CELL_X_SIZE),
floor(mouseY / CELL_Y_SIZE)
).alive = true;
}
frame += 1;
}
void mousePressed() {
prevMouseX = mouseX;
prevMouseY = mouseY;
}
void mouseClicked() {
if(prevMouseX == mouseX && prevMouseY == mouseY) {
cells.getcell(
floor(mouseX / CELL_X_SIZE),
floor(mouseY / CELL_Y_SIZE)
).toggle();
changed = true;
}
}
void keyPressed() {
if(key == 'p' || key == 'P' || key == ' ') {
isPause = !isPause;
changed = true;
}
}
class Cell {
int cellX;
int cellY;
boolean alive;
int livingNb;
Cell(int x, int y) {
cellX = x;
cellY = y;
alive = false;
livingNb = 0;
}
void toggle() {
alive = !alive;
}
void sweep() {
livingNb = 0;
for(int xPos = -1; xPos <= 1; xPos++) {
for(int yPos = -1; yPos <= 1; yPos++) {
if(xPos == 0 && yPos == 0) {
continue;
}
if(cells.isAlive(cellX+xPos, cellY+yPos)) {
livingNb += 1;
}
}
}
}
void update() {
if(!alive && livingNb == 3) {
alive = true;
} else if(alive && (livingNb < 2 || livingNb > 3)) {
alive = false;
}
}
void draw() {
if(isPause) {
stroke(0);
} else {
stroke(75);
}
if(alive) {
fill(255, 255, 0);
} else {
fill(40);
}
rect(
cellX * CELL_X_SIZE,
cellY * CELL_Y_SIZE,
CELL_X_SIZE,
CELL_Y_SIZE
);
}
}
class CellList {
Cell[] cells;
CellList() {
cells = new Cell[CELLS_X * CELLS_Y];
for(int currX = 0; currX < CELLS_X; currX++) {
for(int currY = 0; currY < CELLS_Y; currY++) {
cells[currX + CELLS_Y * currY] = new Cell(currX, currY);
}
}
}
void getcell(int xPos, int yPos) {
return this.cells[xPos + CELLS_Y * yPos];
}
void isAlive(int xPos, int yPos) {
if(xPos < 0 || yPos < 0) {
return false;
}
if(xPos >= CELLS_X || yPos >= CELLS_Y) {
return false;
}
return this.cells[xPos + CELLS_Y * yPos].alive;
}
void update() {
for(int i = 0; i < CELLS_X * CELLS_Y; i++) {
this.cells[i].sweep();
}
for(int i = 0; i < CELLS_X * CELLS_Y; i++) {
this.cells[i].update();
}
}
void draw() {
for(int i = 0; i < CELLS_X * CELLS_Y; i++) {
this.cells[i].draw();
}
}
}