title: How do I randomly group together adjacent cells in a 2 dimensional array in JavaScript?
body: <p>I am making a <a href="https://en.wikipedia.org/wiki/KenKen" rel="nofollow noreferrer">KenKen</a> generator in JavaScript. For this, I need to create a Latin square with "cages" that will later have operands in them. I have been following some guidance from <a href="http://www.geometer.org/mathcircles/kenken.pdf" rel="nofollow noreferrer">a paper by Tom Davis</a>, and he describes how to create the cages (9.4, page 21):</p>
  
  <blockquote>
    <p>First, [my algorithm] generates a random Latin square. It then generates cages by randomly picking adjacent squares and combining them into cages with some restrictions.</p>
  </blockquote>
  
  <p>I already have the code to generate a random Latin square, but I seem to be stumped on how to combine adjacent cells. I tried something myself, as you can see below, but the more I wrote, the less sure I felt and the messier and more unmaintainable the code became. </p>
  
  <p>My question is, how do I do this efficiently?</p>
  
  <pre><code>/**
   * Create the cages for operations to go in
   */
  createCages(){
    var cages = []; // list of all cages
  
    // keep track of what cells are in what cages 
    // (the contents of this will be changed later, we just clone the grid so it has the same structure)
    var cagesByCell = this.clone(this.grid); 
  
    // every cell starts out as its own cage
    for (let y = 0; y &lt; this.size; y++){
      for (let x = 0; x &lt; this.size; x++){
        let newCage = [[y,x]];
        cages.push(newCage);
        cagesByCell[y][x] = newCage;
      }
    }
  
    // 
    let cells = this.getCellPositions();
    for (let i = 0; i &lt; this.size; i++){
      // get random cell
      let cell = cells[i];
      let y = cell[0];
      let x = cell[1];
  
      // pick a random adjacent neighor to that cell
      let other;
      while (other == undefined){
        let neighor = Math.floor(Math.random()*4)
        switch (neighor){
          case 0: if (y &gt; 0)           {other = [y-1, x]} break; // NORTH
          case 1: if (x &lt; this.size-1) {other = [y, x+1]} break; // EAST
          case 2: if (y &lt; this.size-1) {other = [y+1, x]} break; // SOUTH
          case 3: if (x &gt; 0)           {other = [y, x-1]} break; // WEST
        }
      }
      let y1 = other[0];
      let x1 = other[1];
  
      // merge their cages
      let cageNum = cages.indexOf(cagesByCell[y][x]);
      let cageNum1 = cages.indexOf(cagesByCell[y1][x1]);
      let cage = cages[cageNum];
      let cage1 = cages[cageNum1];
      for (let i = 0; i &lt; cage1.length; i++){
        cage.push(cage1[i])
      }
  
      cages.splice(cageNum1, 1);
    }
    console.log(cages)
  }
  </code></pre>