13,798,583 members
alternative version

#### Stats

30.8K views
36 bookmarked
Posted 15 Dec 2013
Licenced CPOL

# Learn JavaScript Part 3 - AngularJS and Langton's Ant

, 30 Dec 2013
Learn how to use Bower, Bootstrap and AngularJS to create the Langton's Ant simulation in JavaScript

## Introduction

Welcome to Part 3 in my series on learning JavaScript. In this article, I'm going to show you how to implement the Langton's Ant simulation in JavaScript. I'm also going to use the framework AngularJS to help with the client side logic. You can take a look at the finished result here.

I'm also going to introduce Bower for handling client side components.

## The Learn JavaScript Series

This is part three of my Learn JavaScript series:

The series is all about learning JavaScript and the HTML5 tech stack with hands on projects.

## What is Langton's Ant?

Langton's Ant is a simple mathematical simulation, it's a little bit like Conway's Game of Life. Basically, we imagine an infinite two dimensional plane of squares, all of them white. The ant sits on the square in the middle. Every time we advance the simulation, we move the ant forward. If the ant leaves a white tile it turns left, if it leaves a black tile it turns right. When it leaves the tile, it toggles it between black and white.

We can extend the simulation by including more states for tiles.

What's interesting about this simulation? Well it's really the behaviour of the universe we find interesting. It only has three rules, but shows quite complex behaviour. For the first few hundred moves, we see what looks to be like a pattern, there appears to be symmetry and order. After a little while, the system becomes chaotic - the ant is wandering with seemingly no order, disturbing the earlier made patterns. After about 11000 moves, the final state of the behaviour is seen - emergent order. From the chaos before, the ant builds a pattern that repeats and slowly moves in one direction. This is called the highway.

It is not known whether all initial configurations produce a highway. What is fascinating is that we know the 'theory of everything' for this universe, but there is still much we don't know - do all configurations lead to a highway? Knowing all of the rules of a system is not enough to understand it.

## Part 1 - Getting Started

The first thing we will do is put together the structure of our application. We'll have a file and folder structure like this:

```-langtonsant/
-client/
-index.htm
-js/
-langtonsant.js  ```

The index.html file will contain the presentation of the simulation and its controls - langtonsant.js will contain a class that represents the simulation and offers functionality to start/stop it, etc.

What else are we going to need? Well, we're going to use two third party libraries.

Bootstrap is one of the most popular packages for web development. At its core, it is a set of CSS styles that greatly clean up 'standard' HTML, by using cleaner fonts, better paragraph spacings, better link styles and so on. It then adds on this by giving a large set of UI components you can drop into HTML, such as tabs and carousels. I wrote an article called Create Clean Webpages with Twitter Bootstrap if you want to read more.

We'll use Bootstrap for the clean styling of text and form controls, as well as the 'accordion' component that shows an item that can be dropped down to show more UI.

### AngularJS

AngularJS is a framework for building HTML/JS applications on the client. It supports data binding and so on, meaning that you can change the state of a JavaScript object and the UI updates accordingly.

AngularJS is a big topic, we'll be using only a few of its features. I have an entire series on AngularJS on my website, Practical AngularJS - I'd recommend the Introduction to AngularJS if you've not heard of it.

## Part 2 - Installing Client Side Components with Bower

We're going to use Bower to install Angular and Bootstrap for us. What is Bower? Bower is a package manager for the web - it's like Nuget if you use C#, Gem if you use Ruby, Pip if you use Python, etc.

To install Bower, make sure you have NodeJS installed. If you've not used or heard of NodeJS before, don't worry - for the purposes of what we're doing, it's just going to offer a way to install Bower. I'm planning a big series on Node as well.

Now install Bower as a global NodeJS package with the following command line command:

`npm install -g bower`

The '`-g`' flag indicates that this package should be installed globally - we want to use bower from any location.

Now comes to the cool bit. Navigate to the 'client' folder in langtonsant and run the following commands:

```bower init
bower install angular#1.2.x --save
bower install bootstrap#3.0.x --save ```

