function Cell(x, y) { this.column = x; this.row = y; this.currentState = false; this.nextState = false; this.neighbours = 0; this.Position = function() { return this.column + 'x' + this.row; } this.IsChanged = function() { return this.nextState != this.currentState; } this.SetChanged = function() { this.currentState = this.nextState; } this.SetNeighbours = function(amount) { if (this.currentState == true) { if (amount != 2 && amount != 3) this.nextState = false; else this.nextState = true; } else { if (amount == 3) this.nextState = true; else this.nextState = false; } this.neighbours = amount; }; } function GameOfLifeRenderer(container, columns, rows) { this.columns = 50; this.rows = 30; if (typeof (columns) == 'number' && columns >= 50) this.columns = columns; if (typeof (rows) == 'number' && rows >= 30) this.rows = rows this.gol = new GameOfLifeLogic(this.columns, this.rows); var htmlString = '<table id="grid" class="big">'; for (var j = 0; j < this.rows; j++) { htmlString += '<tr>'; for (var i = 0; i < this.columns; i++) { htmlString += '<td id="' + i + 'x' + j + '"></td>'; } htmlString += '</tr>'; } htmlString += '</table>'; $('#' + container).html(htmlString); $('#container').width($('#grid').width()); } GameOfLifeRenderer.prototype.SetShape = function(shapeName) { this.gol.LoadShape(shapeName); $('#grid tbody tr td').removeClass('full'); this.DrawInit(); } GameOfLifeRenderer.prototype.DrawInit = function() { this.Draw(); } GameOfLifeRenderer.prototype.DrawNext = function() { this.gol.Advance(); this.Draw(); } GameOfLifeRenderer.prototype.Draw = function() { for (var i = 0; i < this.columns; i++) { for (var j = 0; j < this.rows; j++) { if (this.gol.shape[i][j].IsChanged()) { $('#grid tbody tr td#' + this.gol.shape[i][j].Position()).toggleClass('full'); this.gol.shape[i][j].SetChanged(); } } } } GameOfLifeRenderer.prototype.ClickCell = function(cell) { if (cell.id.indexOf('x') > -1) { var coords = cell.id.split('x'); if (coords.length == 2) { var x = coords[0]; var y = coords[1]; if (!isNaN(x) && !isNaN(y)) { this.gol.ClickCell(x, y); $(cell).toggleClass('full'); } } } } function GameOfLifeLogic(cols, rows) { this.columns = cols; this.rows = rows; this.LoadShape('glider'); } GameOfLifeLogic.prototype.LoadShape = function(shapeName) { this.shape = new Array(this.columns); for (var i = 0; i < this.columns; i++) { this.shape[i] = new Array(this.rows); for (var j = 0; j < this.rows; j++) { this.shape[i][j] = new Cell(i, j); this.shape[i][j].currentState = false; this.shape[i][j].nextState = false; } } var coords; switch (shapeName) { case 'clear': coords = []; break; default: case 'glider': coords = [[24, 13], [25, 14], [23, 15], [24, 15], [25, 15]]; break; case 'small exploder': coords = [[24, 13], [23, 14], [24, 14], [25, 14], [23, 15], [25, 15], [24, 16]]; break; case 'exploder': coords = [[22, 12], [24, 12], [26, 12], [22, 13], [26, 13], [22, 14], [26, 14], [22, 15], [26, 15], [22, 16], [24, 16], [26, 16]]; break; case '10 cell row': coords = [[19, 14], [20, 14], [21, 14], [22, 14], [23, 14], [24, 14], [25, 14], [26, 14], [27, 14], [28, 14]]; break; } this.LoadShapeByCoords(coords); } GameOfLifeLogic.prototype.LoadShapeByCoords = function(coords) { for (var i = 0; i < coords.length; i++) { this.shape[coords[i][0]][coords[i][1]].nextState = true; } } GameOfLifeLogic.prototype.ClickCell = function(x, y) { this.shape[x][y].currentState = !this.shape[x][y].currentState; this.shape[x][y].nextState = this.shape[x][y].currentState; } GameOfLifeLogic.prototype.Advance = function() { for (var i = 0; i < this.columns; i++) { for (var j = 0; j < this.rows; j++) { var neighbours = 0; neighbours += this.GetPopulationSizeOfCell(i - 1, j - 1); neighbours += this.GetPopulationSizeOfCell(i, j - 1); neighbours += this.GetPopulationSizeOfCell(i + 1, j - 1); neighbours += this.GetPopulationSizeOfCell(i - 1, j); neighbours += this.GetPopulationSizeOfCell(i + 1, j); neighbours += this.GetPopulationSizeOfCell(i - 1, j + 1); neighbours += this.GetPopulationSizeOfCell(i, j + 1); neighbours += this.GetPopulationSizeOfCell(i + 1, j + 1); this.shape[i][j].SetNeighbours(neighbours); } } } GameOfLifeLogic.prototype.GetPopulationSizeOfCell = function(x, y) { if (x < 0 || x >= this.columns || y < 0 || y >= this.rows) return 0; else { if (this.shape[x][y].currentState == true) return 1; else return 0; } }