Thursday, 19 March 2009

Too LINQy?

This post contains a tale of two methods. Well, more precisely, a tale of one method implemented in two different ways -- once using LINQ-based functional-fu, and once using old school procedural code.

Recently I was pairing on a task that required us to keep a running average of multiple sets of samples that came through our app. Unfortunately it was more than likely that some sets of samples would be different lengths (depending on exactly when sampling stopped). In these situations where we were missing samples the requirements were to leave the averages for the missing samples unchanged. When we had extra samples, we should use them as the new average at that position. Here's some tests that hopefully show what we were trying to do:

[Test]
public void ShouldAverageFirstTwoLotsOfSamples() {
    var firstSamples = new float[] { 1, 2, 3 };
    var secondSamples = new float[] { 3, 4, 5 };
    var expectedAverages = new float[] {2, 3, 4};
    _averager.AddSamples(firstSamples);
    _averager.AddSamples(secondSamples);
    Assert.That(_averager.GetAverages(), Is.EqualTo(expectedAverages));
}  

[Test]
public void ShouldAddExtraSamplesToAverages() {
    var firstSamples = new float[] { 1, 2, 3 };
    var secondSamples = new float[] { 3, 4, 5, 2 };
    var expectedAverages = new float[] { 2, 3, 4, 2 };    
    /* ... snip ... */
}

[Test]
public void ShouldHandleShorterNumberOfSamples() {
    var firstSamples = new float[] { 1, 2, 3 };
    var secondSamples = new float[] { 3, 4 };
    var expectedAverages = new float[] { 2, 3, 3};
    /* ... snip ... */
}

A LINQ implementation

After a brief flurry of for looping, we decided to muck around with LINQ to filter and transform the sets of data in a pseudo-functional kind of way.

public class AverageCalculator {
    private float[] _averages = new float[0];
    private uint _numberOfAverages;    

    public void AddSamples(float[] samples) {
        _numberOfAverages++;
        var numberOfNewSamples = samples.Length;
        var numberOfSamplesInLastAverage = _averages.Length;
        var leftOverSamples = samples.Skip(numberOfSamplesInLastAverage);
        var leftOverAverages = _averages.Skip(numberOfNewSamples);

        _averages = _averages
            .Take(numberOfNewSamples)
            .Select(
                (average, sampleIndex) => CalculateNewAverage(average, samples[sampleIndex], _numberOfAverages)
            )
            .Concat(leftOverAverages)
            .Concat(leftOverSamples)
            .ToArray();
    }

    private float CalculateNewAverage(float oldAverage, float newSample, uint totalSamples) {
        return oldAverage + (newSample - oldAverage) / totalSamples;
    }

    public float[] GetAverages() {
        return _averages;
    }
}

Stepping through the logic, we take a maximum of numberOfNewSamples from the running _averages, then calculate the new averages based on each new sample. To handle the possibility of mismatched array sizes, we concatenate any left over items from each array. In reality, one of these arrays of left overs will be empty (depending on which array is larger).

My first thought once the tests went green was "wow that's evil!", but compared with the procedural approach we started with, this one really began to grow on me. It was surprisingly easy to write, but I was concerned about its readability (initially we had the local variables in AddSamples(...) inlined, but we extracted them out to try and make it more readable). We decided to test out the procedural equivalent and see if that was any clearer.

A procedural implementation

public void AddSamples(float[] samples) {
    _numberOfAverages++;

    var largestArray = (samples.Length >= _averages.Length) ? samples : _averages;
    var smallestArray = (samples.Length >= _averages.Length) ? _averages : samples;

    var newAverages = new float[largestArray.Length];
    for (int i = 0; i < newAverages.Length; i++) {
        newAverages[i] = (i < smallestArray.Length) 
                            ? CalculateNewAverage(_averages[i], samples[i], _numberOfAverages) 
                            : largestArray[i];
    }

    _averages = newAverages;
}

