//conwayice2 - kirk israel, http://kisrael.com/ //generations of Conwy's game of life plotted in 3D //click to reset; the higher the click, the denser the initial population //camera follows the mouse, if left idle, starts rotating on its own //core life code loving ripped from Mike Davis: // http://processing.org/learning/examples/cellularautomata1.html // (but my version is better commented ;-) // 2nd version is a hack: // now world boundaries don't wrap // plus it reads some setup from params... float SIZE=800; int sx, sy; float density = 0.15; int[][][] world; int[][][] worldhistory; int historylength = 32; int worldsize=32; float r = 0; int bs = 6; float oldmx, oldmy; int counter = 500; int spinpatience = 100; float rY,rZ; int zoom = 0; int basezoom = 0; String msg = null; //re-initialize arrays, randomy populate, and run all the generations void reset(){ zoom = basezoom; world = new int[sx][sy][2]; worldhistory = new int[sx][sy][historylength]; //randomly populate parseStart(param("seed")); for(int i = 0 ; i < historylength; i++){ dogen(i); } } void parseStart(String s){ if(s == null || "".equals(s)){ for (int i = 0; i < sx * sy * density; i++) { world[(int)random(sx)][(int)random(sy)][1] = 1; } } else { try{ s = s.substring(1); String pairs[] = s.split("\\+"); for(int i = 0; i < pairs.length; i++){ String xy[] = pairs[i].split(","); int x = Integer.parseInt(xy[0]); int y = Integer.parseInt(xy[1]); if (x < sx && y < sx){ world[x][y][1] = 1; } else { msg += "x of "+x+" y of "+y+" out of range"; } } } catch(Exception e){ msg += "ERROROR PARSING '"+s+"'" ; } } } int doInt(String s, int d){ String v = param(s); if(v == null) return d; try{ return Integer.parseInt(v); } catch(NumberFormatException e){ msg += "can't parse '"+s+"' of '"+v+"'!\n"; return d; } } void setup() { msg=param("msg"); if(msg == null) { msg = ""; } worldsize=doInt("worldsize",32); historylength=doInt("historysize",32); basezoom= doInt("zoomout",0); background(128); size(800,800,P3D); rectMode(CENTER); frameRate(20); sx =worldsize; sy = worldsize; reset(); oldmx = mouseX; oldmy = mouseY; textFont(loadFont("ArialNarrow-24.vlw")); } void draw(){ background(128); if(mousePressed){ zoom+=10; } else { if(zoom > basezoom){ zoom-=10; } } stroke(255); fill(255); text(msg,50,50); //blue, plus an alpha value for opacity etc... fill(32,32,128,30); //fill(200,200,255,40); noStroke(); //move to roughly middle of screen translate(width/2,height/2,zoom); //if they've moved the mouse, readjust the rotation //and reset the mouse watching and counter if(oldmx != mouseX || oldmy != mouseY){ rY = (mouseX)/200.0; rZ = (400.0-mouseY)/400.0; oldmx = mouseX; oldmy = mouseY; counter = 0; } else { counter++; //if its been a while since they've moved the mouse, //rotate it automagically if(counter > spinpatience){ rY += .02; } } rotateY(rY); rotateZ(rZ); r += .01; for(int gen = 0; gen 0 && y > 0){ count += world[x-1][y-1][0]; } if(y > 0){ count += world[x][y-1][0]; } if(x < sx-1 && y > 0){ count += world[x+1][y-1][0]; } if(x > 0){ count += world[x-1][y][0]; } if(x < sx-1){ count += world[x+1][y][0]; } if(x > 0 && y < sy-1){ count += world[x-1][y+1][0]; } if(y < sy-1){ count += world[x][y+1][0]; } if(x < sx-1 && y < sy-1){ count += world[x+1][y+1][0]; } return count; } void dogen(int historyptr) { for (int x = 0; x < sx; x=x+1) { for (int y = 0; y < sy; y=y+1) { //if cell TOBE born, or cell NOWIS alive and TOBO no change... if ((world[x][y][1] == 1)|| (world[x][y][0] == 1 && world[x][y][1] == 0) ) { //NOWIS ALIVE world[x][y][0] = 1; worldhistory[x][y][historyptr] = 1; } else { worldhistory[x][y][historyptr] = 0; } //if cell TOBE killed if (world[x][y][1] == -1) { //NOWIS dead world[x][y][0] = 0; } //TOBE nochange... world[x][y][1] = 0; } } // Birth and death cycle for (int x = 0; x < sx; x=x+1) { for (int y = 0; y < sy; y=y+1) { int count = neighbors(x, y); //if 3 neighbors and NOWIS dead... if (count == 3 && world[x][y][0] == 0) { //TOBE born world[x][y][1] = 1; } //if too few, too many neighbors and NOWIS alive if ((count < 2 || count > 3) && world[x][y][0] == 1) { //TOBE killed world[x][y][1] = -1; } } } }