## UK Postcode Validation in AS3

Let me file this post under boring but useful. Recently I worked on a project where I had to validate UK postcodes in flash. The method I used in the end was a regular expression I found, with a bit of formatting logic added. This should work for all UK postcodes.

```var validPostcode:String   =  "LS12ED";
var validPostcode2:String   = "LS1 2ED";
var invalidPostcode:String =  "NOTAPOSTCODE";

trace(validateUkPostcode(validPostcode));//true
trace(validateUkPostcode(validPostcode2));//true
trace(validateUkPostcode(invalidPostcode));//false

function validateUkPostcode(str:String):Boolean {

if(str.indexOf(" ")==-1){
var l:int = str.length;
str=str.substr(0,l-3)+" "+str.substr(l-3,l);
}

var pattern:RegExp =  /[A-Z]{1,2}[0-9R][0-9A-Z]? [0-9][ABD-HJLNP-UW-Z]{2}/i

var result:Object = pattern.exec(str);
if(result == null) {
return false;
} else {
return true;
}
}
```

## Cellular Automidi – Audio App

Presenting my latest Flash Music Toy App Thing –

## Cellular AutoMidi!

Cellular AutoMidi is a generative music app, making “music” based on a modified Cellular Automata algorithm.

It’s an AIR app –

Check it out in action in the video below, first using Flash dynamic sounds, then using Flash Midi Server to control a synth –

According to Wikipedia –

A cellular automaton is a discrete model studied in computability theory, mathematics, physics, complexity science, theoretical biology and microstructure modeling. It consists of a regular grid of cells, each in one of a finite number of states, such as “On” and “Off” . For each cell, a set of cells called its neighborhood is defined relative to the specified cell. An initial state (time t=0) is selected by assigning a state for each cell. A new generation is created (advancing t by 1), according to some fixed rule (generally, a mathematical function) that determines the new state of each cell in terms of the current state of the cell and the states of the cells in its neighborhood. For example, the rule might be that the cell is “On” in the next generation if exactly two of the cells in the neighborhood are “On” in the current generation, otherwise the cell is “Off” in the next generation. Typically, the rule for updating the state of cells is the same for each cell and does not change over time, and is applied to the whole grid simultaneously, though exceptions are known.

…..yep! Basically – each cell can be alive or dead. Once in a generation, each cell looks at it’s surrounding cells, and dies if it is lonely or overcrowded. If a dead cell has an optimum amount of neighbors, it will come to life! Each generation, all the cells which have come to life will sound a note. The notes are assigned based on the cell’s y position, and are all in the pentatonic scale.

There’s a few controls at the bottom which change how things work too.

• Start/Stop – Starts/Stops the automation.
• Export – Exports the current pattern to the clipboard. You can send it to friends, or save it for later, then load in with the load button.
• Clear down – Stop and clear the current pattern.
• Law Mode – An error when coding the cell rules gave this other odd mode.
• Skip Audio – Just show the cell animations.
• Sing Dead – Instead of singing the recently revived notes, sing for the recently deceased.
• Note duration – Alter the system speed.

Also, along the top there are banks of preset systems. Click play to start a saved pattern, and click assign to assign the pattern currently displayed to that button. You can also trigger each pattern with the keyboard keys 1-8.

When you press Export, your pattern is automatically copied to the clipboard, so you can save it, or share it with people. Here’s a pattern I made – you can load it by pasting it into the load box, and pressing Load!

1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,2 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,2 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,2 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,2 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,2 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,1 ,1 ,2 ,2 ,2 ,2 ,2 ,2 ,1 ,1 ,2 ,2 ,2 ,2 ,2 ,2 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,2 ,1 ,1 ,1 ,1 ,1 ,1 ,2 ,1 ,2 ,2 ,1 ,1 ,1 ,1 ,2 ,2 ,2 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,2 ,1 ,2 ,1 ,2 ,2 ,1 ,2 ,1 ,2 ,1 ,1 ,1 ,1 ,1 ,1 ,2 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,2 ,1 ,1 ,1 ,1 ,2 ,1 ,2 ,2 ,2 ,2 ,1 ,1 ,1 ,1 ,1 ,2 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,2 ,1 ,2 ,1 ,2 ,2 ,1 ,2 ,1 ,2 ,1 ,1 ,1 ,1 ,1 ,1 ,2 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,2 ,1 ,1 ,1 ,1 ,1 ,1 ,2 ,1 ,2 ,2 ,1 ,1 ,1 ,1 ,2 ,2 ,2 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,1 ,1 ,2 ,2 ,2 ,2 ,2 ,2 ,1 ,1 ,2 ,2 ,2 ,2 ,2 ,2 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,2 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,2 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,2 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,2 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,2 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1