When we use '`bower install`', we install the package that follows into the current directory. Bower creates a 'bower_components' folder and drops the required files in there. We can use a hash after the package name to use a specific version - in this case, I know I want Angular 1.2 and Bootstrap 3.0, and I'm happy to take bugfixes and minor non breaking updates (that's why I use '`x`' at the end) but don't want any larger updates.

Including the '`--save`' flag in the command means bower creates a bower.json file in the folder that lists the packages I've installed, this means the next person to use the code can just use:

`bower install `

And Angular and Bootstrap will be installed, because they're in the bower.json file. Easy!

Because we've installed the packages, we can now reference them in our index.html file:

```<!DOCTYPE html>
<html >
<title>Langton's Ant</title>

href="bower_components/bootstrap/dist/css/bootstrap.min.css">
<script src="bower_components/angular/angular.min.js"></script>
<body>
<!-- We'll put everything here! -->
<script src="bower_components/jquery/jquery.min.js"></script>
<script src="bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
</body>
</html>```

We know all of our third party stuff lives in the bower_components folder, nice and separate from our own code.

## Part 2 - Creating the Simulation

We need an object that will represent the simulation. Now in the last two articles, we've gone into quite a bit of detail on creating objects in JavaScript, so for this section, I'm going to go very quickly - we're not going to dissect every part of the simulation. I'll show the code and highlight key points, but then we'll move onto what's new for this part of the series.

Let's start by creating the langtonsant.js file and making a class:

```/*
Langton's Ant

The Langton's Ant class represents a Langton's Ant simulation. It is
initialised with a call to 'Initialise', providing all configuration
and erasing any state. The simulation can then be 'ticked', forwards
or backwards.
*/

function LangtonsAnt() {

//  The position of the ant.
this.antPosition = {x: 0, y: 0};

//  The direction of the ant, in degrees clockwise from north.
this.antDirection = 0;

//  A set of all tiles. The value for each tile is its state index.
//  We also have a set of tile states.
this.tiles = [];
this.states = [];

//  The bounds of the system.
this.bounds = {
xMin: 0,
xMax: 0,
yMin: 0,
yMax: 0
};

//  The number of ticks.
this.ticks = 0;

//  The offset and current zoom factor.
this.offsetX = 0;
this.offsetY = 0;
this.zoomFactor = 1.0;```

This defines the `LangtonsAnt` class and the state it will have. We'll need the position of the ant, the direction of the ant, an array of tiles and the bounds of the system.

Why do we have the bounds and an array of tiles? Well, we don't want to limit the system to a certain size, so what we'll do is assume the universe is infinite, and we get the state of any tile, it's white. As we change the state of tiles we'll save it in the '`tiles`' array. This means that the `tiles` array is sparse - if we have a universe that is 100x100 tiles, we don't need 10000 tiles, we only need tiles that have a non-default state.

What do we store in a tile? Just the index of the state. Each tile can have two states, white or black, but we can have more complex simulations with more tile states, in this case, the index is just larger. This lets us define the next function, which initialises the universe.

```//  Initialises a universe. If we include a configuration
//  value, we can override the states.
this.initialise = function (configuration) {

//  Reset the tiles, ant and states.
this.antPosition = {
x: 0,
y: 0
};
this.antDirection = 0;
this.tiles = [];
this.bounds = {
xMin: 0,
xMax: 0,
yMin: 0,
yMax: 0
};
this.states = [];
this.offsetX = 0;
this.offsetY = 0;

//  If we have no states, create our own.
if(configuration.states !== undefined) {
this.states = configuration.states;
} else {
this.states = [
{direction: 'L', colour: '#FFFFFF'},
{direction: 'R', colour: '#000000'}
];
}
};
```

Initialising the universe must reset all of the values, as we might call it on a universe we've already created. If we pass a states array, we use it, otherwise we create a default array of states - one white tile (where we turn left) one black tile (where we turn right).

From here, it's trivial to define helper functions that get a tile state index or a tile state:

```//  Gets a tile state index. If we don't have a state, return the
//  default (zero), otherwise return the state from the tiles array.
this.getTileStateIndex = function(x, y) {
if(this.tiles[x] === undefined) {
this.tiles[x] = [];
}
var stateIndex = this.tiles[x][y];
return stateIndex === undefined ? 0 : stateIndex;
};

//  Gets a tile state.
this.getTileState = function(x, y) {
return this.states[this.getTileStateIndex(x, y)];
};
```

