/* This class describes a basic 1 dimensional Cellular Automata, controlled by a basic series of rules that determine whether the cell at a given pixel is alive or dead from generation to generation. Each generation describes a row on screen. 8 rules exists for the automata, describing how a cell should react to the state of the 3 cells in the row above. These 8 rules can be codified into 8 integers of 0 or 1 in an array. */ class Automata1D { int[] rules; int[] cells; int generation; public Automata1D( int[] r) { // we need to save the rules to start with rules = r; // setup the cells array cells = new int[width]; // startup the simulation restart(); } public Automata1D() { // set the startup rules rules = new int[8]; useRule(200); // setup the cells array cells = new int[width]; // startup the simulation restart(); } void useRule(int r) { // We want to convert the integer to it's corresponding // rule, which means the integer needs to be in the range // of 0 - 255 r = r % 256; // figure out the bits for (int i = 0; i < 8; i++) { int bitPart = r % 2; r = r / 2; rules[i] = bitPart; } } void setRules( int[] r) { rules = r; } void randomizeRules() { // generate a random rule for (int i = 0; i < 8; i++) { rules[i] = (int)random(2); } } void restart() { // clear the first generation of cells for (int i = 0; i < width; i++) { cells[i] = 0; } // turn on the center cell in the first generation cells[ width / 2] = 1; // start at the 0 generation generation = 0; } void simulate() { update(); render(); } void update() { // We want to calculate what the next generation of // cells will look like, which means we need to store // the next generation in a temporary array. We'll loop // over each cell and figure out what it will look like // in the next generation int[] nextGen = new int[cells.length]; for (int i = 1; i < (cells.length - 1); i++) { int leftCell = cells[i - 1]; int centerCell = cells[i]; int rightCell = cells[i + 1]; nextGen[i] = checkRule(leftCell, centerCell, rightCell); } // we'll copy the nextGen array back into the cells array cells = (int[])nextGen.clone(); generation++; } void render() { // draw each cell on screen at the appropriate row. color cellColor = color(0); for (int i = 0; i < width; i++) { if (cells[i] == 1) { cellColor = color(255); } else { cellColor = color(0); } set(i, generation, cellColor); } } int checkRule(int rl, int rc, int rr) { if ( rl == 1 && rc == 1 && rr == 1) return rules[7]; if ( rl == 1 && rc == 1 && rr == 0) return rules[6]; if ( rl == 1 && rc == 0 && rr == 1) return rules[5]; if ( rl == 1 && rc == 0 && rr == 0) return rules[4]; if ( rl == 0 && rc == 1 && rr == 1) return rules[3]; if ( rl == 0 && rc == 1 && rr == 0) return rules[2]; if ( rl == 0 && rc == 0 && rr == 1) return rules[1]; if ( rl == 0 && rc == 0 && rr == 0) return rules[0]; return 0; } boolean isDead() { if (generation > height) { return true; } else { return false; } } }