This page is a draft explanation of my entry in the ICFP2002 programming contest. Some of the constants I state are wrong, the final versions are in the files (which are linked from here).
typos and misspellings on this page are mine, and should not reflect poorly on my mother.

Team Name : Aqua Team Hunger Farce
Members : Jack Diederich [aka jackdied] jack_diederich atthehost email.com

Why Aqua Team Hunger Farce you ask? Because there was one minute left to the lightning submission deadline and it sounds better than anything I could think of for the The Brak Show. My computer wallpaper is Brak Show, so I was looking at it at the time. If you want to know more, here is the Aqua Teen Hunger Force fanpage. Visit the site, the images were 'borrowed' from there. I could have changed the name for the real round, but I didn't

Update. Results out. I'm not in 'em

Scoring summaries here
My pure-python lightning entry ran (6th out of 8), so I guess my buildme or runme was flawed (my second entry used C w/ python bindings for performance-critical sections). Bummer.
I promised myself I would never look at the code again, but I did. I spent three hours removing all the typos and bugs mentioned below and incorporating stuff that didn't even make it into CVS for the real contest. (Take a look in the tarball for a Knapsack algo to choose packages and routes) It wallops my original bot, and even edges out RadicalToo's (only on the small boards, I didn't try anything larger). Let me know if it runs on your redhat 7.3 system, it was developed on Debian Potato. Maybe that was my problem...

Tarball is Here
I included compiled C DSO's for my modules. If you aren't on intel/386 recompile them with 'python2 setup.py build'. It assumes that 'python2' is your python 2.2.1+ binary. If this isn't the case change the one-line 'runme' to something else (If you don't have python 2.2.x it won't run at all). By default it will unpack into a directory called icfp_athf/

My ICFP History

I heard about it last year from /. about 36 hours before the deadline. I raced and raced but missed the deadline. This year I was determined not to miss it. I even turned some of my work from last year into C w/ python bindings to prepare for this years'. Fast Combination, Permutation, and Cartesian product classes can be found on ProbStat Sourceforege Page. The priority queue I wrote [adapted from public domain source] for this year's will go into cvs there sometime soon. The AStar class should also be published somewhere, but its too small for its own page and won't fit under that sourceforge project. It can sit here for now.

Lessons learned this time, get a real friggin team. There are a dozen things I could have done that I just didn't have time for. And I'm sure there are a couple ideas that never crossed my mind. If you look at the bottom of my TODO file, you'll see 'DROP MULTIPLE PACKAGES'. If we're at a location that has multiple deliveries, they'll just have to wait for the next turn. This could be considered a drawback.

Links links links

ICFP 2002 Contest Homepage
Other people's pages who entered
Team Radical Too's bot beats me on the bridge map. I'm hoping the judges pick maps that favor me more (biiig ass maps). I also want to know how he got my email before I put it on this page, Hmmmmm.
Who host this site.

Every link below here is a link into the pretty-printed HTML version of the source code. Most of it is python, a little C.

Old! Server

I stopped running the server, it wasn't getting many hits anyway. Here is a list of my scores, out of 820. The other guy got the rest. my score : times seen
468 : 1
296 : 1
228 : 1
306 : 1
206 : 1
284 : 1
236 : 1
820 : 18
I have no way of knowing how many unique bots this is

Lightning Entry: Meatwad  

I won't say much about this one, it did the AStar search in Python, so it was sloooooooow. It also didn't do any fun stuff like remember where it is going. It is also prone to throwing uncaught exceptions.

Regular Entry: Frylock


This entry is VASTLY different from my lightning entry [which sucked]

Python made it possible,

The Basic umph of this program is a fast AStar search. Or if you are also in Massachusetts, a wickedfast AStar search. The priority queue was re-written in C with python bindings, the priority queue consumed most of the time, so this made the AStar much much quicker. The map keeping-tracker was also re-written in C. For a 1000x1000 map it consumes 1/10 the memory of the supplied test Server! To limit the AStar from running forever without returning, we use python Generators, which are very powerful. On my development box (I borrowed an Athlon2000+ from work) it can go about 13k continuations on the generators per second. This gives us very fine control over time slices. Python's exception mechanism was also very handy, in non-critical places where I knew the code was buggy or we look for a beneficial but remote possibility we just resume at the next heuristic and purr along.

Bot Heuristics

weren't great, but worked on all the small boards.
  1. continue_walk() If we are going somewhere, try to pathfind to 7 steps later to allow (the broken?) other player avoidance pathfinding and water avoidance.
  2. good_package() If there are packages HERE, try to pick some up
  3. deliver_package() If we are carrying packages, try to deliver the closest one
  4. Find a base, and go there in the hope there are packages
  5. The server hasn't called the game to an end, pick a spot and go there, resume 1)
We actually iterate over the list up to twice, the second time when the DESPERATE flag is set we use CPU above our limit. If we still haven't found anything, we call wander() which picks random spots +/- 7 squares X/Y of us and tries to go there.

AStar heurisitics:

distance:

neighbors: NSEW are calculated at startup and kept in bit fields for fast results

CPU usage heursitics

FindClose

the FindClose is the workhorse of the program, for a list of coordinates it will find the closest one (usually) to find a soluton, we usually do

find = FindClose(start, list of destinations)
answer = find.try_weakly()
if (still need an answer or have spare CPU time)
  answer = find.try_harder()
if (no answer and DESPERATELY need a solution)
  asnwer = find.try_hardest()

FindClose heuristics

try_weakly()
try_harder() The result is that as answers become available, they are added to the list
After we have used up our available time slice, we toss out all the generators that haven't finished

try_hardest()

FindPackage

FindPackage is a derivative of FindClose, and works in a similar way
try_harder()
  run FindClose.try_harder()
  if (Jiffies.available has lots of time left)
    pick the best package
    do a FindPackage with the Start coords being the DESTINATION of this package
      recurse while we have lots of time left
So ideally, FindPackage() will return a list of packages in a delivery route!
We don't actually store the delivery route, or take into account the weight of the packges, which is a shame.

Bidding Heuristics

Bidding is a very important part of the game, it can mean the different between a delivered package for you or the other guy. It can mean getting pushed into the water. So we use the following strategy:

The Map object is written using C array, which cuts the memory usage by an ugodly amount (4M vs 40M)
Each space is represented by two bytes
Byte 1, how close are we to a player
Byte 2

The observant will note that there is no reason that bits 7/8 couldn't be just one bit. I could have used the two bits to be Good/Wall/Water - I didn't, no reason. The result was that this program uses 1/10 the space of the supplied test server for the maximum 1000x1000 board! The map parsing is done in python, which is quick even on the largest board. As it parses it keeps a list of Home/Base nodes in python. It then calls the C routines with the parsed info. After the map has been read it calls finalize() on the C object which then figures out the WARN_H20 and DANGER_H20 bits.

The neighbors function used in the AStar search calls the Map object to find its neighbors, the routine examines the bitmap and returns Python tuples for each of the coordinates.

Bugs

If you were worried about my bot after reading this, exhale.