Phil Trelford's Array
POKE 36879, 255

Pacman Tiles

July 22, 2012 10:11 by phil

Back in January I built a sample Pacman maze script in F# to use at a Pacman Kata evening with the F#unctional Londoners group. Coincidentally there’s another Coding Kata this Thursday 26th July at Skills Matter. Anyway a couple of weeks ago I started playing with the sample again on the train to and from work, filling in some of the gameplay.

You can play the latest version with your cursor keys and 9 lives below:

(Right click to install game to desktop)

 
Windows 8

As the sample runs in Silverlight I thought I’d also try it out on it’s cousin WinRT. WinRT lets you build Metro apps on Windows 8. The transition code wise has been pretty straight forward and I now have a tile for the game appearing on my Windows 8 start page:

One click: From Metro tile to video game

 

WinRT is yet another XAML based framework, and is very similar to Silverlight and WPF. One of the few differences I have encountered has been the namespaces the classes are in. For example in Silverlight the Canvas class is in the System.Windows.Controls namespace and in WinRT it is in Windows.UI.Xaml.Controls namespace. It is possible to target both WinRT and Silverlight from the same source code using conditional directives:

#if NETFX_CORE
using Windows.UI.Xaml.Controls;
#else
using System.Windows.Controls;
#endif

 

Multi-targeting

Multi-targeting Silverlight and WinRT is the route I decided to go down which allowed me to develop the game on my laptop running Windows 7 with Visual Studio 2010. Then I periodically tested it out on a desktop box running the Windows 8 Preview Release using Visual Studio 2012. Visual Studio 2012 does run on Windows 7, however WinRT does not.

The WinRT version of the app is implemented in F# and C#. The game part is written in F# as a portable library and the plumbing in C#. There’s a great walkthrough on Creating a Portable F# Library over on MSDN which describes this direction in some detail.

Code Fragment

When the ghosts are eaten they need to return to the enclosure. I used a flood fill algorithm to mark the shortest route from anywhere in the maze back to the enclosure. The flood fill is started inside the enclosure, the fill number is incremented with each iteration of the fill, so that the shortest route is to follow the lowest number adjacent to the ghost’s current square:

module Algorithm =
    let flood canFill fill (x,y) =
        let rec f n = function
            | [] -> ()
            | ps ->
                let ps = ps |> List.filter canFill
                ps |> List.iter (fill n)
                ps |> List.collect (fun (x,y) -> 
                    [(x-1,y);(x+1,y);(x,y-1);(x,y+1)]
                )
                |> f (n+1)
        f 0 [(x,y)]
 
Full Source

The full source code to the game is publicly available on BitBucket:

A single file playable script version is also available on F# Snippets:


Progressive F# Tutorials 2012 NYC – Day 1

June 10, 2012 22:38 by phil

Last week I flew out to New York for the Progressive F# Tutorials NYC hosted by Skills Matter and organised by Richard Minerich. The event was held in the atmospheric Liberty Hall event space at the Ace hotel in mid-town Manhattan, and not far from the Empire State Building.

liberty_theater-548x174

Keynote

Don Syme kicked off proceedings with a keynote on Being Successful with Functional-first techniques in Finance (you can check out the video of a broadly similar talk at the Progressive .Net Tutorials in London). In the talk Don outlines key areas in which F# is used to solve:

  • Time to market
  • Complexity
  • Correctness
  • Effeciency

F# Koans

Chris Marinos started off the beginner’s track with the excellent F# Koans which aim to teach you F# through testing. Based on the Ruby Koans, Chris provides the F# Koans for free on github.

FSharp Koans Assert Truth


F# Katas

Chris then followed on after lunch with a member of the audience on a data mining Kata where the goals was to extract specific data from a text file. Then I introduced the next Kata, Conway’s Game of Life via an epic video I found on YouTube:

By the end of the session there were plenty of complete implementations including one in OCaml, which is quite close to F#.

Here’s a few blog entries I have with example implementations in F#:

Apparently the 127 character version made a cameo at NDC Oslo on Friday last week too:

r600x600

Thanks to Vagif Abilov for the mention and Richard Dalton for the picture.


Tags:
Categories: F# | .Net | Software Craftsmanship
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

Method Stubs

November 25, 2011 00:34 by phil

I’ve spent the last 2-days of this week on a hands on TDD & Refactoring workshop ran by Jason Gorman. The course comprises of short exercises that you tackle in pairs. The provided machines came with Visual Studio 2010 installed so for most of the exercises my programming pair, Martin Trojer and I, used Visual F#.

