how to control a cellular automata iteration

edited March 2015 in How To...

I'm trying to add a slider (controlP5) to control a cellular automata iteration. Let me try to explain it better: slider value is 3, so I want that are generated 3 rows; slider value is 76, 76 rows and so on. For example, in this example from The Nature of Code of Daniel Shiffman, how can I control the integer calls generation through a slider??thanksss

CA ca;   // An object to describe a Wolfram elementary Cellular Automata

int delay = 0;

void setup() {
  size(800, 200);
  background(255);
  int[] ruleset = {
    0, 1, 0, 1, 1, 0, 1, 0
  };    // An initial rule system
  ca = new CA(ruleset);                 // Initialize CA
  frameRate(30);
}

void draw() {
  ca.display();          // Draw the CA
  ca.generate();

  if (ca.finished()) {   // If we're done, clear the screen, pick a new ruleset and restart
    delay++;
    if (delay > 30) {
      background(255);
      ca.randomize();
      ca.restart();
      delay = 0;
    }
  }
}

void mousePressed() {
  background(255);
  ca.randomize();
  ca.restart();
}
// A class to manage the CA

class CA {

  int[] cells;     // An array of 0s and 1s 
  int generation;  // How many generations?

  int[] ruleset;     // An array to store the ruleset, for example {0,1,1,0,1,1,0,1}

  int w = 5;

  CA(int[] r) {
    ruleset = r;
    cells = new int[width/w];
    restart();
  }

  // Make a random ruleset
  void randomize() {
    for (int i = 0; i < 8; i++) {
      ruleset[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] = rules(left, me, right); // Compute next generation state based on ruleset
    }
    // The current generation is the new generation
    cells = nextgen;
    generation++;
  }

  // This is the easy part, just draw the cells, fill 255 for '1', fill 0 for '0'
  void display() {
    for (int i = 0; i < cells.length; i++) {
      if (cells[i] == 1) fill(0);
      else               fill(255);
      noStroke();
      rect(i*w, generation*w, w, w);
    }
  }

  // Implementing the Wolfram rules
  // This is the concise conversion to binary way
  /*int rules (int a, int b, int c) {
   String s = "" + a + b + c;
   int index = Integer.parseInt(s, 2);
   return ruleset[index];
   }*/
  // For JavaScript Mode
  int rules (int a, int b, int c) {
    if (a == 1 && b == 1 && c == 1) return ruleset[0];
    if (a == 1 && b == 1 && c == 0) return ruleset[1];
    if (a == 1 && b == 0 && c == 1) return ruleset[2];
    if (a == 1 && b == 0 && c == 0) return ruleset[3];
    if (a == 0 && b == 1 && c == 1) return ruleset[4];
    if (a == 0 && b == 1 && c == 0) return ruleset[5];
    if (a == 0 && b == 0 && c == 1) return ruleset[6];
    if (a == 0 && b == 0 && c == 0) return ruleset[7];
    return 0;
  }

  // The CA is done if it reaches the bottom of the screen
  boolean finished() {
    if (generation > height/w) {
      return true;
    } 
    else {
      return false;
    }
  }
}

Answers

  • Break your problem down into smaller individual steps. Can you create a standalone example sketch that just prints out the value of a slider? Can you create another standalone example sketch that shows a cellular automata that uses hard-coded values for its width and height?

    When you get each step working separately, then worry about combining them. And when you get stuck, post an MCVE of the specific step you're stuck on, and we'll go from there.

  • edited March 2015

    I know what you mean...but I posted this example because my code is more complicated than this...my problem is that i can't understand how I can print out from a slider a continuous value, from 0 to 40 and not just a number... I want 0,1,2,3,4,5,6,7,8,9,10 and not 0,10,36,2,4,20.

  • Then please post an MCVE of just your slider code, and we'll go from there.

  • import controlP5.*;
    
    ControlP5 cp5;
    
    int scl;         
    int generation; 
    int sliderValue;
    
    void setup() {
      size(400, 400);
      background(0);
      frameRate(15);
      cp5 = new ControlP5(this);
      scl = 5;
      generation = 0;
    
      cp5.addSlider("sliderValue")
        .setPosition(220, 360)
          .setRange(0, height/scl)
            .setValue(0)
              ;
    }
    
    void draw() {
      generation++;
      for (int i = 0; i < height; i++) {
        fill(random(255));
        noStroke();
        // rect(i*scl, generation*scl, scl, scl);
        rect(i*scl, sliderValue*scl, scl, scl);
      }
    }
  • Take a look at the documentation for the Slider class: http://www.sojamo.de/libraries/controlP5/reference/controlP5/Slider.html

    There are several methods in there you might want to try. What happens when you call snapToTickMarks(false)?

  • edited March 2015
    import controlP5.*;
    
    ControlP5 cp5;
    
    int scl;         
    int sliderTicks = 30;
    
    void setup() {
      size(400, 400);
      background(0);
      cp5 = new ControlP5(this);
      scl = 5;
    
      cp5.addSlider("sliderTicks")
         .setRange(0,height/scl)
         .setValue(0)
         .setPosition(80,370)
         .setSize(200,10)
         .setNumberOfTickMarks(height/scl)
         .setSliderMode(Slider.FLEXIBLE);
    }
    
    void draw() {
      for (int i = 0; i < height; i++) {
        fill(random(255));
        noStroke();
        rect(i*scl, sliderTicks*scl, scl, scl);
      }
    }
  • edited March 2015

    with .setNumberOfTickMarks(height/scl) is better...and now how to force it to pass on any value?how to delete the previous values? thank you for your time!you are very kind!

  • other tips??

Sign In or Register to comment.