Screen Shot 2019-12-20 at 1.37.00 AM.png

Processing

Part I

The first attempt is testing out whether the grid size affects the game duration. Therefore I make changes to grid size and modify two grid groups: 1. 1920 x 1080 2. 800 x 800. Make the game duration for grid group 1 is 04:02 and grid group 2 is 02:02. The grid size affects the game duration.

Part II

The second part is to create my own rule for Game of Life.

Adjacency Rules

  • Gave takes less than two slices of pizza for dinner, he will starve for the night

  • Gave takes two or three slices of pizza, it’s just enough for him

  • Gave takes more than three slices of pizza, he will have a hard time to digest

  • When Gave is starving and cannot move, he eats three slices of pizza and gains energy

Part III

The second part is to use data as a design material. A video file is used in the processing code .

The cell size is modified to be smaller from 20 to 10, which makes the video more clear to watch. The second modification is adding a filter to the video, it appears as paints spread on the canvas.

Code:

/**

* A Processing implementation of Game of Life

* By Joan Soler-Adillon

*

* Press SPACE BAR to pause and change the cell's values with the mouse

* On pause, click to activate/deactivate cells

* Press R to randomly reset the cells' grid

* Press C to clear the cells' grid

*

* The original Game of Life was created by John Conway in 1970.

*/

// Special thanks to the processging community and p5.js community for their work, software and community!

//this has been modified by Lee Cody and Christine Meinders from the game of life sketch and video loop files from processing examples.

/**

* Loop.

*

* Shows how to load and play a QuickTime movie file.

// CMD K

*

*/

import processing.video.*;

Movie movie;

// Size of cells

int cellSize = 2;

// How likely for a cell to be alive at start (in percentage)

float probabilityOfAliveAtStart = 15;

// Variables for timer

int interval = 100;

int lastRecordedTime = 0;

// Colors for active/inactive cells

color alive = color(225);

color dead = color(100);

// Array of cells

int[][] cells;

// Buffer to record the state of the cells and use this while changing the others in the interations

int[][] cellsBuffer;

// Pause

boolean pause = false;

//importing image into graphics (so you can draw and have transpaecny)

PGraphics drawLayer;

void setup() {

size(1280, 750);

background(0);

// Load and play the video in a loop

movie = new Movie(this, "transit.mov");

movie.loop();

// Instantiate arrays

cells = new int[width/cellSize][height/cellSize];

cellsBuffer = new int[width/cellSize][height/cellSize];

// This stroke will draw the background grid

stroke(48);

noSmooth();

// Initialization of cells; random number

for (int x=0; x<width/cellSize; x++) {

for (int y=0; y<height/cellSize; y++) {

float state = random (100);

if (state > probabilityOfAliveAtStart) {

state = 0;

}

else {

state = 1;

}

cells[x][y] = int(state); // Save state of each cell

}

}

background(0);

drawLayer = createGraphics(width, height);

}

void movieEvent(Movie m) {

m.read();

}

void draw() {

//if (movie.available() == true) {

// movie.read();

//}

runGOL();

drawLayer.beginDraw();

for(int x=0; x< width;x++){

for(int y=0; y< height;y++){

color c = movie.get(x, y);

if(brightness(get(x, y)) > 150){

drawLayer.set(x, y, c);

}

}

}

// CHANGE THESE LINES TO PLAY WITH THE DESIGN

//drawLayer.filter(BLUR, 6);

//drawLayer.filter(ERODE);

drawLayer.filter(DILATE);

//filter(THRESHOLD);

filter(POSTERIZE, 4);

textureMode(NORMAL);

drawLayer.endDraw();

background(0);

image(movie, 0, 0);

image(drawLayer, 0, 0);

}

void runGOL(){

//Draw grid

noStroke();

for (int x=0; x<width/cellSize; x++) {

for (int y=0; y<height/cellSize; y++) {

if (cells[x][y]==1) {

fill(alive); // If alive

}

else {

fill(dead); // If dead

}

rect (x*cellSize, y*cellSize, cellSize, cellSize);

}

}

// Iterate if timer ticks

if (millis()-lastRecordedTime>interval) {

if (!pause) {

iteration();

lastRecordedTime = millis();

}

}

// Create new cells manually on pause

if (pause && mousePressed) {

// Map and avoid out of bound errors

int xCellOver = int(map(mouseX, 0, width, 0, width/cellSize));

xCellOver = constrain(xCellOver, 0, width/cellSize-1);

int yCellOver = int(map(mouseY, 0, height, 0, height/cellSize));

yCellOver = constrain(yCellOver, 0, height/cellSize-1);

// Check against cells in buffer

if (cellsBuffer[xCellOver][yCellOver]==1) { // Cell is alive

cells[xCellOver][yCellOver]=0; // Kill

fill(dead); // Fill with kill color

}

else { // Cell is dead

cells[xCellOver][yCellOver]=1; // Make alive

fill(alive); // Fill alive color

}

}

else if (pause && !mousePressed) { // And then save to buffer once mouse goes up

// Save cells to buffer (so we opeate with one array keeping the other intact)

for (int x=0; x<width/cellSize; x++) {

for (int y=0; y<height/cellSize; y++) {

cellsBuffer[x][y] = cells[x][y];

}

}

}

}

void iteration() { // When the clock ticks

// Save cells to buffer (so we opeate with one array keeping the other intact)

for (int x=0; x<width/cellSize; x++) {

for (int y=0; y<height/cellSize; y++) {

cellsBuffer[x][y] = cells[x][y];

}

}

// Visit each cell:

for (int x=0; x<width/cellSize; x++) {

for (int y=0; y<height/cellSize; y++) {

// And visit all the neighbours of each cell

int neighbours = 0; // We'll count the neighbours

for (int xx=x-1; xx<=x+1;xx++) {

for (int yy=y-1; yy<=y+1;yy++) {

if (((xx>=0)&&(xx<width/cellSize))&&((yy>=0)&&(yy<height/cellSize))) { // Make sure you are not out of bounds

if (!((xx==x)&&(yy==y))) { // Make sure to to check against self

if (cellsBuffer[xx][yy]==1){

neighbours ++; // Check alive neighbours and count them

}

} // End of if

} // End of if

} // End of yy loop

} //End of xx loop

// We've checked the neigbours: apply rules!

if (cellsBuffer[x][y]==1) { // The cell is alive: kill it if necessary

if (neighbours < 2 || neighbours > 3) {

cells[x][y] = 0; // Die unless it has 2 or 3 neighbours

}

}

else { // The cell is dead: make it live if necessary

if (neighbours == 3 ) {

cells[x][y] = 1; // Only if it has 3 neighbours

}

} // End of if

} // End of y loop

} // End of x loop

} // End of function

void keyPressed() {

if (key=='r' || key == 'R') {

// Restart: reinitialization of cells

for (int x=0; x<width/cellSize; x++) {

for (int y=0; y<height/cellSize; y++) {

float state = random (100);

if (state > probabilityOfAliveAtStart) {

state = 0;

}

else {

state = 1;

}

cells[x][y] = int(state); // Save state of each cell

}

}

}

if (key==' ') { // On/off of pause

pause = !pause;

}

if (key=='c' || key == 'C') { // Clear all

for (int x=0; x<width/cellSize; x++) {

for (int y=0; y<height/cellSize; y++) {

cells[x][y] = 0; // Save all to zero

}

}

}

}