Phil Trelford's Array
POKE 36879, 255

Pong

January 22, 2012 14:59 by phil

It’s a bit of a long story. A chain of events would unfurl that would lead me inextricably to writing a clone of a 70s video game. It started a few weeks ago while exploring early 90s dance tracks on Spotify, when I happened upon the seminal EP - Clonks Coming by the Sweet Exorcist. Later a lack of content on Spotify would push me towards YouTube and to find a hypnotic collage of Space Invaders, Beach Balls, Pong and the BBC test card girl.

 

Tapping along to the retro beeps on the train to London, a couple of white rectangles started moving up and down with the keyboard and a small white square began floating diagonally, and then the train reached King’s Cross. Much later a copy of RetroActivity would arrive in the post and I would return to the rectangles and make the white square bounce. Well, not before I had spent a few hours playing with Rebirth. The code is posted as an F# Snippet and fits happily in just under 100 lines. You can play in the browser if you have the Silverlight plug-in installed, just click inside to start the game.

Player 1 keys 'Q' - up, 'A' - down. Player 2 keys 'P' - up, 'L' – down.


Today I added a few beeps and a score, and put the project up on BitBucket. I started out trying the new SoundEffect classs in Silverlight 5 that promises low latency sound but unfortunately it seems a bit temperamental and I had to switch to using the old MediaElement class.

There’s a couple of reusable routines that are specific to gaming, the first is to know what keys are pressed at any instant in time:

type Keys (control:Control) =
    let mutable keysDown = Set.empty  
    do  control.KeyDown.Add (fun e -> keysDown <- keysDown.Add e.Key)
    do  control.KeyUp.Add (fun e -> keysDown <- keysDown.Remove e.Key)
    member keys.IsKeyDown key = keysDown.Contains key

The second is to synchronize the game updates with Silverlight’s rendering:

let run rate update =
    let rate = TimeSpan.FromSeconds(rate)
    let lastUpdate = ref DateTime.Now
    let residual = ref (TimeSpan())
    CompositionTarget.Rendering.Subscribe (fun _ -> 
        let now = DateTime.Now
        residual := !residual + (now - !lastUpdate)
        while !residual > rate do
            update(); residual := !residual - rate
        lastUpdate := now
    )

If you’re interested in playing and making simple games, or even just coding, why not pop down to Skills Matter in London this Thursday for a PacMan Kata.

Winking smile


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

PacMan Kata

January 11, 2012 11:37 by phil

F#unctional LondonersThe F#unctional Londoners Meetup Group will be starting 2012 with a code Kata on Thursday January 26th at 6:30pm at Skills Matter.

 
Kata

The term Kata comes from martial arts. A code Kata is a short programming exercise for practicing an aspect of software development.

C64_explodingfistBack in November in the Programming with the Stars session at the Progressive F# Tutorials our celebrities Mark Needham and Mark Seemann took on the Tennis Kata, first in C# and then F#.

As the two Mark’s talked through their solutions a number of people worked on their own versions, 2 of which you can see on the F# Snippets site:


PacMan
Scanning over the Kata catalogue for ideas the PacMan Kata bit me immediately.

    Pacman finds himself in a grid filled with monsters. Will he be able to eat all the dots on the board before the monsters eat him?

    maze

    To get things started I’ve built up a maze and some graphics. You can see an example over on F# Snippets that runs in the browser on http://tryfsharp.org which uses Silverlight: PacMan Maze

    I’ve also created a repository on BitBucket with sample projects for Visual Studio 2010 targeting WPF, Silverlight and HTML/JavaScript.

    The Javascript version uses the Pit compiler, you can see it running here. (Keys Q/A/Z/X *only in IE)

     


    Look forward to seeing you at the event.


    Tags:
    Categories: F# | Silverlight | WPF | .Net | JavaScript
    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 (4) | Comment RSSRSS comment feed