Skip to content

Instantly share code, notes, and snippets.

@nimitmaru
Created February 15, 2015 07:43
Show Gist options
  • Save nimitmaru/c65c84247ac8ca58c0d7 to your computer and use it in GitHub Desktop.
Save nimitmaru/c65c84247ac8ca58c0d7 to your computer and use it in GitHub Desktop.
var gameOfLife = {
width: 20,
height: 20,
stepInterval: null,
createAndShowBoard: function () {
// create <table> element
var goltable = document.createElement("tbody");
// build Table HTML
var tablehtml = '';
for (var h=0; h<this.height; h++) {
tablehtml += "<tr id='row+" + h + "'>";
for (var w=0; w<this.width; w++) {
tablehtml += "<td data-status='dead' id='" + w + "-" + h + "'></td>";
}
tablehtml += "</tr>";
}
goltable.innerHTML = tablehtml;
// add table to the #board element
var board = document.getElementById('board');
board.appendChild(goltable);
// once html elements are added to the page, attach events to them
this.setupBoardEvents();
},
forEachCell: function (func) {
for(var y = 0; y< this.height; y++) {
for(var x = 0; x< this.width; x++) {
myid = x+'-'+y;
cell = document.getElementById(myid);
if (cell) {
func(cell, x, y);
}
}
}
},
toggleCell: function(cell) {
if (cell.getAttribute('data-status') == 'dead') {
cell.className = "alive";
cell.setAttribute('data-status', 'alive');
} else {
cell.className = "dead";
cell.setAttribute('data-status', 'dead');
}
},
setupBoardEvents: function() {
var onBoardClick = function (event) {
var cell = event.toElement;
this.toggleCell(cell);
};
$('#board').click(onBoardClick.bind(this));
// setup control panel button events
$('#step_btn').click(this.step.bind(this));
$('#reset_btn').click(this.resetRandom.bind(this));
$('#clear_btn').click(this.clearBoard.bind(this));
$('#play_btn').click(this.enableAutoPlay.bind(this));
},
resetRandom: function () {
var forEachFunc = function(cell) {
if (Math.random() < .5) {
this.toggleCell(cell);
}
};
this.forEachCell(forEachFunc.bind(this));
},
clearBoard: function () {
var forEachFunc = function(cell) {
cell.setAttribute('data-status', "dead");
cell.className = "dead";
};
this.forEachCell(forEachFunc.bind(this));
},
step: function () {
this.forEachCell(function (cell, x, y) {
var aliveNeighbors, ncell, nid;
aliveNeighbors = 0;
for(var i = -1; i<=1; i++) {
for(var j = -1; j<=1; j++) {
nid = (x+i)+"-"+(y+j);
if (nid !== myid) {
ncell = document.getElementById(nid);
if (ncell && ncell.getAttribute('data-status') === "alive") {
aliveNeighbors++;
}
}
}
}
cell.setAttribute('data-neighbors', aliveNeighbors);
});
var getNextState = function (currentState, numNeighbors) {
var newStatus = currentState;
if(currentState == "alive" && (numNeighbors < 2 || numNeighbors > 3)) {
newStatus = "dead";
} else if( currentState == "dead" && numNeighbors === 3) {
newStatus = "alive";
}
return newStatus;
};
this.forEachCell(function (cell, x, y) {
var currentState = $(cell).attr('data-status');
var numNeighbors = parseInt($(cell).attr('data-neighbors'));
var newCellStatus = getNextState(currentState, numNeighbors);
if (newCellStatus) {
$(cell).attr({ 'data-status': newCellStatus, 'class': newCellStatus });
}
});
},
togglePlayPause: function () {
if (!this.stepInterval) {
$('#play_btn').text("Play").attr('class', 'btn btn-primary');
} else {
$('#play_btn').text("Pause").attr('class', 'btn btn-danger');
}
},
enableAutoPlay: function () {
// Start Auto-Play by running the 'step' function
// automatically repeatedly every fixed time interval
if (this.stepInterval) {
window.clearInterval(this.stepInterval);
this.stepInterval = false;
this.togglePlayPause();
} else {
var self = this;
this.stepInterval = window.setInterval(function () {
self.step();
}, 100);
this.togglePlayPause();
}
}
};
gameOfLife.createAndShowBoard();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment