Trying AI Challenge Fall 2011 with Clojure

About two weeks ago a post popped up on Reddit that the fall 2011 Google AI Challenge had opened. This time, you command your own little ant army in an attempt to beat out the other colonies on the map through attrition (total or partial). I’ve been interested in Lisp and functional programming for a few years now, with a special eye towards Clojure. My interested had been rekindled after reading Writing Tetris in Clojure, and once I saw that Clojure was a first class citizen in the content I was off.

I don’t think Clojure 1.2 was out the last time I played with it, so there are some small changes to the language. I’ve been using the La Clojure plugin for IntelliJ as my IDE, and I’m trying to learn the Leiningen tool for Clojure project management. To top it off all, I’m using git instead of SVN to keep my changes. This means I’m learning quite a bit, but things aren’t perfect.

La Clojure doesn’t know anything about Leiningen, and I had to search for a while to find a good tutorial on Leiningen. Most seem to be in the form “Download, run this command, you’re all set”. That doesn’t give you much information. The blog entry I finally found was more useful, but I lost the link (it’s somewhere in my history).

Debugging Clojure is just as frustrating as I remember it. There is no debugger, you’re basically on your own. You can try to use a Java debugger, but that makes little sense. There is a package of macros for Clojure that is supposed to make things a little better, but I haven’t used it yet. This is all complicated by the fact that the AI Challenge tools run your program for you in a little sandbox, so I’m not even spawning the process. I’ve fallen back to the tried-and-true method of printing out values I’m interested in, which isn’t ideal. Leiningen supports running tests, so as I’m starting to get a grip on my program I’m going to have try writing some soon.

I took the Clojure starter bot and split it out into a couple of files to help me keep the code organized. At this point, each ant moves towards the closest piece of food, or randomly if it can’t move in that direction. The ants aren’t intelligent and they like to run into each other. But I’m making progress. It took me quite a while to sort things into files, but only an hour or two to do some additional refactoring and add the basic food seeking.

But still stymie me though. The other day I was stuck with my program just exiting after the setup phase. There was no error message, it would just quit. It came down to some changes I made to the code. I took a piece of code that look like this:

(loop [blah blah]
	(if (test? program-exiting-condition)
		(do-something-and-return)
		(more-calculations-and-recur)))

and I removed the part I didn’t need, the (do-something-and-return), replacing it with a comment to put code there later. This effectively turned the code into this:

(loop [blah blah]
	(if (test? program-exiting-condition)
		(more-calculations-and-recur)
		)); Fall through and exit program

That took me way too long to find. Once I figured out where the problem was, it took me a few minutes to get back into the Clojure mindset and remember that wouldn’t work.