Thursday, November 10, 2011

A Candy Land Simulator: Overview and Data Representations

Note: this post is from a series on Candy Land.

As I was playing Candy Land with Thing 1, it occurred to me how much I dislike the game. As I blindly turned card after card I wondered what the typical number of moves looks like. And then I wondered what the distribution looks like. Really my brain just wanted to know how long it would be suffering, and how confident it should be about that answer.

I guess the driving force behind these questions is my insatiable desire to finish this game so I can banish it to the bookshelf for another night and redirect the kiddos to other, less torturous activities.

This is not a novel thing to wonder. In fact, apparently it’s pretty straight forward to approximate mathematically with a Markov chain. I’m not interested (or knowledgeable) in any of that, though. Instead, I want to simply build a test apparatus that yields the same kinds of answers from generated experimental data instead of fancy mathematics.

But that’s been done, too. I already had this idea festering as I enjoyed a friendly match of the worst game ever invented so I’m going to do it anyway. Come along for the ride—here we go!

My primary goal is to figure out the average number of moves required to end a game of Candy Land between my daughter and me, experimentally. Along the way, we’ll do these too:

  • Create a simulator that can run through a whole game of Candy Land unattended
  • Produce some output with different variables (e.g. number of players)
  • Make some fancy tables and charts

We might pile some more on as we go, of course. Throughout the whole process, I will try to make everything accessible to novice or aspiring programmers. This might mean I’m far more verbose and explicit about things than I normally would be; experienced programmers will just have to play along.

We’ll use Javascript as much as possible. Let’s get started.

First, we need to represent the game elements. We’ll start with something crude and then adjust it as needed. I transcribed the board into a Google Doc (you can steal that if you like) and from that we’ll extract some JSON (that’s in the spreadsheet, too).

If JSON (Javascript object notation) is unfamiliar to you, check it out. It’s pretty important.

The board looks like this in JSON:

var board = [
    // ...
    { color: 'Purple' },
    { color: 'Yellow', bridgeTo: 45 },
    { color: 'Blue' },
    // ...
    { color: 'Green' },
    { color: 'Red', loseTurn: true },
    { color: 'Purple' },
    { color: 'Yellow' }
    // ...
];

Here’s the full board. Basically we have an array of hashes. Each hash represents a square on the board and has the following properties:

  • color (or character), required
  • loseTurn, only present if true
  • bridgeTo, if present this indicates where the bridge leads to

Next we need the deck of cards:

var cards = [
    'Red'   , 'Red'   , 'Red'   , 'Red'   , 'Red'   , 'Red'   , 'Red'   , 'Red'   ,
    'Purple', 'Purple', 'Purple', 'Purple', 'Purple', 'Purple', 'Purple', 'Purple',
    'Yellow', 'Yellow', 'Yellow', 'Yellow', 'Yellow', 'Yellow', 'Yellow', 'Yellow',
    'Blue'  , 'Blue'  , 'Blue'  , 'Blue'  , 'Blue'  , 'Blue'  , 'Blue'  , 'Blue'  ,
    'Orange', 'Orange', 'Orange', 'Orange', 'Orange', 'Orange', 'Orange', 'Orange',
    'Green' , 'Green' , 'Green' , 'Green' , 'Green' , 'Green' , 'Green' , 'Green' ,
    
    '2Red', '2Blue', '2Purple', '2Orange', '2Yellow', '2Green',
    '2Red', '2Blue', '2Purple', '2Orange', '2Yellow', '2Green' ,
    
    'Gingerbread Man', 'Candy Cane', 'Gum Drop', 'Peanut', 'Lolly Pop', 'Ice Cream Cone'
];

With those in place, we can now do simple things like counting spaces:

alert(board.length);

Or counting cards:

alert(cards.length);

Or peeking at a random card from the deck:

var cardCount = cards.length;
var randomIndex = Math.floor(Math.random() * cardCount);
var randomCard = cards[randomIndex];
alert(randomCard);

I haven’t decided how to simulate shuffling yet (shuffle first, or draw randomly)—we’ll talk about that and do it tomorrow.

You can run what we have so far by hitting the little “play” triangle in this fiddle:

Now that we have our structures in place, we should start thinking about how we’re going to use the cards to navigate the board. I’ll start on that tomorrow, too… :)