Code viewer for World: Variant of the Game of Life

// Cloned by Lacraft on 10 Jul 2018 from World "The Game of Life" by Mathias Bazin 
// Please leave this clone trail here.
 


// Cloned by Mathias Bazin on 9 Jul 2018 from World "Cloned The Game of Life bugs" by test  
// Please leave this clone trail here.
 


// Cloned by Mark test  on 6 Jul 2018 from World "The Game of Life bugs" by Mathias Bazin 
// Please leave this clone trail here.
 
// Daniel Shiffman
// http://codingtra.in
// http://patreon.com/codingtrain

// Game of Life
// Video: https://youtu.be/FWSR_7kZuYg

AB.drawRunControls = false;
AB.screenshotStep  = 300;   

let grid;
let cols;
let rows;
let resolution = 10;
let play = false;


function make2DArray(cols, rows) {
  let arr = new Array(cols);
  for (let i = 0; i < arr.length; i++) {
    arr[i] = new Array(rows);
  }
  return arr;
}


function countNeighbors(grid, x, y) {
  let sum = 0;
  for (let i = -1; i < 2; i++) {
    for (let j = -1; j < 2; j++) {
      let col = (x + i + cols) % cols;
      let row = (y + j + rows) % rows;
      sum += grid[col][row];
    }
  }
  sum -= grid[x][y];
  return sum;
}

function rowNeighbors(grid, x, y, length) {
  if (x === 0)
    return grid[x+1][y];
  else if (x == cols-1)
    return grid[x-1][y];
  else 
    return grid[x-1][y] + grid[x+1][y];
}




function World() 
{ 
    
    


	
	this.newRun = function()
	{
 		threeworld.init (  "black"  ); 
 		
 			
	};


	this.nextStep = function()		 
	{


 	};


	this.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 
	
	$("#user_span1").html("<button id=play>Play</button> <button id=clear>Clear</button>" /*Speed : <input id='speed' type='number' value='60'>"*/ );
	
	$("#play").on("click", function(){
	    play = !play;
	    if(play)
	    {
	        $("#play").html("Pause");
	    }
	    else
	    {
	        $("#play").html("Play");
	    }
	});
	
	$("#clear").on("click", function(){
	     for (let i = 0; i < cols; i++) {
            for (let j = 0; j < rows; j++) {
                grid[i][j] = 0;
            }
        }
	});
	
// 	$("#speed").on("change", function(){  
// 	    let fps = this.value;
// 	    frameRate(fps);
//         console.log(fps, frameRate());

// 	});

}


function aftersetup()       // Optional
{
	// Anything you want to run at the start AFTER the canvas is created 
	
		
        cols = floor ( threeworld.canvas.width / resolution );
        rows = floor ( threeworld.canvas.height / resolution );
    
    console.log ( cols + " " + rows );
    
        grid = make2DArray(cols, rows);
        for (let i = 0; i < cols; i++) {
            for (let j = 0; j < rows; j++) {
                grid[i][j] = 0;
            }
        }
    
}


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

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

  		// Code to execute every step. 
		// Can put P5 instructions to be executed every step here, or in draw() 
        
        
    	background(0);
    
          for (let i = 0; i < cols; i++) {
            for (let j = 0; j < rows; j++) {
              let x = i * resolution;
              let y = j * resolution;
              if (grid[i][j] == 1) {
                fill(255);
                stroke(0);
                rect(x, y, resolution - 1, resolution - 1);
              }
            }
          }
          
    if(play)
	{
        
          let next = make2DArray(cols, rows);
        
          // Compute next based on grid
          for (let i = 0; i < cols; i++) {
            for (let j = 0; j < rows; j++) {
              let state = grid[i][j];
              // Count live neighbors!
              let sum = 0;
              let rowNeighb = rowNeighbors(grid, i, j);
              if(state === 1 && rowNeighb === 0){
                  next[i][j] = 0;
              }
              else if(state === 0 && rowNeighb === 1){
                  if(j === 0){
                    next[i][j+1] = 1;
                    next[i][rows-1] = 1;
                  }
                  else if(j == rows-1){
                    next[i][0] = 1;
                    next[i][j-1] = 1;
                  }
                  else{
                    next[i][j+1] = 1;
                    next[i][j-1] = 1;
                  }
              }
              else if(state === 0 && rowNeighb === 2){
                  if(i === 0){
                      if(j === 0){
                          next[i+1][j+1] = 1;
                          next[cols-1][rows-1] = 1;
                          next[cols-1][j+1] = 1;
                          next[i+1][rows-1] = 1;
                      }
                      else if (j == rows-1){
                          next[i+1][0] = 1;
                          next[cols-1][j-1] = 1;
                          next[cols-1][0] = 1;
                          next[i+1][j-1] = 1;
                      }
                      else {
                          next[i+1][j+1] = 1;
                          next[cols-1][j-1] = 1;
                          next[cols-1][j+1] = 1;
                          next[i+1][j-1] = 1;
                      }
                  }
                  else if (i == cols-1){
                      if(j === 0){
                          next[0][j+1] = 1;
                          next[i-1][rows-1] = 1;
                          next[i-1][j+1] = 1;
                          next[0][rows-1] = 1;
                      }
                      else if (j == rows-1){
                          next[0][0] = 1;
                          next[i-1][j-1] = 1;
                          next[i-1][0] = 1;
                          next[0][j-1] = 1;
                      }
                      else {
                          next[0][j+1] = 1;
                          next[i-1][j-1] = 1;
                          next[i-1][j+1] = 1;
                          next[0][j-1] = 1;
                      }
                  }
                  else if(j === 0){
                      next[i+1][j+1] = 1;
                      next[i-1][rows-1] = 1;
                      next[i-1][j+1] = 1;
                      next[i+1][rows-1] = 1;
                  }
                  else if (j == rows-1){
                      next[i+1][0] = 1;
                      next[i-1][j-1] = 1;
                      next[i-1][0] = 1;
                      next[i+1][j-1] = 1;
                  }
                  else {
                      next[i+1][j+1] = 1;
                      next[i-1][j-1] = 1;
                      next[i-1][j+1] = 1;
                      next[i+1][j-1] = 1;    
                  }
                  next[i][j] = 0;
              }
              else {
                  next[i][j] = state;
              }
            }
          }
          grid = next;
        
    }
}

function mouseClicked() {
    
    let headerPos = $("#ab-runheaderbox");
    
    let x = floor( mouseX / resolution );
    let y = floor( mouseY / resolution );
    
    if (grid[x][y] == 1)
    {
        grid[x][y] = 0;
    }
    else if (grid[x][y] == 0)
    {
        grid[x][y] = 1;
    }
}