The logic used here is to find which array is largest, and to create a new array of that size. We loop through every possible index, calculating the average until all of the smallest array is used, then append the left overs from the largest array. This seems quite neat to me, although I should mention that this is a refactored, sanitised version (as is the LINQ version). The initial implementation was more verbose and the logic less clear, and it somehow managed to take longer to get it to a state where the tests all passed.

Who's right?

Which approach do you like best? It probably comes down to how much imperative vs. functional programming you've done. (Or you hate both versions of the method, in which case please leave a comment with the correct approach. :)). Imperative programming concentrates on telling the computer how to do something, while functional is more about telling the computer what to do. For example, our LINQ version starts with some data and specifies what transformations we want to make to it. Our second version of the code focuses more on the mechanics -- create an array, loop, check the bounds etc.

The second version's focus on implementation makes it fairly easy to mentally trace through how it works, but how clear is the intention behind the implementation? The LINQ version probably takes a bit more effort to understand how it works (especially as the first exposure most people have to programming tends to be to imperative-style control structures like IF, FOR, WHILE and even GOTO), but what it is doing might be a little clearer.

Overall, I kind of prefer the LINQ version for its faint hint of functional elegance, but on the other hand the procedural version is just so darn familiar and comfortable to read for a C#/Java/C person like me. I'd love to hear any thoughts you have on these approaches, and how you are handling the encroachment of functional concepts into our formerly purely-procedural C# language.

Sunday, 15 March 2009

Garden Race Pt 3: It's GUI time!

This post is part of a series exploring the (very) basics of iterative development using the example of a simple Snakes and Ladders-like game. Links to each post in the series will be added to the index page.

After having a think about top-down and bottom-up design, I concluded that delivering complete vertical slices was more important than whether you started at the top or bottom of the slice. As most of the work in previous iterations has been closer to the bottom of our design, it now seems a good time to start writing some tests around the GUI. This work will form the basis of this iteration.

Confession: I had about 3 attempts at this installment of the series over the last year or so, each time having something crop up that stopped me working on it. Some of this post may be biased by previous attempts, although with my poor memory there shouldn't be too much chance of that. :)

Project status and work for iteration 3

Based on the previous two iterations, all we have left from the original list is the "feature squares" (the snakes and ladders style squares):

  1. A player can roll the die, and then move that many spaces along the board.
  2. A player that ends his or her turn on a "feature square" (a square containing a creature or obstacle), will be moved to the square connected with that feature.
  3. There can be 1-4 players, and each player has their turn in sequence.
  4. A player that reaches the final square wins the game.

We'll leave the pending story on hold for now so we can get to the GUI bits. One thing to notice is that none of these stories, strictly speaking, demand a GUI. So let's add one, in consultation with our customers (i.e. firstborn and I):

  1. Each player's position will be displayed on an 8 x 8 grid of squares.

This should give us enough to get rid of the command line demo code and give the customer something closer to a usable product. It will probably be enough to fill the whole iteration as well, as we may have to revisit some of the original stories and make sure we have exposed them all through our GUI (story 1 for example). I've also managed to miss a fairly major part of story 3 -- there is currently no way to choose how many players there are in the game.

I think this indicates a problem with the approach so far. Imagine having to revisit every story after implementing 50 or so due to a change to the front end. One big thing we are missing that could help us avoid this are acceptance tests. If we had those, the relevant ones would fail and we could test drive out our way back to green. It could also be an indication that we have too much logic in the untested demo app. We were aware of this when we wrote the demo app though, and never intended to keep it around long enough for it to become a problem, so manually rechecking our 3 finished stories shouldn't be too big a deal.

Let's start off using WPF for this, as it's shiny and new (well, compared with standard WinForms), and comes standard with our current .NET 3.5 platform. We'd obviously want to do some more research if doing this for real. I've done practically nothing with WPF to date, so I'm looking forward to publicly humiliating myself throughout the remainder of this post. (Why don't my regular readers look surprised? ;))

