Conway’s Game of Life in Angular.js

I know there are a lot of posts for Angular, so I will spare everyone a rehash of setup and Hello World. Instead, I thought it would be fun to show a simple example of Angular recreating Conway’s Game of Life.

This example will use the following technologies:

  • HTML
  • CSS
  • Angular.js
  • Bootstrap

If you would like to see a sample of the working application, click here: http://www.nicholasbarger.com/demos/conways-game-of-life.

What is Conway’s Game of Life

Check out Wikipedia: http://en.wikipedia.org/wiki/Conway%27s_Game_of_Lifefor a more in depth definition and origin of the game, but in short, it’s a simulation that allows you to observe evolutions based on an initial starting configuration while applying the following four basic rules at each round:

  1. Any live cell with fewer than two live neighbors dies, as if caused by under-population.
  2. Any live cell with two or three live neighbors lives on to the next generation.
  3. Any live cell with more than three live neighbors dies, as if by overcrowding.
  4. Any dead cell with exactly three live neighbors becomes a live cell, as if by reproduction.

The game can continue indefinitely resulting in either a repeating pattern or a “still life” where no more moves can occur.

Since this article is more about Angular, I’ve simplified the game a bit as well to randomly select the starting positions and limited the board to 30 by 30 cells, but feel free to improve the code to allow the gamer to specify starting positions or infinite space. All source code can be found here: https://github.com/nicholasbarger/conways-game-of-life.

Let’s set up the UI

To start, let’s set up a form and board to play on. The form is pretty straightforward and allows you to specify the number of starting life forms, how many generations to simulate and finally, a button to start the game.


            Enter the number of spontaneous lifeforms:
            
            Enter the number of generations to simulate:
            
            Start

Notice, that we’re using a few Angular tags to collect the data and fire off the game.

First, the data to interact with is wrapped with a div that specifies an ng-controllerattribute. This attribute is used to specify what controller will be used to execute logic against the HTML DOM elements. It is common to place this controller logic in another Javascript file.

Next, ng-submitis used to specify what function will be called on the controller when the form is submitted. When we wire up the controller, this is the method that will start iterating over generations in the game.

Finally, ng-modelis used to bind data values from the input form fields into variables that can be accessed in the controller. When the values on the form are changed, the variables backing them are automatically notified of the change and updated.

Now that we have a form created to gather some basic information about starting the game, let’s create the board that the game will actually play on.

<strong ng-show="rows.length > 0">Generation </strong>
        <table id="board" class="table table-bordered">
            <tr ng-repeat="row in rows">
                <td ng-repeat="cell in row">
                    <i class="glyphicon glyphicon-fire" ng-show="cell.isAlive == true"></i>
                    
                </td>
            </tr>
        </table>

In this code snippet, we see a few new Angular components used for controlling presentation of data.

First, ng-showallows us to toggle the visibility of DOM elements by evaluating a true/false statement. Essentially, when the expression is true, we’re setting a CSS style “display: block”, and when false, setting “display: none”.

