I made this simple game of life simulation and wondering if I can make the code cleaner
What options do I have?
jsfiddle: https://jsfiddle.net/04vazdrb/
/*
Conway's Game Of Life in JavaScript
*/
window.onload = function() {
var gridHeight = 400;
var gridWidth = 400;
var theGrid = createCellArr(gridWidth);
var mirrorGrid = createCellArr(gridWidth);
var genCounter = 0;
seed();
tick();
//main loop
function tick() {
drawGrind();
updateGrid();
counter();
requestAnimationFrame(tick);
}
/* Returns an array with n elements and places an empty
array in each of them using a FOR loop.
*/
function createCellArr(rows) {
var arr = [];
for (var i = 0; i < rows; i++) {
arr[i] = [];
}
return arr;
}
// Populating & filling the grid randomly.
function seed() {
// Iterate through rows
for (var j = 0; j < gridHeight; j++) {
// /iterate through columns
for (var k = 0; k < gridWidth; k++) {
//get a raw random number bettwen 0-1
var randomBinary = Math.floor(Math.random() * 2);
// checking the state
theGrid[j][k] = randomBinary;
}
}
}
// draw each grid cell in the array as a pixel on a Canvas
function drawGrind() {
var c = document.getElementById("gridCanvas");
var ctx = c.getContext("2d"); // get the context
ctx.clearRect(0, 0, 400, 400); // clear the canvas ahead of each redraw - (x, y, width, height)
//iterate through rows
for (var j = 1; j < gridHeight; j++) {
//iterate through the coloumns
for (var k = 1; k < gridWidth; k++) {
if (theGrid[j][k] === 1) { // alive cell
ctx.fillStyle = "#71bc4a"; // hot red!
ctx.fillRect(j, k, 1, 1) // fill a cell (x, y, width, height)
}
}
}
}
// Update the grid - game logic
function updateGrid() {
//iterate through rows
for (var j = 1; j < gridHeight - 1; j++) {
//iterate through columns
for (var k = 1; k < gridWidth - 1; k++) {
var totalCells = 0;
//add up the total values for the surrounding cells
totalCells += theGrid[j - 1][k - 1]; // top left
totalCells += theGrid[j - 1][k]; //top center
totalCells += theGrid[j - 1][k + 1]; //top right
totalCells += theGrid[j][k - 1]; //middle left
totalCells += theGrid[j][k + 1]; //middle right
totalCells += theGrid[j + 1][k - 1]; //bottom left
totalCells += theGrid[j + 1][k]; //bottom center
totalCells += theGrid[j + 1][k + 1]; //bottom right
//apply the rules to each cell
if (theGrid[j][k] === 0) {
switch (totalCells) {
case 3:
// if cell is dead and has 3 neighbours, switch it on
mirrorGrid[j][k] = 1;
break;
default:
mirrorGrid[j][k] = 0; //otherwise leave it dead
}
//apply rules to living cell
} else if (theGrid[j][k] === 1) {
switch (totalCells) {
case 0:
case 1:
mirrorGrid[j][k] = 0; //die of lonelines
break;
case 2:
case 3:
mirrorGrid[j][k] = 1; //carry on living
break;
case 4:
case 5:
case 6:
case 7:
case 8:
mirrorGrid[j][k] = 0; //die of overcrowding
break;
default:
mirrorGrid[j][k] = 0; //
}
}
}
}
////iterate through rows
for (var j = 0; j < gridHeight; j++) {
//iterate through columns
for (var k = 0; k < gridWidth; k++) {
//copy mirrorGrid to theGrid
theGrid[j][k] = mirrorGrid[j][k];
}
}
}
// Generation counter
function counter() {
genCounter++;
document.getElementById("generationCount").innerHTML = "Generation: " + genCounter;
}
} //]]>
You can abstract the action of looping each cell in it's own function, like this:
function forEachCell(doSomething) {
// Iterate through rows
for (var y = 0; y < gridHeight; y++) {
// Iterate through columns
for (var x = 0; x < gridWidth; x++) {
doSomething(x, y);
}
}
}
Have a look: https://jsfiddle.net/uzrabeq0/