Where to start?

I'd like to replace our untested demo code with tested, production code that we can use as a foundation for a GUI. We need to make sure the functionality of our original stories are exposed via the GUI, rather than the demo app. The two things that jump out at me is that we need a way for a player to roll a die, and we also need some way to indicate the end of the game. The actual rules of the game are hopefully captured in our Game class, so with a bit of luck we'll only need to verify our UI's interaction with that class. Then to complete our story we'll need to make sure each player's position is displayed on the game board.

I'd love to avoid jumping straight to an MVP-style pattern here, in favour of starting from first principles and refactoring to patterns like that when it becomes painfully obvious we need to. However I have absolutely no idea how to do that test-first, so let's try the standard route of creating a GamePresenter that will mediate between our Game model and our UI. We'll start off with the basics of rolling the die and move on from there.

Rollin', rollin', rollin'

What should happen when a player interacts with the view to roll the die? Well for starters our model class, Game, should probably be updated to reflect the fact the player is having their turn. We don't have an actual GUI button to press, but we know that we can fire off an event when a GUI button is clicked. If we add this event to a view interface, and our real GUI implements that interface, then we'll be able to write automated tests for large number of interactions with our GUI via its interface. Our GUI implementation itself should be fairly basic and concentrate on rendering and widgets rather than application logic (see the Humble Dialog Box [PDF]).

public class GamePresenterSpec {
    [Fact]
    public void Game_should_update_when_roll_die_is_clicked() {
        var fakeGameView = MockRepository.GenerateStub<IGameView>();
        var fakeGame = MockRepository.GenerateMock<IGame>();
        var gamePresenter = new GamePresenter(fakeGameView, fakeGame);

        fakeGameView.Raise(view => view.RollClicked += null, this, EventArgs.Empty);
        fakeGame.AssertWasCalled(game => game.Roll(Arg<int>.Is.Anything));
    }
}

This test isn't really saying much, just that game.Roll(...) should be called with any argument, which is how a player currently has their turn in our model. We need to extract an IGame interface for this, and also create an IGameView and a GamePresenter.

 
public class GamePresenter {
    public GamePresenter(IGameView view, IGame game){}
}

public interface IGameView {
    event EventHandler RollClicked;
}

public interface IGame {
    void Roll(int dieValue);
}

Our test compiles, but fails. We'll fix that now.

public class GamePresenter {
    private readonly IGame _game;
    public GamePresenter(IGameView view, IGame game) {
        _game = game;
        view.RollClicked += view_RollClicked;
    }
    void view_RollClicked(object sender, EventArgs e) {
        _game.Roll(1);
    }
}

Our test now passes, and as I can't see much refactoring to do, let's try the next test. Looking at what we have so far, the most obvious deficiency to me seems to be that we are just rolling 1 in the game. We really need a die roll here (1d6 :)), but that would involve random numbers running around our tests causing havoc. So let's fake a DieRoller that we can use to get known values during tests, and random values during the actual game.

 public class GamePresenterSpec {
    private IGameView fakeGameView;
    private IGame fakeGame;
    private IDieRoller fakeDieRoller;

    private GamePresenter CreateGamePresenterAndDependencies() {
        fakeGameView = MockRepository.GenerateStub<IGameView>();
        fakeGame = MockRepository.GenerateMock<IGame>();
        fakeDieRoller = MockRepository.GenerateStub<IDieRoller>();
        return new GamePresenter(fakeGameView, fakeGame, fakeDieRoller);            
    }
    /* ... snip ... */
    [Fact]
    public void Game_should_roll_value_from_die_when_roll_die_is_clicked() {
        CreateGamePresenterAndDependencies();
        int dieFace = 3;
        fakeDieRoller.Stub(die => die.Roll()).Return(dieFace);

        RaiseRollClickedEventOnView();
        fakeGame.AssertWasCalled(game => game.Roll(dieFace));
    }

    private void RaiseRollClickedEventOnView() {
        fakeGameView.Raise(view => view.RollClicked += null, this, EventArgs.Empty);
    }
}

