AngularJS sample : game of life
by ffischer2309
HTML
<script src="http://code.angularjs.org/1.0.0rc1/angular-1.0.0rc1.js"></script>
<div ng:app ng-controller="GameOfLifeCntl">
<h1>AngularJS Game of Life</h1>
Height: <input type="text" ng-model="height" /> Width: <input type="text" ng-model="width" />
<button ng-click="newGame()">New</button>
<button ng-click="next()">Next</button>
<table id="board">
<tr ng-repeat="row in board">
<td ng-repeat="cell in row" ng-click="toggle($parent.$index, $index)" class="{{cellClass($parent.$index, $index)}}">
<span ng-show="cell">O</span>
</td>
</tr>
</table>
<p class="history" ng-show="history.length > 0">Previous steps (click to rewind)</p>
<table class="history">
<tr>
<td ng-repeat="step in history" ng-click="$parent.step($index)">{{$index}}</td>
</tr>
</table>
</div>
CSS
h1 {
font-size: 1.3em;
color: #844;
font-style: bold;
}
table#board td {
width: 1.5em;
height: 1.5em;
text-align: center;
vertical-align: middle;
border: solid 1px #ddd;
}
table#board td.new {
background-color: #efe;
}
table#board td.die {
background-color: #fee;
}
.history {
color: #777;
}
table.history td {
width: 1.5em;
height: 1.5em;
text-align: center;
vertical-align: middle;
border: solid 1px #eee;
}
JavaScript
function GameOfLifeCntl($scope, $http, $resource) {
$scope.newGame = function() {
$scope.history = [];
$scope.board = init($scope.height, $scope.width);
};
$scope.next = function() {
$scope.history.push($scope.board);
$scope.board = computeNext($scope.board);
};
$scope.step = function(index) {
$scope.board = $scope.history[index];
$scope.history = $scope.history.slice(0, index);
};
$scope.toggle = function(row, cell) {
$scope.history = []; // Reset history as it is no longer accurate
$scope.board[row][cell] = !$scope.board[row][cell];
};
$scope.cellClass = function(row, cell) {
if (willDie($scope.board, row, cell)) {
return "die";
}
if (newCell($scope.board, row, cell)) {
return "new";
}
return "";
};
$scope.height = 10;
$scope.width = 20;
$scope.newGame();
function init(height, width) {
var board = [];
for (var h = 0; h < height; h++) {
var row = [];
for (var w = 0; w < width; w++) {
row.push(false);
}
board.push(row);
}
return board;
}
function computeNext(board) {
var newBoard = [];
for (var r = 0; r < board.length; r++) {
var newRow = [];
for (var c = 0; c < board[r].length; c++) {
newRow.push(willLive(board, r, c) || newCell(board, r, c));
}
newBoard.push(newRow);
}
return newBoard;
}
function willLive(board, row, cell) {
return cellAt(board, row, cell) &&
neighbours(board, row, cell) >= 2 &&
neighbours(board, row, cell) <= 3;
}
function willDie(board, row, cell) {
return cellAt(board, row, cell) &&
(neighbours(board, row, cell) < 2 ||
neighbours(board, row, cell) > 3);
}
function newCell(board, row, cell) {
return !cellAt(board, row, cell) &&
neighbours(board, row, cell) == 3;
}
function neighbours(board, row, cell) {
var n = 0;
n += cellAt(board, row - 1, cell - 1) ? 1 : 0;
n +=...