Next, we get our first look at the mustache-inspired template rendering (http://mustache.github.io) used by Angular. Notice the double curly braces surrounding the variable name in . This allows rendering of this variable and is automatically updated whenever the value of the variable changes.

The Angular control we have not yet covered is ng-repeatand is used when building out the table as we create rows and cells based on the number of items in the “rows” variable. This simply iterates over the collection and continues to generate the content where the attribute is specified and all information that is a child within it.

Finally, we revisit the ng-show attribute to show a small icon in the cell based on whether it is alive or dead. The “== true” is a bit redundant (and admittedly, should be “===” if used anyway to strictly check the value).

Wire up the Controller to Play

The controller is just a function that sets up all of the code to interact with the UI and exposes the necessary variables through a special parameter called $scope. You can read quite a bit more on $scope through the Angular documentation https://docs.angularjs.org/guide/scopebut for simplicity, it’s a way to expose variables to binding in the UI.

If the UI is going to use a variable or call a function, it must be attached to $scope through the following syntax:

$scope.myVariable = ‘Some value’;
$scope.myFunction = function(param1, param2) { return param1 + param2; };

For brevity sake, I will just link to the file hosted on Github since its code is not truly Angular specific and mostly controls running the game. I’ve attempted to comment the rules fairly well so it is evident what is happening in each “generation” of the game. https://github.com/nicholasbarger/conways-game-of-life/blob/master/game.html

Take Away

At my company, we’ve adopted Angular to use every day in production development and haven’t looked back. The benefits of creating a single page applications (SPA) which limits full trips back and forth on the server has allowed us to provide a more native experience over the web while reducing our server load by pushing some of the processing back onto the client.

The example shown in this article is by no means production code and is structured all in one file, which is usually not appropriate for production use. Enterprise level applications need to fully utilize separation into various modules that are comprised of controllers, views, partials, directives, services, and so on.

I’ve learned to stop promising future blog posts since I tend to write in short waves and then neglect my blog for months at a time; however, I think it would be great to write several posts on architecting large Angular web applications and some of the challenges we have faced. Stay tuned (but don’t hold your breath)!

That’s one MEAN stack

On Thursday (6/26/2014), we had a nice meet up for the Southwest Florida [.net] Developers Groupwhere I was happy to see some old friends and get the opportunity to present on the MEAN stack. This is a little out of my comfort zone since I am just learning this stack and am by no means an expert on it, but it was fun nonetheless.

This blog post is a bit of a recap on what we covered with some follow up links for more information.

What is the MEAN stack?

The MEAN stack is Mongo as the database, Express as a web server framework, Node as the underlying server, and Angular as the client-side framework. Let’s take a minute and briefly discuss each of these technologies.

Mongo

Mongo DB is a NoSQL document database that uses Javascript syntax and stores data as BSON (binary json). It’s not a Mickey Mouse database; it’s actually quite powerful, and it’s free.

Some of the highlights of Mongo are:

  • Document database (NoSQL)
  • Javascript syntax
  • Stored as BSON (binary JSON)
  • Collections instead of tables
  • Single instance or sharded cluster
  • Replicated servers with automatic master failover

You can learn more about Mongo through 10gen’s introduction.

Also, take a look at comparing SQL to Mongowhich is a great article if you’re already experienced in relational databases.

Express

Express is a web-server framework that sits on top of node. It’s very lightweight and just makes node a little easier to use for web-based activities.

It’s not the only web framework for node, but it certainly is the most popular. Learn more about express.

Node

Node is server-side Javascript which focuses on non-blocking IO and is uses an event driven model. At first, the notion of writing Javascript to run the server-side code seemed a bit odd to me, but once I got over my old preconceptions of the limitations, I really embraced it.

The “hello world” of node looks a bit like this:

var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');

You can learn more about node by visiting the official website.

Angular

Angular is a front-end framework for Javascript web applications which is supported by Google. Angular has the following benefits (among others):

  • Creation of new directives which allow you to augment HTML controls.
  • Clean separation of view, controllers, and services.
  • A simple to use binding mechanism for updating the view based on changes in the controller.
  • Testable using the IoC pattern.

More information can be found on the official website.

Try it out

You can try out the MEAN stack in several ways. First, as we did during the meeting, install each component manually by first installing node, and then using npm and bower to install the other packages. You can follow the public Trello boardfor simple steps that we followed during the presentation.

Two additional ways, which are quite a bit quicker and include additional libraries not covered during the presentation, are to use mean.ioand yeoman.io. Both of these are scaffolding tools to get you up quickly and provide a solid foundation to work from.

This blog post is a bit of a recap on what we covered with some follow up links for more information.

Learning Knockout JS – Crazy Mom Baby Tracker Demo

I’m thrilled to be able to report my wife and I had our second daughter on May 8th, 2012. Vanessa was 7 pounds even and very healthy. Due to the birth, I took a few days off of work to help out (in many ways, I think I was more work for my wife being home). Most of my time has been spent getting acquainted with my new daughter, but occasionally, I’ve grabbed an hour here and there, usually in the middle of the night after a feeding, to read about knockout and even write a small demo as a learning exercise.

This little app is not meant to serve any commercial value and is very simplistic, but given the current situation I felt it was a fun and fitting topic.

To any mom’s out there, I mean the title to be lighthearted – no offense intended!

Ok, on with the article.

Knockout Demo Screenshot

What’s It Made Out Of?

The Crazy Mom Baby Tracker is intended to exercise the following technologies:

At the Southwest Florida .NET User Group, we recently had a Battle of the UI Frameworks which highlighted a general movement towards JavaScript-centric applications in the .net community. I thought we were aggressive at work, perhaps even cutting edge, but alas – it turns out we’re about where everyone else appears to be right now.

HTML5 is, of course, the latest version of HTML (at the time of this blog post) and all the rage. Though I will display HTML5 semantics, there are not any earth shattering HTML5 snippets throughout this demo.

jQuery is found throughout, as it has become the de facto standard for working with JavaScript these days.

Bootstrap was shown to me by our non-.NET marketing development team and it has been a nice addition for standardizing the HTML structure, CSS (or LESS) classes, and general user experience.

Knockout is very recent for me and the main purpose of this educational demo. It is a responsive MVVM JavaScript implementation that binds the UI to the underlying view model.

jqPlot is a jQuery charting library that I added into the project to visualize the data more interestingly.

A Little Prep Work Before We Get Building

This application is pure HTML, CSS, and JavaScript. As such, there is no need for the .net framework or Visual Studio. However, it certainly is a nice IDE to work in and by using the Nuget Package Manager you can get up and running very quickly. Therefore, all screenshots will be provided using Visual Studio, but this is not a requirement and you can ignore these references if you like.

First, let’s create a new Web Site. In Visual Studio, click File > New Website. Then under the template selector, choose ASP.NET Empty Web Site. By selecting this, you get a pretty bare web site that does not need to contain any ASP-related tags or code. After selecting an appropriate location to store the files you should be ready to begin.

Next, right click the project and select Manage Nuget Packages. You will want the following packages: jQuery, Bootstrap from Twitter, Knockout JS, and jqPlot.

Nuget Packages

Let’s also add a few placeholder files that we’ll work with later. Please create the following:

  • /Content/my.css
  • /Scripts/my.js
  • /index.html

Let’s Start Building

At this point, everything should be ready for us to start getting to the good stuff. Let’s open the index.html (our main application page) and add the css references for the selected Nuget packages, as well as our custom css file.

<head>
    <title>Crazy Mom Demo</title>
    <link rel="stylesheet" type="text/css" href="Content/bootstrap.min.css" />
    <link rel="stylesheet" type="text/css" href="Content/bootstrap-responsive.min.css" />
    <link rel="stylesheet" type="text/css" href="Scripts/jqPlot/jquery.jqplot.min.css" />
    <link rel="stylesheet" type="text/css" href="Content/my.css" />
</head>

Next, let’s add our script tags to bring in the code for the Nuget packages, and our own placeholder js file which we will use to add all of our custom logic to drive the application.

<body>
    <script type="text/javascript" src="Scripts/jquery-1.7.2.min.js"></script>
    <script type="text/javascript" src="Scripts/bootstrap.min.js"></script>
    <script type="text/javascript" src="Scripts/knockout-2.1.0.js"></script>
    <script type="text/javascript" src="Scripts/jqPlot/jquery.jqplot.min.js"></script>
    <script type="text/javascript" src="Scripts/my.js"></script>
</body>

Now that the references are in place, we need to build the structure of the html. Since we’re using bootstrap, we’re going to use the fixed grid layout they provide (hence the css classes “row” and “spanX”). The basics are below.

<div class="container">
	<h1 data-bind="text: title">Title</h1>
	<div class="row">
		<!—-panel for data entry -->
		<div class="span8">
                
		</div>

		<!—-panel for my cute kids picture -->
		<div class="span4">
			<!-—we won’t cover adding this in the blog post -->
		</div>
	</div>
</div>

We need a container wrapping the layout, and a few other layout related div’s to format the page. Notice the h1 tag which has our first knockout data-bind attribute. This is going to look for a property on the viewmodel called “title” and bind the innerText to it’s value.

Next, inside the data entry panel, let’s add two textboxes and a pair of buttons to control adding baby weight entries.

<form class="form-inline well" data-bind="submit: addItem">
	<h3>Enter the babies weight below</h3>
	
	<label>Pounds</label>
	<input id="pounds" type="text" class="input-mini" data-bind="hasfocus: true" />

	<label>Remaining ounces</label>
	<input id="ounces" type="text" class="input-mini" />

	<button type="submit" class="btn btn-primary"><i class="icon-ok icon-white"></i> Add Baby Weight</button>
	<button type="reset" class="btn btn-danger" data-bind="click: clearItems"><i class="icon-remove icon-white"></i> Start Over</button>
</form>

The css classes for the form are also from bootstrap and help to stylize the form. You can view the bootstrap documentation for more details.

The form has a knockout binding for submit to call the function on the viewmodel “addItem”. There is also a binding for the click event of the reset button to clear all data in the viewmodel (not just the form fields as normal).

Directly below the form, let’s add a section for displaying notifications and data validation. We’ll again use knockout to bind the results of the messages based on what is happening in the viewmodel.

<div id="alert" class="alert" 
	data-bind="
		visible: msg().length > 0, 
		css: { 
			'alert-success': msgType() == 'success', 
			'alert-error': msgType() == 'error', 
			'alert-info': msgType() == 'info' }"<
                    
	<a class="close" href="#" data-bind="click: hideAlert">×</a>
	<p data-bind="text: msg"></p>
</div>

Let’s now add the final pieces to allow for a bit of data visualization. We’re going to use a chart control from jqPlot and a table displaying the individual entries.

<div id="resultsChart" data-bind="chart: items()"></div>

<table class="table table-striped" data-bind="visible: items().length > 0">
	<thead>
		<tr>
			<td>Weight</td>
			<td>Total Pounds</td>
			<td>Total Ounces</td>
		</tr>
	</thead>
	<tbody data-bind="foreach: items">
		<tr>
			<td data-bind="text: display()"></td>
			<td data-bind="text: totalPounds()"></td>
			<td data-bind="text: totalOunces()"></td>
			<td><a href="#" data-bind="click: $parent.removeItem"><i class="icon-remove"></i></a></td>
		</tr>
	</tbody>
</table>

The chart is interesting, as it will be a custom binding we create for knockout to work with jqPlot. Data within the table are bound to an array of items and looped through using the foreach knockout binding. I’ve also added a remove button next to each entry to allow for the removal of entries added by mistake. Notice the scoping when specifying the knockout binding; while looping through the items, we’re at the individual item level – therefore, we must move up one level to access the viewmodel directly ($parent) and call the removeItem function.

jqPlot Chart Screenshot

Wiring Up the Logic with Knockout and jQuery

Now that we have a clear picture of what we want this application to look like, let’s wire up the viewmodel and make it actually perform.

Open up your my.js file and begin by creating a good old jQuery ready event:

$(function () {
});

We’ll put our code in here. Let’s also create our own namespace with the following code to avoid any collisions.

// global namespace
var my = my || {};

We now need a model to structure the baby weight entries. Let’s create it as follows:

// models
my.BabyWeight = function(pounds, ounces) {
	var self = this;

	self.pounds = pounds;
	self.remainingOunces = ounces;

	self.totalOunces = function () {
		return (self.pounds * 16) + (self.remainingOunces * 1);
	};
	self.totalPounds = function () {
		return (self.pounds * 1) + (self.remainingOunces / 16);
	};
	self.display = function () {
		return self.pounds + 'lbs - ' + self.remainingOunces + 'oz';
	};
};

This could contain knockout observables and computed values, but it’s not particularly necessary the way the demo is set up. The BabyWeight model has two properties: pounds and remainingOunces which together make up for the entire weight of the baby. I’ve also added a few calculated properties to add to the tabular data for each entry.

Let’s now create the viewmodel which will contain the bulk of our knockout observables.

// view model
my.vm = function(existingItems) {
	var self = this;

	// properties
	self.items = ko.observableArray(existingItems);
	self.msg = ko.observable("");
	self.msgType = ko.observable("info");
	self.title = ko.observable("Crazy Mom Baby Tracker v.001");

	// methods
	self.addItem = function () {
		var pounds = $('#pounds').val();
		var remainingOunces = $('#ounces').val();
		var itemToAdd = new my.BabyWeight(pounds, remainingOunces);
		
		// validate
		if (itemToAdd.pounds == "" || itemToAdd.ounces == "") {
			self.msgType("error");
			self.msg("Oops, either the baby has become weightless or you didn't enter any data.");
			return;
		}
		else {
			self.msg("");
		}

		// add to items array
		self.items.push(itemToAdd);

		// update msg
		self.msgType("success");
		self.msg("You've successfully weighed the baby in at " + itemToAdd.display());
	},
	self.clearItems = function () {

		// clear items
		self.items([]);

		// update msg
		self.msgType("info");
		self.msg("All weight entries have been cleared.");
	},
	self.hideAlert = function () {
		self.msg("");  //clearing the message will auto-hide since it's bound
	},
	self.removeItem = function (item) {

		// remove item from items array
		self.items.remove(item);

		// update msg
		self.msgType("info");
		self.msg("The weight entry has been successfully removed.");
	}
};    

Note the use of this line:

var self = this;

This helps to maintain reference to the proper this when inside callbacks from anonymous functions.

The observables ensure that changes to their values will be automatically reflected in the UI for any bindings. For example, as an item is added or removed from the items array, the UI for the chart and table will automatically be updated, well as soon as we add the custom binding to the chart that is. Let’s add that now:

// kick off knockout bindings
ko.applyBindings(new my.vm([]));
    
// add custom binding for charting
ko.bindingHandlers.chart = {
	init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
		// empty - left as placeholder if needed later
	},
	update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
		// prepare chart values
		var items = ko.utils.unwrapObservable(valueAccessor);
		var chartValues = [[]];
		for (var i = 0; i < items().length; i++) {
			chartValues[0].push(items()[i].totalOunces());
		}

		// clear previous chart
		$(element).html("");

		// plot chart
		$.jqplot(element.id, chartValues, {
			title: 'Baby Weight'
		});
	}
};

The custom binding simply updates the chart on any change to the passed in valueAccessor, which we specified in the html as the items array in the viewmodel. jqPlot uses the element.id, in our case a div tag, to act as the placeholder container to drop the chart into. See the jqPlot documentation for much more detail on creating significantly more elaborate charting capabilities.

Some Odds and Ends

I didn’t cover the my.css file but I used this to add some very minor additional styling to the page. Most of the styles though do come “out of the box” from bootstrap. I hope someone finds this useful and please feel free to correct any mistakes I’ve made – this is certainly meant to reinforce my own pursuit in working with knockout and I welcome any advice.