The new test stubs out a known value for IDieRoller.Roll(), then makes sure that will get passed to our Game. I've also shown that we've extracted the common fixture setup code into a CreateGamePresenterAndDependencies() method, although we'd normally do this refactoring after all the tests get to green (unfortunately this stuff is surprisingly difficult to get into blog-form, so please excuse me taking some licence with presentation).

public class GamePresenter {
    private readonly IGame game;
    private readonly IDieRoller roller;

    public GamePresenter(IGameView view, IGame game, IDieRoller roller) {
        this.game = game;
        this.roller = roller;
        view.RollClicked += view_RollClicked;
     }

    void view_RollClicked(object sender, EventArgs e) {
        game.Roll(roller.Roll());
    }
}

public interface IDieRoller {
    int Roll();
}

And we're back at green. What else can we look at? Well we should probably display the result of the roll to the player. Like our view.RollClicked event, we'll just make our view interface have a method for setting the result of a die roll (say, ShowRollResult(dieFace)), and we'll let our actual GUI implementation worry about translating this message to the display.

[Fact]
public void View_should_show_result_of_roll() {
    CreateGamePresenterAndDependencies();
    int dieFace = 2;
    fakeDieRoller.Stub(die => die.Roll()).Return(dieFace);
    RaiseRollClickedEventOnView();
    fakeGameView.AssertWasCalled(view => view.ShowRollResult(dieFace));
}
public class GamePresenter {
    private readonly IGameView view;
    /* ... snip ... */
    void view_RollClicked(object sender, EventArgs e) {
       var dieValue = roller.Roll();
       game.Roll(dieValue);
       view.ShowRollResult(dieValue);
    }
}

Whose turn is it anyway?

Tests pass, and can't see any refactoring to do. It is probably important to show whose turn it is, so let's try that now. First up, we need to show the current player when the game is first started.

[Fact]
public void View_should_show_current_player_when_game_is_created() {
    CreateGamePresenterAndDependencies();
    var currentPlayer = 1;
    fakeGame.Stub(game => game.CurrentPlayer).Return(currentPlayer);
    fakeGameView.AssertWasCalled(view => view.SetCurrentPlayer(currentPlayer));

}

Oops, this won't work. We are using CreateGamePresenterAndDependencies() to create everything in one step, but then we go on to stub out the game.CurrentPlayer call. Let's separate the dependency creation from the creation of the subject under test.

[Fact]
public void View_should_show_current_player_when_game_is_created() {
    CreateGameDependencies();
    var currentPlayer = 1;
    fakeGame.Stub(game => game.CurrentPlayer).Return(currentPlayer);
    new GamePresenter(fakeGameView, fakeGame, fakeDieRoller);
    fakeGameView.AssertWasCalled(view => view.SetCurrentPlayer(currentPlayer));
}
Note: this kind of mucking around with the fixture is a drawback of using a fixture-per-class style of test organisation. This seems to be how most people start TDD (myself included), but I think using a fixture-per-scenario approach (more of a BDD style) is easier to use and probably to learn from. I'm using a more BDD-like approach for my real code now, and am finding it generally makes TDD much easier. I still haven't got it right yet though, so both for that reason and for consistency I'll stick with fixture-per-class for this post.

To get this passing we'll need to pull up Game.CurrentPlayer to the IGame interface, then update the GamePresenter constructor to pass this information to the view.

public GamePresenter(IGameView view, IGame game, IDieRoller roller) {
    this.view = view;
    this.game = game;
    this.roller = roller;
    view.RollClicked += view_RollClicked;
    view.SetCurrentPlayer(game.CurrentPlayer);
}

That handles the start of the game, but we also need to change whose turn it is after each roll.

