topical media & game development

talk show tell print

#javascript-processing-example-topic-automata-wolfram.htm / htm



  <!DOCTYPE html>
  <html><head>
  <script src="javascript-processing-example-processing.js"></script>
  <script src="javascript-processing-example-init.js"></script>
  <link rel="stylesheet" href="javascript-processing-example-style.css">
  </head><body><h1><a href="http://ejohn.org/blog/processingjs/">Processing.js</a></h1>
  <h2>Wolfram</h2>
  
  <p>by Daniel Shiffman.  
  
  Simple demonstration of a Wolfram 1-dimensional cellular automata
  When the system reaches bottom of the window, it restarts with a new ruleset
  Mouse click restarts as well.</p>
  
  <p><a href="http://processing.org/learning/topics/wolfram.html"><b>Original Processing.org Example:</b> Wolfram</a><br>
  <script type="application/processing">
  CA ca;   // An instance object to describe the Wolfram basic Cellular Automata
  
  void setup() {
    size(200,200);
    frameRate(30);
    background(0);
    int[] ruleset = {0,1,0,1,1,0,1,0};    // An initial rule system
    ca = new CA(ruleset);                 // Initialize CA
  }
  
  void draw() {
    ca.render();    // Draw the CA
    ca.generate();  // Generate the next level
    
    if (ca.finished()) {   // If we're done, clear the screen, pick a new ruleset and restart
      background(0);
      ca.randomize();
      ca.restart();
    }
  }
  
  void mousePressed() {
    background(0);
    ca.randomize();
    ca.restart();
  }
  
  class CA {
  
    int[] cells;     // An array of 0s and 1s 
    int generation;  // How many generations?
    int scl;         // How many pixels wide/high is each cell?
  
    int[] rules;     // An array to store the ruleset, for example {0,1,1,0,1,1,0,1}
  
    CA(int[] r) {
      rules = r;
      scl = 1;
      cells = new int[width/scl];
      restart();
    }
    
     CA() {
      scl = 1;
      cells = new int[width/scl];
      randomize();
      restart();
    }
    
    // Set the rules of the CA
    void setRules(int[] r) {
      rules = r;
    }
    
    // Make a random ruleset
    void randomize() {
      for (int i = 0; i < 8; i++) {
        rules[i] = int(random(2));
      }
    }
    
    // Reset to generation 0
    void restart() {
      for (int i = 0; i < cells.length; i++) {
        cells[i] = 0;
      }
      cells[cells.length/2] = 1;    // We arbitrarily start with just the middle cell having a state of "1"
      generation = 0;
    }
  
    // The process of creating the new generation
    void generate() {
      // First we create an empty array for the new values
      int[] nextgen = new int[cells.length];
      // For every spot, determine new state by examing current state, and neighbor states
      // Ignore edges that only have one neighor
      for (int i = 1; i < cells.length-1; i++) {
        int left = cells[i-1];   // Left neighbor state
        int me = cells[i];       // Current state
        int right = cells[i+1];  // Right neighbor state
        nextgen[i] = genRules(left,me,right); // Compute next generation state based on ruleset
      }
      // Copy the array into current value
      cells = (int[]) nextgen.clone();
      generation++;
    }
    
    // This is the easy part, just draw the cells, fill 255 for '1', fill 0 for '0'
    void render() {
      for (int i = 0; i < cells.length; i++) {
        if (cells[i] == 1) fill(255);
        else               fill(0);
        noStroke();
        rect(i*scl,generation*scl, scl,scl);
      }
    }
    
    // Implementing the Wolfram rules
    // Could be improved and made more concise, but here we can explicitly see what is going on for each case
    int genRules (int a, int b, int c) {
      if (a == 1 && b == 1 && c == 1) return rules[0];
      if (a == 1 && b == 1 && c == 0) return rules[1];
      if (a == 1 && b == 0 && c == 1) return rules[2];
      if (a == 1 && b == 0 && c == 0) return rules[3];
      if (a == 0 && b == 1 && c == 1) return rules[4];
      if (a == 0 && b == 1 && c == 0) return rules[5];
      if (a == 0 && b == 0 && c == 1) return rules[6];
      if (a == 0 && b == 0 && c == 0) return rules[7];
      return 0;
    }
    
    // The CA is done if it reaches the bottom of the screen
    boolean finished() {
      if (generation > height/scl) {
         return true;
      } else {
         return false;
      }
    }
  }
  </script><canvas width="200" height="200"></canvas></p>
  <div style="overflow: hidden; height: 0px; width: 0px;"></div>
  
  <pre><b>// All Examples Written by <a href="http://reas.com/">Casey Reas</a> and <a href="http://benfry.com/">Ben Fry</a>
  // unless otherwise stated.</b>
  CA ca;   // An instance object to describe the Wolfram basic Cellular Automata
  
  void setup() {
    size(200,200);
    frameRate(30);
    background(0);
    int[] ruleset = {0,1,0,1,1,0,1,0};    // An initial rule system
    ca = new CA(ruleset);                 // Initialize CA
  }
  
  void draw() {
    ca.render();    // Draw the CA
    ca.generate();  // Generate the next level
    
    if (ca.finished()) {   // If we're done, clear the screen, pick a new ruleset and restart
      background(0);
      ca.randomize();
      ca.restart();
    }
  }
  
  void mousePressed() {
    background(0);
    ca.randomize();
    ca.restart();
  }
  
  class CA {
  
    int[] cells;     // An array of 0s and 1s 
    int generation;  // How many generations?
    int scl;         // How many pixels wide/high is each cell?
  
    int[] rules;     // An array to store the ruleset, for example {0,1,1,0,1,1,0,1}
  
    CA(int[] r) {
      rules = r;
      scl = 1;
      cells = new int[width/scl];
      restart();
    }
    
     CA() {
      scl = 1;
      cells = new int[width/scl];
      randomize();
      restart();
    }
    
    // Set the rules of the CA
    void setRules(int[] r) {
      rules = r;
    }
    
    // Make a random ruleset
    void randomize() {
      for (int i = 0; i &lt; 8; i++) {
        rules[i] = int(random(2));
      }
    }
    
    // Reset to generation 0
    void restart() {
      for (int i = 0; i &lt; cells.length; i++) {
        cells[i] = 0;
      }
      cells[cells.length/2] = 1;    // We arbitrarily start with just the middle cell having a state of "1"
      generation = 0;
    }
  
    // The process of creating the new generation
    void generate() {
      // First we create an empty array for the new values
      int[] nextgen = new int[cells.length];
      // For every spot, determine new state by examing current state, and neighbor states
      // Ignore edges that only have one neighor
      for (int i = 1; i &lt; cells.length-1; i++) {
        int left = cells[i-1];   // Left neighbor state
        int me = cells[i];       // Current state
        int right = cells[i+1];  // Right neighbor state
        nextgen[i] = rules(left,me,right); // Compute next generation state based on ruleset
      }
      // Copy the array into current value
      cells = (int[]) nextgen.clone();
      generation++;
    }
    
    // This is the easy part, just draw the cells, fill 255 for '1', fill 0 for '0'
    void render() {
      for (int i = 0; i &lt; cells.length; i++) {
        if (cells[i] == 1) fill(255);
        else               fill(0);
        noStroke();
        rect(i*scl,generation*scl, scl,scl);
      }
    }
    
    // Implementing the Wolfram rules
    // Could be improved and made more concise, but here we can explicitly see what is going on for each case
    int rules (int a, int b, int c) {
      if (a == 1 &amp;&amp; b == 1 &amp;&amp; c == 1) return rules[0];
      if (a == 1 &amp;&amp; b == 1 &amp;&amp; c == 0) return rules[1];
      if (a == 1 &amp;&amp; b == 0 &amp;&amp; c == 1) return rules[2];
      if (a == 1 &amp;&amp; b == 0 &amp;&amp; c == 0) return rules[3];
      if (a == 0 &amp;&amp; b == 1 &amp;&amp; c == 1) return rules[4];
      if (a == 0 &amp;&amp; b == 1 &amp;&amp; c == 0) return rules[5];
      if (a == 0 &amp;&amp; b == 0 &amp;&amp; c == 1) return rules[6];
      if (a == 0 &amp;&amp; b == 0 &amp;&amp; c == 0) return rules[7];
      return 0;
    }
    
    // The CA is done if it reaches the bottom of the screen
    boolean finished() {
      if (generation &gt; height/scl) {
         return true;
      } else {
         return false;
      }
    }
  }</pre>
  
  </body></html>
  


(C) Æliens 20/2/2008

You may not copy or print any of this material without explicit permission of the author or the publisher. In case of other copyright issues, contact the author.