// 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;
}
}