[Fact]
public void View_should_show_current_player_after_a_roll() {
    CreateGamePresenterAndDependencies();
    var player = 2;
    fakeGame.Stub(game => game.CurrentPlayer).Return(player);
    RaiseRollClickedEventOnView();
    fakeGameView.AssertWasCalled(view => view.SetCurrentPlayer(player));
}

/* In GamePresenter: */
void view_RollClicked(object sender, EventArgs e) {
    var dieValue = roller.Roll();
    game.Roll(dieValue);
    view.ShowRollResult(dieValue);
    view.SetCurrentPlayer(game.CurrentPlayer);
}
Ugh: Looking back through my notes while I'm typing this up, I have something to the effect of "Seems ugly. Using WPF, shouldn't I be binding to the ViewModel/PresentationModel?". This is fairly important -- I'm going to blatantly end up misusing WPF in this case because I'm not taking advantage of any of the nice databinding features it has. Let's press on though, if for no reason other than to point at the author and laugh at his incompetence. Maybe we can salvage what we have later on.

Where am I?

Ostensibly the story we are working on is to display each player's position on the grid. It should not be too hard to update each player's position after they take their turn. Because I haven't done enough of a spike to see how our view should work, let's just assume we have a MovePlayerMarker(...) method on the view that will handle any animation or display stuff we need.

[Fact]
public void Should_update_players_position_after_roll() {
    CreateGamePresenterAndDependencies();
    var player = 1;
    var newSquare = 10;
    var oldSquare = 5;
    fakeGame.Stub(game => game.CurrentPlayer).Return(player);
    fakeGame.Stub(game => game.GetSquareFor(player)).Return(oldSquare);
    fakeGame.Stub(game => game.GetSquareFor(player)).Return(newSquare);
    RaiseRollClickedEventOnView();

    fakeGameView.AssertWasCalled(view => view.MovePlayerMarker(player, oldSquare, newSquare));
}

/* In GamePresenter: */
void view_RollClicked(object sender, EventArgs e) {
    var dieValue = roller.Roll();
    var player = game.CurrentPlayer;
    var startingSquare = game.GetSquareFor(player);
    game.Roll(dieValue);
    view.ShowRollResult(dieValue);
    view.SetCurrentPlayer(player);
    view.MovePlayerMarker(player, startingSquare, game.GetSquareFor(player));
}

We are really starting to run into some of the limitations of our Game class now. As soon as a player rolls the die in the game, the positions and current player changed, so we need to save this information prior to calling game.Roll(...). This may indicate we may have an overly intimate implementation. We need to know all kinds of stuff about the Game implementation to use it, which is making our view_RollClicked(...) code fairly ugly as it steps through the procedure of running the game. Maybe we should instead expose a list of player positions that we could bind to instead?

It looks like we are due for some refactoring, but I'm not really sure how to proceed with that. Instead of letting that hold us up as we worry about all the potential solutions we could pick, let's put that off and whack up a quick view implementation and see if that helps at all.

This time I'm playing to win!

Before we make that final step to the GUI implementation we still need to handle one more case from our original console app -- winning the game. Here's two tests and an implementation that passes them both (although written one at a time, of course!).

[Fact]
public void Should_show_winner_when_game_is_finished() {
    CreateGamePresenterAndDependencies();
    int player = 3;
    fakeGame.Stub(game => game.CurrentPlayer).Return(player);
    fakeGame.Stub(game => game.IsFinished).Return(true);
    RaiseRollClickedEventOnView();
    fakeGameView.AssertWasCalled(view => view.ShowWinner(player));
}

[Fact]
public void Should_disable_die_roll_when_game_is_finished() {
    CreateGamePresenterAndDependencies();
    fakeGame.Stub(game => game.IsFinished).Return(true);
    RaiseRollClickedEventOnView();
    fakeGameView.AssertWasCalled(view => view.DisableDieRolls());
}