So far so good - now we can use helpers to set a tile state.

```//  Set a tile state index.
this.setTileStateIndex = function(x, y, stateIndex) {
if(this.tiles[x] === undefined) {
this.tiles[x] = [];
}
this.tiles[x][y] = stateIndex;

//  Update the bounds of the system.
if(x < this.bounds.xMin) {this.bounds.xMin = x;}
if(x > this.bounds.xMax) {this.bounds.xMax = x;}
if(y < this.bounds.yMin) {this.bounds.yMin = y;}
if(y > this.bounds.yMax) {this.bounds.yMax = y;}
};
```

Next, we can write a helper to advance a tile to the next state, going back to the first if we've rolled over each state.

```//  Advance a tile states.
this.advanceTile = function(x, y) {
//  Get the state index, increment it, roll over if we pass
//  over the last state and update the tile state.
var stateIndex = this.getTileStateIndex(x, y)+1;
stateIndex %= this.states.length;
this.setTileStateIndex(x, y, stateIndex);
};
```

The next function moves the simulation forwards one step. We get the tile state, change direction based on the state, move the ant and then advance the tile.

```//  Take a step forwards.
this.stepForwards = function() {

//  Get the state of the tile that the ant is on, this'll let
//  us determine the direction to move in.
var state = this.getTileState(this.antPosition.x, this.antPosition.y);

//  Change direction.
if(state.direction === 'L') {
this.antDirection -= 90;
} else if(state.direction === 'R') {
this.antDirection += 90;
}
this.antDirection %= 360;

//  Move the ant.
if(this.antDirection === 0) {
this.antPosition.y++;
} else if (this.antDirection === 90 || this.antDirection === -270) {
this.antPosition.x++;
} else if (this.antDirection === 180 || this.antDirection === -180) {
this.antPosition.y--;
}
else {
this.antPosition.x--;
}

//  Now we can advance the tile.

this.ticks++;
};
```

The last function renders the simulation to a canvas. I won't include it here as it's rather long, but you can see the code if you want to check it here. This code is not particularly helpful to the article as we've already gone over canvas drawing in the last two articles.

We've now created the simulation. The next step is to create a controller the user interface can use to control the simulation.

## Part 3 - Creating a Controller

A controller is an object AngularJS builds to create and manipulate state in the scope. The scope is a data context for binding operations in the view. Controllers contain fields, which the view binds to, and functions, which the view also binds to. This lets us write HTML to write up UI elements to data or UI elements to activate functionality.

We'll need two new files - app.js and controllers.js. App.js will be the main angular app and will depend on the controllers. The controllers.js file will define the main controller for the app.

```//  Define the langtons ant module. It depends on app controllers and directives.
var app = angular.module('langtonsant',
['langtonsant.controllers',
'langtonsant.directives']);```

Angular uses a module system to allow us to split up the app. We've defined '`langtonsant`' as the main module, and said that it dependes on the '`langtonsant.controllers`' module, as well as the '`langtonsant.directives`' module, which we'll see later. Now let's write a controller.

We're going to create the main controller - it'll have a simulation object and a function to start it, stop it and reset it.

Here's how controllers.js starts:

```//  All controllers go in the langtonsant.controllers module.
angular.module('langtonsant.controllers', [])
.controller('MainController', function(\$interval, \$timeout) {
var self = this;```

We've defined a new module, '`langtonsant.controllers`'. The second parameter is an array of modules that this one depends on, which is nothing. Next, we add a controller called '`MainController`'. The controller definition function returns an instance of the controller. It's parameters are its dependencies. Angular will automatically inject these dependencies for us. Every dependency that starts with a dollar sign is a built in Angular dependency.

We depend on `\$interval`, which is for repeating timers, and `\$timeout`, which is for calling a function after a given amount of time.

Next, we can define the data on the controller. If we assign it to `this`, we'll be able to bind the view to it. Normal `var` definitions are for data we use internally.