HINT – When drawing patterns, symmetrical patterns seem to evolve nicely.

The app is fully compatible with Flash Midi Server (my Flash to MIDI audio interface app) – it checks to see if it is running when the app is launched. If it’s not, then it uses fancy Flash Player 10 dynamic audio! I’m hoping to roll this out to the Flash Midi Server class soon – so any app which tried to access the midi server and fails, will use the dynamic audio as a backup. I’ll keep you posted!

In case you missed it, you can download the app here – it weighs in at just 79kb including icons! The screenshot images above are 79k! If you don’t have Adobe Air installed, the link will prompt you to download that too.

I’d love to hear what you think of it – and see any patterns you come up with, so please post them in the comments.
Have fun!
Law.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS”
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

## VIMEO LIKES

The other day I had a little time on my hands, so I decided to make a Vimeo video explorer.

From the beginning, Vimeo was created by filmmakers and video creators who wanted to share their creative work, along with intimate personal moments of their everyday life. As time went on, like-minded people came to the site and built a community of positive, encouraging individuals with a wide range of video interests. We hope that you feel inspired to show us both your creative side as well as your friendly side.

### What is a ‘like’?

A ‘like’ is quick and friendly way to let a video creator know that you appreciate or like his or her video.

### What is the point of liking a video?

‘Liking’ a video is simple way to let other users know that you enjoy their videos. Once you look around Vimeo, you’ll quickly start to find videos that you enjoy. By ‘liking’ a video you are helping to promote content to your contacts and subscribers as well as giving that video a creator a nice feeling.

So the Vimeo Explorer site looks up all the videos a user has “liked” – then displays their thumbnails in this semi-3D grid. You can then click a thumbnail to read the details of that video – and click again to watch the video.

There’s a few weird bugs in there still – sometimes the description doesn’t match the selected video, and the embedded vimeo player has a few odd quirks of its own. But on the whole, I was quite pleased with how it turned out.

As well as trying the Vimeo API, I got the chance to try out some cool effects, such as text to speech conversion and animated displacement maps.
See – http://wonderfl.net/c/rgyc and http://wonderfl.net/c/tLMY for source code demos.

The page is set to default to my personal Vimeo Likes – but by passing in any Vimeo user’s ID, you can load theirs.

Hopefully you’ll find it a fun way of exploring the videos liked by various people.
Cheers.
Lawrie.

## New game – PuzzBox

I’ve finally got all the contract details sorted with one of my new games – PuzzBox, a stylish little Simon-esque puzzle game – sponsored by the guys over at BubbleDevil.

It’s a basic “copy the number pattern as it gets longer” memory puzzle game – but I’ve jazzed it up with some PV3D, particle effects and some displacement maps which give a nice glitchy effect.

Give it a play and let me know what you think.

## Constellation – A flocking experiment

This week I saw Flight 404’s “Swarm Behavior” on vimeo –

Swarm behavior from flight404 on Vimeo.

Yet another awesome video from Robert, using his Cinder framework. Cool!
In the description, he mentions the particle’s behavioral rules –

1) If I am far away from my neighbors, move towards them.
2) If I am too close to my neighbors, move away from them.
3) If I am neither too close or too far from my neighbors, move with them.

So I decided to try and implement these rules in Flash. The idea changed a few times, and ended up looking like an interactive constellation app. So here it is! It’s still pretty rough around the edges – but I’m quite pleased with how it’s developing.

See and edit the code over on Wonderfl

CODE

