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
}
}
}
}