javascriptp5.jscellular-automata

Incomplete Sierpinski's Triangle Displaying


I am following the textbook The Nature of code's Example 7.1. (The original code is written in Java, but since the processing library is functionally identical to p5.js, I have rewritten it JavaScript out of convenience)

I believe that I have copied the examples code verbatim, yet somehow I have ended up with a result which I did not expect. There is an incomplete portion in the Sierpinski's triangle which is displayed.

I would like to know where I am going wrong in my code, or what I might be misunderstanding to cause this kind of issue.

Sierpinski's Triangle displays incompletely

Here's the Code for the image

class CA {
  constructor(ca_width) {
    this.generation = 0;
    this.w = 5;
    this.cells = new Array(1050 / this.w);
    this.newcells = new Array(this.cells.length);
    this.ruleset = [0, 1, 0, 1, 1, 0, 1, 0]; // [1,1,0,1,1,1,1,0]//

    for (let i = 0; i < this.cells.length; i++) {
      this.cells[i] = 0;
    }

    this.cells[this.cells.length / 2] = 1;
  }


  generate() {
    let nextgen = new Array(this.cells.length);
    for (let i = 1; i < this.cells.length - 1; i++) {
      let left = this.cells[i - 1];
      let me = this.cells[i];
      let right = this.cells[i + 1];
      nextgen[i] = this.rules(left, me, right);
    }
    this.cells = nextgen;
    this.generation++;
  }

  rules(a, b, c) {
    let s = "" + a + b + c;
    let index = parseInt(s, 2);
    return this.ruleset[index];
  }

  display() {
    for (let i = 0; i < this.cells.length; i++) {
      if (this.cells[i] == 0)
        fill(255);
      else fill(0);
      stroke(0);
      rect(i * this.w, this.generation * this.w,
        this.w, this.w);
    }
  }
}

let cA;

function setup() {
  createCanvas(windowWidth, windowHeight);
  cA = new CA(1000);
}

function draw() {
  // createCanvas(windowWidth, 400);
  // background(150);

  cA.display();
  cA.generate();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.1/p5.js"></script>


Solution

  • Based on your logic for computing the next generation, this.cells[0] and this.cells.at(-1) are always undefined, which is rendered as black. You might want to initialize these to 0, and possibly use a wraparound logic for computing their value (i.e. cells[0] = rule(cells.at(-1), cells[0], cells[1])).

    I don't know what your Java code looks like, but if you're using a new int[] type, then that'll be zeroed out and probably work as expected, unlike JS Array().

    In general, use caution with the Array() constructor in JS. It leaves the cells in an uninitialized state ("empty slots"), so you usually want to chain .fill(0) or spread/map it to make it a usable, unsurprising array that you'd expect such a constructor to emit, as it does in Java.

    Keep in mind that the Nature of Code is available in a p5.js version, and there exist automatic translators from Processing to p5.js, like pde2js. Note that I haven't tried pde2js or the other translators but they seem worth a look.