int maxCells = 16; boolean[][][] life = new boolean[maxCells][maxCells][2]; boolean paused = true; int step = 0; float noteDuration = 0.25f; // seconds float volume = 0.03; long lastAdvance = 0; void setup() { size(256, 256); frameRate(30); initLife(); background(0); } void draw() { background(255); noStroke(); for (int i = 0; i < life.length; i++) { for (int j = 0; j < life[i].length; j++) { fill(life[i][j][0] ? 255 : 0); pushMatrix(); translate(i*((float)width/maxCells), j*((float)height/maxCells)); rect(0, 0, (float)width/maxCells, (float)height/maxCells); popMatrix(); } } // draw grid stroke(32); for (int i = width/maxCells; i < width; i += width/maxCells) { for (int j = height/maxCells; j < height; j += height/maxCells) { line(i, 0, i, height); line(0, j, width, j); } } if (!paused) { long ms = millis(); if (ms > lastAdvance + (noteDuration*1000)) { calcNext(); printCSoundScore(); lastAdvance = millis(); } } } void calcNext() { for (int i = 0; i < life.length; i++) { for (int j = 0; j < life[i].length; j++) { int s = sumNeighbors(life, i, j); if (life[i][j][0] && (s < 2)) { life[i][j][1] = false; } else if (life[i][j][0] && (s > 3)) { life[i][j][1] = false; } else if (!life[i][j][0] && (s == 3)) { life[i][j][1] = true; } else { life[i][j][1] = life[i][j][0]; } } } for (int i = 0; i < life.length; i++) { for (int j = 0; j < life.length; j++) { life[i][j][0] = life[i][j][1]; } } step++; } void printCSoundScore() { for (int i = 0; i < life.length; i++) { for (int j = 0; j < life[i].length; j++) { if (life[i][j][0]) { println("i 1 " + (step * noteDuration) + " " + noteDuration + " " + j + " " + (800+(i*250)) + " " + volume); } } } } void keyPressed() { if (key == 'n') { paused = true; calcNext(); } else if (key == ' ') { paused = !paused; } else if (key == 'r') { initLife(); paused = true; } else if (key == 'c') { clearLife(); paused = true; } } int sumNeighbors(boolean[][][] l, int s, int t) { int total = 0; for (int i = s - 1; i <= s + 1; i++) { for (int j = t - 1; j <= t + 1; j++) { total += (l[wrap(i, l.length)][wrap(j, l.length)][0] ? 1 : 0); } } if (l[s][t][0]) { total--; } return total; } int wrap(int index, int maxIndex) { if (index >= maxIndex) { return index - maxIndex; } else if (index < 0) { return maxIndex + index; } else { return index; } } void mousePressed() { if (paused) { int cx = (int)(((float)mouseX/width) * maxCells); int cy = (int)(((float)mouseY/height) * maxCells); life[cx][cy][0] = !life[cx][cy][0]; } } void initLife() { for (int i = 0; i < life.length; i++) { for (int j = 0; j < life[i].length; j++) { if (noise(i/2f, j/2f) > 0.5 && random(1) > 0.5) { life[i][j][0] = true; } else { life[i][j][0] = false; } } } step = 0; } void clearLife() { for (int i = 0; i < life.length; i++) { for (int j = 0; j < life[i].length; j++) { life[i][j][0] = false; } } step = 0; }