One of the exercises was to implement a fictional holiday booking system that would connect to an external flight booking system and an external villa booking system. Holidays for a particular week of the year may only be booked if flights are available and one or more villas. The idea for the exercise was to test the holiday booking system using stubs for the flight and villa booking systems.

Being a Test Driven Development (TDD) course we Test First and Assert First, i.e. we write the test and the assertion before the code to implement the test:

[<Test>]
let ``when no flights are available then no holidays are available`` () =
    // ...
    Assert.AreEqual(holidays, [])

Another practice in XP/TDD is to write the simplest code that will make the test pass. In this case the simplest thing seemed to be to implement a function that gets the available holidays for a specific week given functions that determine flight and villa availability:

[<Test>]
let ``when no flights are available then no holidays are available`` () =
    let holidays = 
        getAvailableHolidays (isFlightAvailable, getAvailableVillas) (2,2013)
    Assert.AreEqual(holidays, [])

Now we implement the functions isFlightAvailable and getAvailableVillas as stubs:

[<Test>]
let ``when no flights are available then no holidays are available`` () =
    let isFlightAvailable _ = false
    let getAvailableVillas _ = ["Mountain Dew"]
    let holidays = 
        getAvailableHolidays (isFlightAvailable, getAvailableVillas) (2,2013)
    Assert.AreEqual(holidays, [])

With the stubs in place we can make the test fail:

let getAvailableHolidays (isFlightAvailable, getAvailableVillas) (week,year) = 
   getAvailableVillas (week,year)

The test fails because we are not checking flight availability. To make the test pass:

let getAvailableHolidays (isFlightAvailable, getAvailableVillas) (week,year) = 
   if isFlightAvailable (week,year) then getAvailableVillas (week,year)
   else []

Our first test passed. Time to refactor. In our test there is some code duplication, the stub functions isFlightAvaialble and getAvailableVillas always return the same value. We can create a method to encapsulate this:

let inline always value _ = value

Then we can use partial application to define a function getHolidaysWhenNoFlights:

[<Test>]
let ``when no flights are available then no holidays are available`` () =
    let getHolidaysWhenNoFlights = 
        getAvailableHolidays (always false, always ["Mountain Dew"])
    let holidays = getHolidaysWhenNoFlights (10,2012)
    Assert.AreEqual(holidays, [])

On to the next test case (which unfortunately passes immediately as the system has now been implemented):

[<Test>]
let ``when flights are available but no villas then no holidays`` () =
    let getHolidaysWhenNoVillas = 
        getAvailableHolidays (always true, always [])
    let holidays = getHolidaysWhenNoVillas (10,2012)
    Assert.AreEqual(holidays, [])

And so on:

[<Test>]
let ``flights and a villa are available then a holiday is available`` () =
    let getHolidays = 
        getAvailableHolidays (always true, always ["Mountain Dew"])
    let holidays = getHolidays (10,2012)
    Assert.AreEqual(holidays.[0], "Mountain Dew")

In F# I find myself starting with functions and then moving to classes if necessary. In C# and Java it seems people tend to start with classes, perhaps because refactoring from a static method to a class is felt to be hard. In F# it’s almost as easy as changing the let keyword to type, and declaring a member. So starting with our function to get available holidays:

let getAvailableHolidays (isFlightAvailable, getAvailableVillas) (week,year) = 
   if isFlightAvailable (week,year) then getAvailableVillas (week,year)
   else []

Refactored to a class:

type AvailableHolidays (isFlightAvailable, getAvailableVillas) = 
    member this.Get(week,year) =
        if isFlightAvailable (week,year) then getAvailableVillas (week,year)
        else []

Just before we ran out of time for this exercise we came up with a simple implementation for spying on method calls:

type Recorder () =
    let mutable xs = []
    member recorder.Record(x) = xs <- box x :: xs
    member recorder.Values = xs

let inline spy (recorder:Recorder) f = fun ps -> recorder.Record(ps); f ps

Which allowed us to check if a the flight booking system is being called with the correct values:

[<Test>]
let ``the flight availability system is passed the correct date`` () =
    let recorder = Recorder ()
    let isFlightAvailableSpy = spy recorder (always true)
    let getHolidays = 
        getAvailableHolidays (isFlightAvailableSpy, always [])
    let holidays = getHolidays (12,2012)
    Assert.AreEqual(recorder.Values,[12,2012])

So no frameworks required for either stubs or spies! .

Overall I felt a function based approach to TDD using F# worked very well, and resulted in a very simple solution.


Tags:
Categories: F# | .Net | Software Craftsmanship
Actions: E-mail | Permalink | Comments (5) | Comment RSSRSS comment feed