```package{

[SWF(width="465", height="465", frameRate="50")]

import flash.events.*;
import flash.events.KeyboardEvent;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.DisplayObject;
import flash.display.MovieClip;
import flash.display.Stage;
import flash.geom.Point;
import flash.filters.BlurFilter;
import flash.filters.ColorMatrixFilter;
import flash.filters.ConvolutionFilter;
import flash.filters.GlowFilter
import flash.text.TextField;
import com.bit101.components.*;

public class BFCWonderfl extends MovieClip {

//Vars -
//You can play with these ones -
private var numBoids:int=20;
//Boids closer than this will feel crowded!
private var minDist:int=90;
//Boid further away than another than this will be lonely!
private var maxDist:int=100;
//This is how fast the boids can move. TOP SPEED!
private var maxSpeed:Number = 3;
//This is how much boids influence each other - lower number = more influence
private var divideBy:int=100;
//Shall the boids slow down with friction?
private var enableFriction:Boolean = true;
private var friction:Number = 0.9;
//Settle down - if they're not too close and not too far away from their friends - they'll just stop
private var settleDown:Boolean = false;

private var boidColour:uint = 0xffffff;
private var lineColour:uint = 0xffffff;
private var bgColour:uint   = 0x000033;

private var glow:GlowFilter = new GlowFilter();
private var glowColour:uint = 0x99ffff;

//But you should probably leave these as is -
private var boidArray:Array=[];
private var doMidi:Boolean = false;
private var BMD:BitmapData = new BitmapData(stage.stageWidth,stage.stageHeight-menuHeight, false, bgColour);
private var BF:BlurFilter = new BlurFilter(5,5,1);
private var Bit:Bitmap = new Bitmap(BMD);
private var bitHolder:MovieClip = new MovieClip;
private var ballHolder:MovieClip = new MovieClip;
private var isMouseDown:Boolean = false;
private var TB:TextField = new TextField();
private var myCheckBox1:CheckBox;
private var myCheckBox2:CheckBox;
private var mySlider1:HSlider;
private var mySlider2:HSlider;
//Boid Flock Class
public function BFCWonderfl():void{
trace("Init!");

glow.color = glowColour;
glow.alpha = .5;
glow.blurX = 5;
glow.blurY = 5;

ballHolder.filters = [glow];

TB.y = 0;
TB.width = stage.stageWidth-10;
TB.height = 75;
TB.selectable = false;
TB.text = "Constellation by Lawrie\nhttp://www.LawrieCape.co.uk\nSpace to add a boid at mouse - click to attract - any other key to reset.\n\nADD MINIMAL COMPS HERE - MIN MAX sliders and Friction Settle checkboxes";

myCheckBox1 = new CheckBox(this,5,50,"Friction?",updateVals);
myCheckBox1.selected = true;
myCheckBox2 = new CheckBox(this,5,70,"Settle?",updateVals);
var sLabel:Label  = new Label(this,75,45,"Min size");
var sLabel2:Label = new Label(this,75,65,"Max size");

mySlider1 = new HSlider(this,125,50,updateVals);
mySlider2 = new HSlider(this,125,70,updateVals);

mySlider1.setSliderParams(1,200,75);
mySlider2.setSliderParams(1,200,100);

ballHolder.mouseEnabled  = false;
ballHolder.mouseChildren = false;
bitHolder.alpha=1;

BMD.fillRect(BMD.rect, bgColour);

//makeBoids(numBoids);
}

private function makeASingleBoid(e:KeyboardEvent):void{
if(e.keyCode==32){
makeBoids(1,mouseX,mouseY);
}
else{
reset();
}
}

private function mouseIsDown(e:Event):void{
isMouseDown = true;
}
private function mouseIsNotDown(e:Event):void{
isMouseDown = false;
}

private function makeBoids(makeXBoids:int, bX:Number = 0, bY:Number = 0):void {
for (var i:int=0; imaxDist) {
B.speedX-=B.distToB2X/divideBy;
B.speedY-=B.distToB2Y/divideBy;
}
//2) If I am too close to my neighbors, move away from them.
else if (B.distToB2stage.stageWidth){
B.x=stage.stageWidth-B.speedX;
B.speedX*=-friction;
}
else if(B.x<0){
B.x=-B.speedX;
B.speedX*=-friction;
}
B.speedY*=-friction;
}
else if(B.y<0){
B.y=-B.speedY;
B.speedY*=-friction;
}

//Limit them to a top speed -
if(B.speedX>maxSpeed){
B.speedX = maxSpeed;
}
else if(B.speedX< -maxSpeed){
B.speedX=-maxSpeed;
}
if(B.speedY>maxSpeed){
B.speedY = maxSpeed;
}
else if(B.speedY< -maxSpeed){
B.speedY=-maxSpeed;
}

if(enableFriction){
B.speedX*=friction;
B.speedY*=friction;
}

//Move them
B.x+=B.speedX;
B.y+=B.speedY;

}
//Draw into the BMD

BMD.draw(ballHolder);
//Apply a blur?
BMD.applyFilter(BMD,BMD.rect,new Point(0,0),BF);
}

private function reset():void{
removeEventListener(Event.ENTER_FRAME, updateBoids);
for (var i:int=0; i

```