/* In GamePresenter: */
void view_RollClicked(object sender, EventArgs e) {
    var dieValue = roller.Roll();
    var player = game.CurrentPlayer;
    var startingSquare = game.GetSquareFor(player);
    game.Roll(dieValue);
    view.ShowRollResult(dieValue);
    view.SetCurrentPlayer(player);
    view.MovePlayerMarker(player, startingSquare, game.GetSquareFor(player));
    if (game.IsFinished) {
        view.DisableDieRolls();
        view.ShowWinner(player);
    }
}

The worst, most blatant misuse of WPF in history!!!1!

I'm not proud of what you are about to see. In fact, I'm rarely proud of any of the crud I write on this blog, but if my normal stuff is a 2 out of 10, this is about a -30 * 1012. My local check-in comment for this stuff is "Embarrassingly bad GUI using WPF controls", which is pretty accurate. I'm using WPF controls, but saying this is WPF is like wrapping a 1000 line main method in a class declaration and calling it OO. But I did promise a GUI of sorts, so let's try and get something graphical working.

Don't do this! In case you missed my subtle hints throughout this post, don't repeat what you are about to see. It would be pure evil if it weren't for its lack of competence. Don't bother donning the goggles, they'll do nothing.

First, I've created a new DaveSquared.GardenRace.Gui WPF project to house this hideous monstrosity. I've created a new WPF form called GardenRaceView. Here's the XAML.

<Window x:Class="DaveSquared.GardenRace.Gui.GardenRaceView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="GardenRaceView" Height="526" Width="716">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="528*" />
            <ColumnDefinition Width="166*" />
        </Grid.ColumnDefinitions>
        <UniformGrid Name="gameBoard" Rows="8" Columns="8" />
        <Label Grid.Column="1" Height="28" Margin="0,12,46,0" Name="currentPlayer" VerticalAlignment="Top">currentPlayer</Label>
        <Button Grid.Column="1" Height="23" Margin="46,46,46,0" Name="rollDieButton" VerticalAlignment="Top" Click="rollDieButton_Click">Roll</Button>
        <Label Grid.Column="1" Height="28" Margin="0,86,46,0" Name="rollResult" VerticalAlignment="Top">rollResult</Label>
        <Ellipse Visibility="Hidden" Name="player1Marker" Stroke="Black" Height="30" Margin="5, 0, 0, 0" HorizontalAlignment="Left" VerticalAlignment="Top" Fill="Red" Width="30" />
        <Ellipse Visibility="Hidden" Height="30" HorizontalAlignment="Left" Name="player2Marker" Stroke="Black" Fill="Blue" VerticalAlignment="Top" Width="30" />
    </Grid>
</Window>
The game screen in VS 2008's design view. It looks even worse when running for real!

This gives us two columns to work with: The left hand column to hold the board, and the right hand column for status and game controls. Let's wire this thing up. Here is the xaml.cs file. This was originally wired up piece by piece, manually testing in between (we don't have automated tests for the view remember).

public partial class GardenRaceView : Window, IGameView {
    public GardenRaceView() {
        InitializeComponent();
        FillSquares();
        MoveToStartingPositions();
        var gameModel = new Game(64, 2);
        new GamePresenter(this, gameModel, new DieRoller());
    }

    private void MoveToStartingPositions() {
        MovePlayerMarker(1, 0, 0);
        MovePlayerMarker(2, 0, 0);
    }

    private void FillSquares() {                        
        for (var squareNumber=1; squareNumber <= 64; squareNumber++) {
            var square = new StackPanel();
            var squareLabel = new Label();                
            squareLabel.Content = squareNumber;
            square.Children.Add(squareLabel);
            gameBoard.Children.Add(square);
        }
    }

    public event EventHandler RollClicked;

    private void OnRollClicked() {
        EventHandler rollClickedHandler = RollClicked;
        if (rollClickedHandler != null) rollClickedHandler(this, EventArgs.Empty);
    }

