Phillip Trelford's Array

POKE 36879,255

Game of Life

Last week I had the pleasure of attending Software Craftsmanship 2010 at the magnificent Bletchley Park mansion on a gloriously sunny autumn’s day.

BletchleyPark

One of the great sessions I attended was Michael Hunger’s:

Using the Game Of Life to code, discuss language, paradigms and approaches

Michael used a video of Jon Conway himself to explain the rules; which he followed up by showing a very interesting implementation using APL. Afterwards we all paired up to try implementations in various languages. After about half an hour my pair came up with the following F# implementation.

Initialise a board as a 2D Array:

let width, height = 12,12
let board = Array2D.init width height (fun x y -> 0)

Computing the next generation of life requires finding the neighbours of a specified cell:

let computeNeighbours x y (board:int[,]) =
    let getValue (x,y) =
        let x = (x + width) % width
        let y = (y + height) % height
        board.[x,y]
    [
        -1,-1;0,-1;1,-1;
        -1,0;      1,0;
        -1,1 ;0,1;1,1;  
    ]
    |> Seq.map (fun (dx,dy) -> x+dx,y+dy)
    |> Seq.map getValue
    |> Seq.sum

To compute the next generation the current board is mapped to a new one, computing life  by matching the result of the compute neighbours function to the rules of life:

let doGeneration board =
    board 
    |> Array2D.mapi (fun x y n ->
        match n, computeNeighbours x y board with
        | _, 3 -> 1
        | n, 2 -> n
        | _, _ -> 0
    )

The board is shown to both the console and Visual Studio output window:

let show (board:int[,]) =
    for y = 0 to height-1 do    
        for x = 0 to width-1 do
            let v = if board.[x,y] = 0 then '0' else '1'
            Console.Write v
            Debug.Write v
        Console.WriteLine ()
        Debug.WriteLine ""
    Console.WriteLine(String('-',width))
    Debug.WriteLine(String('-',width))

Finally the board is set up and a number of generations are run:

do  [7,7;8,7;9,7;9,6;8,5]        
    |> List.iter (fun (x,y) -> board.[x,y] <- 1)
do  let mutable current = board
    for i = 1 to 10 do
        show current
        current <- doGeneration current
    done  

A visually prettier implementations was achieved using JavaScript and HTML during the exercise. So just for fun I tried running the F# code inside WebSharper (which converts F# code directly to JavaScript). A few minor changes required:

  • The 2D Array for the board was replaced with a Jagged Array
  • The output was converted to HTML
  • The loop changed to an Asynchronous Workflow

You can see the WebSharper version running here: http://trelford.com/life

Coincidentally Adam Granicz of Intellifactory, who was very recently awarded an F# MVP, will be giving a talk about his WebSharper product this Tuesday October 12th; along with Can Erten on Backtracking, for the Functional Londoner’s Meetup Group at Skills Matter!

GameOfLife.fs (1.36 kb)

GameOfLifeWebSharper.fs (2.55 kb)

Comments (1) -

Pingbacks and trackbacks (1)+

Comments are closed