Code viewer for World: Binary tree
class Node {
  /** @param {number} value */
  constructor(head) {
    this.value = head;
    this.left = null;
    this.right = null;
  }
  /** @returns {number} */
  height() {
    if (this.left === null && this.right === null) {
      return 1;
    }
    if (this.left === null) {
      return height(this.right);
    }
    if (this.right === null) {
      return height(this.left);
    }
    return max(height(this.left), height(this.right));
  }
  // Apply closure to each item inorder transversal
  inorder(closure) {
    if (this.left === null && this.right === null) {
      closure(this);
      return;
    }
    if (this.left !== null) {
      this.left.inorder(closure);
    }
    closure(this);
    if (this.right !== null) {
      this.right.inorder(closure);
    }
  }
}

class Tree {
  /** @param {Node} value */
  constructor(head) {
    this.head = head;
  }
  /** @returns {number} */
  height() {
    return this.head.height();
  }
  /**
   * @param {number} startX
   * @param {number} startY
   */
  render(startX, startY) {
    const h = this.height();
    const q = [this.head];
    const d = 0;
    
    while (q.length > 0) {
      const rOffset = ((h - d) * 50)
      const lOffset = -rOffset;
      const curr = q.shift();
      
      if (curr === null) continue;

      ellipse(currX, currY, 50, 50);
      d += 1;
    }
  }
  /** @param {Node} node */
  insert(node) {
    let found = false;
    let iterNode = this.head;
    while (!found) {
      if (node.value >= iterNode.value) {
        if (iterNode.right === null) {
          iterNode.right = node;
          found = true;
          continue;
        }
        iterNode = iterNode.right;
      } else {
        if (iterNode.left === null) {
          iterNode.left = node;
          found = true;
          continue;
        }
        iterNode = iterNode.left;
      }
    }
  }
  /** @param {object} a */
  addItems(a) {
    for (let value of a) {
      this.insert(new Node(value));
    }
  }

  print() {
    this.head.inorder((node) => console.log(node.value));
  }
}

	
	AB.world.newRun = function()
	{
 		// Code to execute once at the start.  
		// Should call:
		//		ABWorld.init (  COLOR  );
		ABWorld.init(0xf1f1f1);
	};

	AB.world.nextStep = function()		 
	{
		// Code to execute every step. 
		// Can put P5 instructions to be executed every step here, or in draw()
		fill(125, 0, 0);
		let centerX = ABWorld.canvas.offsetWidth / 2;
		let centerY = ABWorld.canvas.offsetHeight / 2;
		ellipse(centerX, centerY, 80, 80);
 	};


	AB.world.endRun = function()
	{
	};




//---- setup -------------------------------------------------------
// Do NOT make a setup function.
// This is done for you in the API. The API setup just creates a canvas.
// Anything else you want to run at the start should go into the following two functions.


function beforesetup()      // Optional 
{
	// Anything you want to run at the start BEFORE the canvas is created 
}


function aftersetup()       // Optional
{
	// Anything you want to run at the start AFTER the canvas is created 
}


//---- draw -------------------------------------------------------

function draw()             // Optional
{
	// Can put P5 instructions to be executed every step here, or in AB.world.nextStep()  
}