    public void ShowRollResult(int dieFace) {
        rollResult.Content = "You rolled a " + dieFace;
    }

    public void SetCurrentPlayer(int player) {
        currentPlayer.Content = "Player " + player + "'s turn.";
    }

    public void MovePlayerMarker(int player, int fromSquare, int toSquare) {            
        var markerForPlayer = GetMarkerForPlayer(player);
        markerForPlayer.Visibility = Visibility.Visible;
        
        var containerForMarker = (Panel) markerForPlayer.Parent;
        containerForMarker.Children.Remove(markerForPlayer);

        if (toSquare >= gameBoard.Children.Count) toSquare = gameBoard.Children.Count-1;
        var newSquare = (StackPanel) gameBoard.Children[toSquare];
        newSquare.Children.Add(markerForPlayer);            
    }

    private Shape GetMarkerForPlayer(int player) {
        if (player == 1) { return player1Marker; }
        if (player == 2) { return player2Marker; }
        throw new ArgumentOutOfRangeException();
    }

    public void ShowWinner(int winningPlayer) {
        MessageBox.Show("Player " + winningPlayer + " wins! Nice work!");
    }

    public void DisableDieRolls() {
        rollDieButton.IsEnabled = false;
    }

    private void rollDieButton_Click(object sender, RoutedEventArgs e) {
        OnRollClicked();
    }
}

If you haven't been blinded yet, the first thing you'll have seen is that we make our form implement our IGameView. The majority of these implementations are trivial: ShowRollResult(...), SetCurrentPlayer(...), ShowWinner(...), DisableDieRolls(), and firing the RollClicked event. The MovePlayerMarker(...) is fairly hideous, but it is pretty much all view-specific logic (except the highlighted code that does bound checking on the player's positions).

There is also some code in the constructor to fill our UniformGrid (in the incorrect order mind you), and then the code to instantiate our presenter and model code. I don't really see a pressing need for an IoC container here yet, do you? :)

The only other implementation is the pseudo-random DieRoller which we pass through to our presenter:

internal class DieRoller : IDieRoller {
    Random random = new Random();
    public int Roll() {
        return random.Next(1, 6);
    }
}

Somewhat surprisingly, this manages to actually work (er, well, somewhat work :)).

Screen shot from the game.

On what poor, pitiful, defenseless customers has my monstrosity been unleashed?

So what have we done? Besides unsubscribing from Dave's blog, we also managed to test drive a presenter and unleash a hideous GUI on our unsuspecting customers. We've done a very rough job on this story (my fault, not yours), but we are now displaying players' positions on a grid. The grid is not in the correct order for a snakes and ladders-style game (it is meant to snake around, starting at the bottom of the board and winding its way up to the top), but we can refine this later. We've also replaced our untested, console-only demo app with a tested, hideous bastardisation of WPF.

We've also found lots of new tasks to do. First, learn WPF. Next, refactor this to have a more useful Game class, and maybe change the presenter into more of a presentation model approach so we can use some WPF goodness. We also need to do something about our incomplete story about being able to play with 1 - 4 players -- at present we have 2 players hard coded in. And we also should put in some snake and/or ladder-like squares.

Despite the obvious problems with the current code, I'd like to try and salvage some small glimmer of positivity from this post. We managed to test drive a whole host of GUI-specific functionality, before we even had a forms project. We managed to hook in a thin view on top of that foundation that, despite being ugly, just worked. (Really it did! If I was going to start lieing to you it would have been in an attempt to hide my incompetence during the rest of the post, not for something trivial like this ;)). And last but not least -- um, no, actually they're the only positives I can think of. :)

I hope you can get some value from this post, even if its just a laugh or two at my expense. :) I'd love to hear your thoughts as to whether what we've got here is salvageable, and if so then how you would start evolving it in the right direction. In the meantime, I'm off to read up on WPF.