```//  The frequency of simulation ticks
this.tickFrequency = 10;

//  The set of default colours for states.
this.defaultStateColours = [
'#FFFFFF',
'#49708A',
'#88ABC2',
'#D0E0EB',
'#EBF7F8'
];

//  Available tile states.
this.states = [
{direction:'L', colour: this.defaultStateColours[0]},
{direction:'R', colour: this.defaultStateColours[1]}
];

//  Simulation info.
this.info = {
currentTicks: 0
};

//  None scope variables. These are used by the controller, but not exposed.
var currentState = "stopped";
var tickIntervalId = null;
var simulation = new LangtonsAnt();
var canvas = null;

//  Initialise the simulation with the states.
simulation.initialise({states: this.states});

//  When the document is ready, we'll grab the antcanvas.
\$timeout(function() {
canvas = document.getElementById('antcanvas');
self.render();
});
```

We need the frequency - that's how many times per second we 'tick' the universe. We define a set of colours to use by default for tiles. We create two initial tile states, which we'll give to the initialise function of the simulation. We keep track of information we might want to see (the number of ticks).

We also store the current state, whether we're running or stopped. We keep an interval id (as we'll set a timer to tick and we'll need to stop it later). We create an instance of the simulation and then something clever...

Using `\$timeout(function() {})` is a little trick. It registers a function to call immediately, but because we're using the angular `\$timeout` rather than the one on the window, we get a special free behaviour - it's called after the DOM is loaded and after the angular app is loaded. If we didn't do this, we'd probably not have the canvas ready in the DOM, and we want to grab the canvas ASAP so we can draw to it. We also call out '`render`' function when we've got it - which we'll write later.

Why `self` sometimes instead of `this`? Well in JavaScript, `this` isn't what you'd always expect. For example, in a timer callback function, `this` will be the global object. As we want to change our class instance, we store it in `self` straightaway, so we can refer to it explicitly in callback functions. Nice trick! This is something you'll see very regularly in JavaScript.

Next, let's create a function that runs the simulation:

```//  Runs the simulation.
this.run = function() {
//  If we're already running, we can't start the simulation.
if(currentState === 'running') {
return;
}

//  Start the timer.
tickIntervalId = \$interval(function() {
simulation.stepForwards();
self.info.currentTicks = simulation.ticks;
self.render();
}, 1000 / this.tickFrequency);

//  Set the status.
currentState = 'running';
};
```

This function makes sure we're not already running, then starts a timer. Each time the timer fires, we step the simulation forwards, update how many steps we've taken and draw. Then we set the state to running.

Because this function is defined on '`this`', we can bind to it in the view, for example making a click fire the function.

