//ran tao //nature of code //10.30.06 //week 7 //a basic implementation of John Conway's Game of Life CA //how could this be improved to use object oriented programming? //think of it as similar to our particle system, with a "cell" class //to describe each individual cell and a "cellular automata" class //to describe a collection of cells //edited from dan shiffman's gol code int cellsize = 15; int COLS, ROWS; //game of life board int[][] old_board, new_board, colors; void setup() { size(800, 500); smooth(); //initialize rows, columns and set-up arrays COLS = width/cellsize; ROWS = height/cellsize; old_board = new int[COLS][ROWS]; new_board = new int[COLS][ROWS]; colors = new int[COLS][ROWS]; colorMode(RGB,255,255,255,100); background(0); //call function to fill array with random values 0 or 1 initBoard(); frameRate(30); } void draw() { //background(0); fill(0,40); rectMode(CORNER); rect(0,0,width, height); grid(); check(); render(); } void grid() { for (int a=0; a<=COLS; a++) { for (int b=0; b<=ROWS; b++) { stroke(15); noFill(); rectMode(CENTER); rect(a*cellsize, b*cellsize, cellsize, cellsize); } } } void check() { Random generator = new Random(); //loop through every spot in our 2D array and check spots neighbors for (int x = 0; x < COLS;x++) { for (int y = 0; y < ROWS;y++) { int nb = 0; //Note the use of mod ("%") below to ensure that cells on the edges have "wrap-around" neighbors //above row if (old_board[(x+COLS-1) % COLS ][(y+ROWS-1) % ROWS ] == 1) { nb++; } if (old_board[ x ][(y+ROWS-1) % ROWS ] == 1) { nb++; } if (old_board[(x+1) % COLS ][(y+ROWS-1) % ROWS ] == 1) { nb++; } //middle row if (old_board[(x+COLS-1) % COLS ][ y ] == 1) { nb++; } if (old_board[(x+1) % COLS ][ y ] == 1) { nb++; } //bottom row if (old_board[(x+COLS-1) % COLS ][(y+1) % ROWS ] == 1) { nb++; } if (old_board[ x ][(y+1) % ROWS ] == 1) { nb++; } if (old_board[(x+1) % COLS ][(y+1) % ROWS ] == 1) { nb++; } float r = (float) generator.nextGaussian(); float g = (float) generator.nextGaussian(); float b = (float) generator.nextGaussian(); float w = (float) generator.nextGaussian(); //define standard deviation and mean //scale by standard deviation and mean //also constrain to between (0,255) since we are dealing with color float sd =50; float mean = 100; r = constrain((r * sd) + mean,0,255); sd = 50; mean = 200; g = constrain((g * sd) + mean,0,255); sd = 50; mean = 150; b = constrain((b * sd) + mean,0,255); sd = 50; mean = 150; w = constrain((w * sd) + mean,0,255); //RULES OF "LIFE" HERE if ((old_board[x][y] == 1) && (nb < 2)) { new_board[x][y] = 0; colors[x][y] = color(w); } //loneliness else if ((old_board[x][y] == 1) && (nb > 3)) { new_board[x][y] = 0; colors[x][y] = color(r,0,0); } //overpopulation else if ((old_board[x][y] == 0) && (nb == 3)) { new_board[x][y] = 1; colors[x][y] = color(0,0,b); } //reproduction else { new_board[x][y] = old_board[x][y]; colors[x][y] = color(0,g,0); } //stasis } } } void render() { //RENDER game of life based on "new_board" values for ( int i = 0; i < COLS;i++) { for ( int j = 0; j < ROWS;j++) { if ((new_board[i][j] == 1)) { // fill(255); fill(colors[i][j]); noStroke(); ellipse(i*cellsize,j*cellsize,cellsize,cellsize); } } } //swap old and new game of life boards int[][] tmp = old_board; old_board = new_board; new_board = tmp; } //init board with random "alive" squares void initBoard() { background(0); for (int i =0;i < COLS;i++) { for (int j =0;j < ROWS;j++) { if (int(random(5)) <= 2) { old_board[i][j] = 1; } else { old_board[i][j] = 0; } } } } void mousePressed() { if (mouseX0 && mouseY 0) { int new_x; int new_y; new_x = mouseX/cellsize; new_y = mouseY/cellsize; old_board[new_x][new_y] = 1; check(); } } //re-set board when mouse is pressed void mouseDragged() { if (mouseX0 && mouseY 0) { int new_x; int new_y; new_x = mouseX/cellsize; new_y = mouseY/cellsize; //old_board[new_x][new_y] = 1; new_board[new_x][new_y] = 1; render(); } } void keyPressed() { if (keyCode == ' ') { initBoard(); } }