Snakes and Ladders Kata

December 2009

I’ve been mentoring a couple of guys at Eden over the last few weeks. They’ve been working away on the Binary Chop kata and it’s been generating some interesting discussions on what Test Driven Development actually is, and how to do it properly.

More on that in another post; today I want to outline the next task I’ve got prepared. Continuing on with the TDD theme, I’ve prepared a basic specification of Snakes and Ladders, using Cucumber features to give a simple outline.

The task is to take this basic github repository and prepare a kata which fully implements the features given using TDD.

If you’d like to try it yourself, feel free! Any patches to the features would be most welcome. Let me know how you get on.

UPDATE: I’ve fixed a bug in the features (thanks nickh) and merged in a patch from ohthatjames to provide some basic support files.

UPDATE: Olly Legg commited a couple of tweaks and improvements.

Share


More articles

Are coding katas really worth it?

Last year I took up Wado-ryu Karate. It’s something that I’ve always wanted to do, and yet never quite got around to. I briefly took it up at university about 15 years ago, and put it down rather too quickly. About a year ago I decided it was time for me to stop saying “I wished I’d learnt it”, and got down to actually learning it.

Karate as a discpline is ancient compared to that of my other discipline, writing software. There are many lessons that we can take from it, and I’m sure I’ll be blogging more about this as I gain more insight. However, one big lesson I’ve learned so far is the value of a Kata.

What is a Kata?

Admittedly, I’d not heard of the term until finding out about the Software Craftsmanship movement a couple of years back. It’s the process of coding a solution to a fixed problem over and over again, trying new things and attempting to gain insight. On first hearing, I liked the concept, but in honesty I thought: “yet another bunch of coders who want to be Samurai!”

On reflection however, and especially after hearing Micah’s viewpoint, I could see the potential value of practicing a certain number of steps over and over. Therefore I decided to give it a go. When trying the technique in 2009, before I started karate, I admit I couldn’t connect katas to better programming performance. I published a checkout kata late last year, and enjoyed working on it. However the jury was out on how much I learnt from it.

That changed when I started Karate.

Katas in Karate

In my particular school, katas are commonplace and begin after your third belt. They are specifically designed to teach certain techniques, and to ensure that your basics are correct (and remain correct over time). So far, I have learnt Pinan Nidan, the first kata in Wado-ryu. It’s designed as a mock fight, where you take on eight imaginary opponents and dispatch them one by one using various techniques.

Technically, this kata contains three types of blocks, two types of stances, one type of punch and a spearhand attack. It’s very simple, and designed to ensure that your body can perform the basics in sequence easily. Once you’ve got the basic moves in the correct order, you then move on to ensuring that your position and strength is good when performing the Kata.

When in a real sparring situation, you then instinctively use parts of the kata to help you. If all you’ve been doing is ‘block, punch, block, punch’ for several hours, then when someone actually comes to hit you, you block correctly and find you’ve thrown a punch without thinking. Watching black belts spar is fascinating: most of what they do is totolly instinctive.

How can we learn from this?

Rolling code without thinking is valuable. I would love to be able to roll code automatically, in the same way that martial artists combine moves in sequence effortlessly. Wouldn’t it be fantastic to be have thoughts and concepts appear on the screen without really even trying? Granted, our tools and methods do change over time, but we need to learn them inside out. Stick to one editor, for example (preferably a decent one). Get to know a framework really well, so that you can make things happen without exercising your brain, leaving maximum energy to think about your problem.

Katas need to be designed well, and operate best as a set. Perhaps what we need on our university courses and apprenticeship schemes is a list of basics (“learn the syntax of Ruby/Haskell/Clojure”), and then a simple problem (kata) to practice a solution for. Rather than have them complete the project and hand it in, they have to perform it in front of an instructor. They might have to repeat this every two weeks. They should be able to perform old projects on demand. These will need to be designed well, so that they offer the maximum learning. A poorly designed Kata is fairly useless.

Please can we get over the ‘coders who want to be samurai’ thing? There are a bunch of starry-eyed coders who would desperately love to be ninjas, and another group who quietly laugh at them. Both are missing the point. In Karate, katas aren’t glamourous; they’re difficult, frustrating and really hard work. But let’s not discard them out of hand! There’s ancient teaching and learning methods here that have proven effectiveness. Let’s learn from them.

I need to think more on this. Perhaps there’s a specific set of katas that is tailored to a particular language that can be designed to really encourage speed of learning and growth. I do believe that a lot of the way we teach programming is inefficient and more about information than practice. Is there a better way?

Read more

Driving out feature ambiguity

Cucumber features are very useful. The ability to spec out what the customer wants in detail in a format they can read and understand really helps to communicatate what needs to be done. This combined with the ability to execute the feature to ensure that it is completed correctly catches many bugs and incorrect assumptions.

However there is one area of bugs that features don’t catch so well, and even cause to some extent. These bugs are built right into the text in the form of ambiguity, sometimes through the constraint of features being executable.

This came up recently in a conversation with James and Enrique at Eden Development about James’ apprentice task, the Snakes and Ladders Kata. It turns out that the text of one of the features runs against the commonly understood way that Snakes and Ladders works:

Scenario: Win the game
    Given player 1 is on position 97
    And player 1 rolls 3
    Then player 1 has won the game