We'll need to know the current state in the view, so we can show or hide the run/pause buttons based on whether we're already running. We also need a `render` function that tells the simulation to render to the canvas (if we've got it yet).

```//  Get the state. We don't offer access to the variable directly
//  as we don't want anyone to change it!
this.getCurrentState = function() {
return currentState;
};

//  Render the simulation. We can only render it if we've got the
//  canvas.
this.render = function() {
if(canvas !== null && canvas !== undefined) {
simulation.render(canvas);
}
};
```

By now, we're pretty comfortable with functions, so let's add one to pause the simulation:

```//  Pauses the simulation.
this.pause = function() {

//  If we're already paused, there's nothing to do.
if(currentState === 'paused') {
return;
}

//  Cancel the timer.
\$interval.cancel(tickIntervalId);

//  Set the status.
currentState = 'paused';
};
```

Why are we using `\$interval` to create timers? Well, it's just a wrapper around the standard interval function, but it works with Angular so that Angular will update the bindings after the timer fires. If we don't use this, we have to tell Angular explicitly to update its bindings after every tick.

We've now got enough to build the view!

## Part 4 - Creating the View

This is where the power of Angular will become apparent. Let's write the index.html file - first including all of our JavaScript and CSS files:

```<!DOCTYPE html>
<html ng-app="langtonsant">
<title>Langton's Ant</title>

href="bower_components/bootstrap/dist/css/bootstrap.min.css">
<script src="bower_components/angular/angular.min.js"></script>
<script src="js/langtonsant.js"></script>
<script src="js/app.js"></script>
<script src="js/controllers.js"></script>
<script src="js/directives.js"></script>

We're just including our JavaScript files here and the CSS for bootstrap. Notice the `ng-app` directive? This tells Angular that everything in the HTML element should be considered part of our `langtonsant` application - from here on, we can use Angular directives to bind the view to the controller.

Now we can create the canvas for the simulation to draw to:

```<body>
<canvas id="antcanvas"></canvas>
<div id="controls" ng-controller="MainController as main">```

There is CSS needed to keep the canvas fullscreen, but we've seen that already in the last two articles. What is new is `ng-controller` directive. We're telling Angular that it must create an instance of the `MainController` and call it `main`. We can use this controller for any element in the `div` from now on. This means we can do some wildly cool stuff, like this:

```<button type="button" ng-click="main.getCurrentState() == 'running' ? main.pause() : main.run()"

class="btn btn-default">
<span ng-show="main.getCurrentState() == 'running'" class="glyphicon glyphicon-pause"></span>
<span ng-show="main.getCurrentState() != 'running'" class="glyphicon glyphicon-play"></span>
</button>
<button type="button" ng-click="main.reset()"

class="btn btn-default"><span class="glyphicon glyphicon-refresh">
</span></button>
<input type="text" class="form-control" ng-model="main.tickFrequency">```

This is very nice - we create a button, and wire up the click event with `ng-click`. When we click, we check the state of the simulation. If it's running we pause it, if it's paused we run it. Within the button, we include two `span`s - one that shows a 'play' icon and one that shows a 'pause' icon. We show each icon only if the state is appropriate, using the `ng-show` directive. We also have a text input bound to the tick frequency via the `ng-model` attribute. This means if we change the input, Angular changes the JavaScript object for us.

Everything that starts with `ng-` is Angular, and we can see how powerful it is - we don't need to turn things on or off or hide them, we let Angular do it for us, based on the results of simple expressions that use the `MainController` called `main`.

If you're new to Angular, this is core functionality and you can find more at Practical AngularJS Part 1 - Introducing AngularJS.

## Part 5 - More Advanced Functionality

If you open Langton's Ant link, you'll see that you can click the cog at the top left to see more settings:

One thing we can do is add and remove tile states - let's wire that up now. First, we'll add controller functions to add and remove a state:

```//  Removes a given state.
this.removeState = function(state) {
var index = this.states.indexOf(state);
if(index !== -1) {
this.states.splice(index, 1);
}
};

//  Adds a new state.
this.addState = function() {
//  Create a new state with the next colour in the list.
var colourIndex = this.states.length % this.defaultStateColours.length;
this.states.push({
direction: 'L',
colour: this.defaultStateColours[colourIndex]
});
};
```

`remoteState `takes a `state` object and removes it from the list. `addState `adds a new `state` with the next colour in the list. That's it! Now we can create a table of `state`s in the view with functionality to add or remove them:

```<table>
<tr>
<td>Direction</td>
<td>Colour</td>
<td></td>
</tr>
<tr ng-repeat="state in main.states">
<td><la-leftright value="state.direction"></la-leftright></td>
<td><la-colourpicker colour="state.colour"></la-colourpicker></td>
<td><a href="" ng-hide="\$first" ng-click="main.removeState(state)">
<span class="glyphicon glyphicon-remove"></span></a></td>
</tr>
<tr>
<td></td>
<td></td>
<td><a href="" ng-click="main.addState()"><span class="glyphicon glyphicon-plus">
</span></a></td>
</tr>
</table>```

Here, we've made a table of three columns - the direction, colour and a space for buttons. We add a heading for each. Then we show each state in a row, by using the `ng-repeat` directive. This directive lets us loop through an array and show content for each element. So we can build a table row for each state.

For the first column, I'm using a `<la-leftright>` control. Doesn't look familiar? That's because we're going to create it! I bind the value of the leftright control to the state direction. Then I show a colour picker control, bound to the state colour. Finally, I show a 'delete' button, which calls `removeState `on click via `ng-click`. Also, I hide the button if we're on the first row, by using `ng-hide="\$first"`. ng-hide hides the element if the expression evaluates to `true` - and `\$first` is a special variable angular provides for us which is `true` for the first row. `\$first` is only available in an `ng-repeat` area - and Angular has other useful ones like `\$index`, `\$last`, `\$even`, `\$odd` and so on.

Finally, we add a row to the table that just includes a plus button that calls `addState`.

That's it!

We add or remove states, Angular updates the DOM for us - which means we can add complex functionality like the above with ease.

Hang on though, I used to bizarre elements - `la-leftright` and `la-colourpicker` - these are not standard HTML so what are they? Well this is the last part - Angular directives.

## Part 6 - Custom Directives

I wrote la-leftright and la-colourpicker because that's how I want my HTML to look - it's fairly clear that they're for a left/right control and a colour picker control. This is how I want my HTML to look and Angular can help with that.

Custom Directives are elements or attributes you add to your HTML that Angular wires up for you. `ng-repeat`, `ng-click` and so on are directives, and we can create our own.

Let's start by defining the `leftright` directive - I want it to show the text "left | right" and underline the selected direction, changing it if the user clicks on it. We created a 'controllers.js' file, now let's create a 'directives.js' file:

```angular.module('langtonsant.directives', [])
.directive('laLeftright', function() {
return {
restrict: 'E',
scope: {
'value': '='
},
templateUrl: "js/laLeftright.html"
};
});```

That's a directive - we use '`restrict`' to specify we want to use this directive as an element ('`E`') - we could also use an attribute '`A`' or class '`C`', or all of them - we can even use comments for directives.

By setting `scope`, I am saying 'In my directive, I want a scope. It has a property called '`value`' and it is bound two way to the attribute '`value`''. I could use `'value':'=leftorright'` to use the attribute name '`leftorright`' as the input to the scope, as I've used just '`=`' on its own, it assumes that name of the attribute is `value`. There are other options too - for example `'value':'@something'` would bind the attribute '`something`' to `value`, but one way only.

Finally, I specify a template url - this is a url to the HTML to use for the directive content, and it's really simple HTML:

```<a href=""

ng-style="{'text-decoration':value == 'L' ? 'underline' : 'none'}"

ng-click="value = 'L'">left</a> |
<a href=""

ng-style="{'text-decoration':value == 'R' ? 'underline' : 'none'}"

ng-click="value = 'R'">right</a>```

We have two links. The first uses `ng-style` to set the text decoration to underline if value is '`L`', none otherwise. It uses `ng-click` to set value to '`L`' if it's clicked. The second link does the same for '`R`'.

That's how easy directives can be! They can be extremely advanced as well, but you can see how quickly we can use them to create reusable client side logic or presentation markup.

## Conclusion

There are a few bits missing here - moving the simulation around, zooming and the colour picker, but if you've ready the article, you will be able to understand all of the extra code, we've shown the key new parts and that's the most important thing. We've seen how Bower can help us with third party libraries and Angular can help us with client side logic and binding.

There's some other stuff in the code too - there's a NodeJS server to serve the content of the page when testing, but this is something we'll look into in a later article!

If you've enjoyed seeing what Angular can do, follow my series on Practical AngularJS - I'm working on it at the moment and going through all parts of the framework.

As always, comments and suggestions are welcome, I hope you've enjoyed this article! Next time, we'll be taking a look into Server Side JavaScript with NodeJS.

## About the Author

 Software Developer United Kingdom
Follow my blog at www.dwmkerr.com and find out about my charity at www.childrenshomesnepal.org.

 Pro

## Comments and Discussions

 First Prev Next
 Very nice indeed Sacha Barber1-Jul-15 2:05 Sacha Barber 1-Jul-15 2:05
 Haven't read them, but... Sander Rossel28-Feb-15 4:41 Sander Rossel 28-Feb-15 4:41
 My vote of 5 Lupuj13-Sep-14 12:15 Lupuj 13-Sep-14 12:15
 Greetings!
 Re: My vote of 5 Dave Kerr14-Sep-14 17:06 Dave Kerr 14-Sep-14 17:06
 typo? Member 1008303619-Dec-13 3:02 Member 10083036 19-Dec-13 3:02
 Re: typo? Dave Kerr30-Dec-13 4:36 Dave Kerr 30-Dec-13 4:36
 Last Visit: 13-Dec-18 15:43     Last Update: 13-Dec-18 15:43 Refresh 1

General    News    Suggestion    Question    Bug    Answer    Joke    Praise    Rant    Admin

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.