ICFP Programming Contest

Summary:

On Friday, August 30th, I entered and won the Judges' Prize for the Fifth ICFP (International Conference on Functional Programming) Programming Contest. This was for my first-place entry in the 24-hour "lightning round" division of the contest. As a winner, I am officially declared an "extremely cool hacker." I like the sound of that.

The Story:

On Friday, August 30th, my house was in the midst of being rather chaotic. My two ex-housemates were moving out, two new housemates were moving in, and I was helping another friend move to Cameroon. So, given all this, guess what my first reaction was when I heard (via the Slashdot story) that there was going to be a speed-progamming contest that weekend? You got it: that little voice in the back of my head said "sure, go for it, you've got lots of time..."

Anyway, so that's what I did. I used Python, which I find to be a brilliant language for rapid prototyping. I wasn't looking for any complex high-level AI, but rather a simple reactive-style agent seemed to me to be the best way to go. All I wanted was something that would work, with minimally complex code. Unsurprisingly, this is pretty much the sort of stuff I look at in my day job as a PhD student in Cognitive Science at Carleton.

The Code:

I'd like to think I got the prize for having the shortest entry to the contest. It's 378 lines including comments, whitespace, and debugging messages (255 lines without). I think it's mostly readable, and there are only a few things I feel I really should re-write to be a bit cleaner.

Also, here is my entry for the main (72 hour) contest. It didn't do as well. :( The main differences are a slightly different path-finding algorithm, faster calculation of optimal distances, and a different package selection mechanism.

The AI:

For path-finding, I used the gradient approach. This is, I think, pretty much equivalent to the more complex Dijkstra algorithm, but a heck of a lot simpler to code in this limited case. Basically, you make a big 2-D array that's the size of the world, mark the spot you're trying to go to with the number '0', all the accessible points around that with a '1', all the ones around that with a '2', and so on. This reasonably quickly finds the shortest path, at the expense of a fair bit of memory. Aw well, RAM's cheap.

I tried to add a little bit of enemy-avoiding strategy to this path-finding aproach. Basically, I made it so that any point with another robot on it was measured to be slightly farther away than it actually was. So, given the option, the robot will choose paths that avoid other robots. Discretion being the better part of valour and all. (Interestingly, I assumed that aggression would be fairly common in the other robots, but it doesn't seem to have turned out that way).

Using this path-finding ability, the robot would simply run around picking up packages at bases and taking them to their destinations. I bid '1' all the time, and didn't have any defensive strategies (I couldn't think of anything that would reliably work -- most strategies would require some pretty sophisticated guesswork about the motivation of the other robots).

The other (rather vital) aspect of the AI is choosing which packages to pick up. For this, I had no good ideas, other than trying to pick up lots of small packages, rather than a few large ones. The algorithm is a bit ugly and I don't like it. I didn't think of doing what a number of other entries did and use A* to actually plan out and find the best route/plan for package picking. Instead, it grabs packages for the closest destination (unless it can get even more for a slightly farther destination). Pretty ugly, and definitely sub-optimal, but apparantly it worked just well enough.

The Mistakes:

I didn't test my code anywhere near enough. I didn't make my own simulator, and so I didn't notice that the robot crashes in a lot of pathological map situations (like the 1x1 map). Oops. Also, a better package selection system was sorely needed. But overall, I'm quite happy with how it went. :)

Next Year:

Here's hoping that next year's contest is as interesting. :) I've already got my team together (composed of other members of my undergraduate Systems Design Engineering class of 1999 at Waterloo -- aka OaSys). So everyone else may as well give up now.

Terry Stewart