Question: is that a valid scenario? Given the commonly understand rules of Snakes and Ladders, you cannot just start on position 97. Implementing it as written complicates the domain model.

How do you implement the first step? Do you go for a simple:

Given /^player (.*?) is on position (.*?)$/ do |player, position|
  @game.set_player_position(player, position)
end

The potential issue with this is that you are exposing a method that in real life won’t get called, just to set up a test. It’s also tying your model down to a particular structure, by implying that the game stores an arbitraty position variable for a player. This might not be the best way to model the problem.

The other option is to change the scenario such that the “Win the game” is tested in a similar way to the following:

Scenario: Win the game
    Given a game is started with two players
    And the following dice are rolled:
      |3|
      |4|
      |5|
      |5|
      (etc.)
    Then player 1 has won the game

That satisfies our understand of Snakes and Ladders, and gives us more freedom in our domain model. In this case, we simply modify the agreed scenario in the code and sidestep the problem.

Right? Wrong.

The important thing to remember is that the customer is always right about how the software should behave, even when it violates our commonly understood assumptions about the world. The software they want you to build might require a different implementation of Snakes and Ladders. They might have a 3 year-old daughter they’re planning to play the game with, who always wants to be given a headstart. In this case, we’ve not delivered what they want, simply because it makes life easier for us. We’ve let our assumptions and our concerns for good design drive out the features, rather than letting the features drive our design.

There’s another possibility: when the customer wrote this scenario, they simply used “starts on position X” as a shortcut and don’t really care if it’s possible to do this in real life. In this case, we can work with them to write the scenario so as not to cheapen our design for the sake of easier feature writing.

The key insight: there’s no way that we can know which it is from reading the scenario. We have to ask the customer and drive out the ambiguity in the feature.

We mustn’t let the necessary constraints of executable features build ambiguity into your conversations about what the customer really wants. And we must be constantly talking to the customer all the way through the iteration, especially if they’re not on site.

You might think “It’s only Snakes and Ladders, what does it matter?” It matters a great deal: situations like this come up regularly in real life projects. Practising how to deal with these issues and the conversations that result is one of the many powerful things you gain by doing katas.

What’s your take on the above problem? Have you come across it in real life?

Read more

Introducing Card Pirates

I made a little game this week called Card Pirates. It’s a fun thematic pirate card game for 2 - 4 players. Players take the role of an old fashioned pirate ship on the high seas, searching for treasure, avoiding storms, attacking other ships and attempting to win the favour of the island governors.

photo of card pirates

It can be learned very quickly, and is great fun to play. You can win if you’re lucky, but there’s a lot of strategy too. It takes about 20 - 40 minutes to play.

The game is playable with just one pack of playing cards and a token to represent each player, so there’s no excuse not to give it a go! We started with lego bricks and have moved on to little plastic ships from another game.

http://cardpirates.com

Try it out and let me know what you think, either here or on the Card Pirates site. I’d be grateful for feedback!

Read more

Waxing Lyrical on Pathfinding

I’ve been attending and giving talks at the Software Craftmanship conference at Bletchley Park for a couple of years now. I’ve always found the crowd there engaging and great to hang out with, and I’d encourage you to come along if you’re not doing much on June 14th. There are still a few tickets left if you’re quick.

My talk proposal: Pathfinding Peril

This year my talk proposal is about pathfinding, a subject rather close to my heart since I started building a game. Finding the shortest path through a connected graph is a complex problem, and one which has a number of very useful applications, not just in the game sector.

Thankfully there are some efficient algorithms out there which solve it well. The aim of my session will be to teach the popular A-Star pathfinding algorithm, along with the factors to consider when choosing appropriate algorithm weights to make the implementation efficient.

A-star can be written in any language, but a simple (untested, probably buggy) version might look like this:

    def find(goal)
      closed_set = []
      open_set = [ start_node ]
      came_from = {}
      while(!open_set.empty)
        current = open_set.sort{|node| node.estimated_score }.first
        return reconstruct_path(came_from, goal) if (current == goal)

        open_set -= [current]
        closed_set += [current]
        current.neighbours.each do |neighbour|
          next if closed_set.include?(neighbour)
          possible_score = best_score[current] + current.cost_to(neighbour)
          if !open_set.include?(neighbour) || possible_score < node.running_score
            open_set += [neighbour]
            came_from[neighbour] = current
            neighbour.running_score = possible_score
            neighbour.estimated_score = neighbour.running_score + neighbour.cost_to(goal)
          end
        end
      end
      return 'failed'
    end

The session will last a couple of hours. I’ll take you through the basic A-Star implementation in the first 30 minutes of the session, and we’ll spend some time getting that coded up in the second 30 minutes. After a break, we’ll be running a tournament for an hour using Matt Wynne’s Robot Tournament engine. Your robot will be one of two characters in a maze, and the idea is to find the exit as soon as possible without being eaten by the minotaur that roams randomly around it.

You’ll get points for exiting the maze within a certain timeframe, exiting first, and simply avoiding being eaten! If I get time, I’ll write a basic ruby gem which allows you to parse the maze presented on stdin into nodes with connections.

We’ll run around 20 minute iterations, but probably reset the score every time so that the final score is the one that matters. It should be lots of fun!

What do you think of the session idea? How could I improve it?

Read more