Post Mortem of a Lousy Google AI Challenge Entry

3/1/2010

After flaming some people on Reddit who were criticizing light cycle AIs in the 2010 Google Challenge without building one themselves, I got the bug to build an entry. I was still a little discouraged after my utter failure with the Netflix prize, but I figured with the light cycle bot, at least it would not take three weeks of data crunching to discover my latest idea was no good.

I had fun but soon conceded I never had any chance of winning. (I'm a Web developer - enough said.) Once I stopped crying, I decided to lose on my own terms. My new goal was to find the simplest program that would still put up a decent fight.

My Code for 321st place (out of 708)

#!/usr/bin/python # The tron library was provided by The University of Waterloo Computer Science Club. import tron # I really wanted to submit without any other imports, but I could not # find a clever way to flip a coin without at least using the time lib. import random def BustAMove(board): # I need the distance between the two farthest points for normalization. max_dst = float((board.height - 1)**2 + (board.width - 1)**2) # This array stores assessment scores for each direction (1, 2, 3, 4 - N, E, S, W) # The first 0 is just a place holder scores = [0, 0, 0, 0, 0] for dir in board.moves(): # If there is a wall at this direction, don't even bother if board.passable(board.rel(dir)): # This weights available directions by the inverse of their distance # to the opponent. The behavior is a simple chaser. scores[dir] = (1-(PseudoDistance(board.rel(dir), board.them())/max_dst)) * 20 # Since chaser bots love to crash into their opponent (I give them full # marks for bravery) I added a check so my driver would not turn into a # space that his opponent could also enter unless he had no other choice. # It would not stop him from colliding on the map named "Toronto". (Which # I assume is a joke aimed at drivers in that city.) if not ProximityAlert(board, board.rel(dir)): scores[dir] = scores[dir] + 50 # After I added this bit to stop my driver from heading into certain # death, my rank went from around 300th to 200th. if ItsNotATrap(board, board.rel(dir)): scores[dir] = scores[dir] + 100 # If two directions are equally weighted, pick one at random. This returns the # perfect choice nearly half the time. Are you feeling lucky? return PickBestDirection(scores) # Distances are for comparison only, so I don't need the square root. (Sorry Pythagoras.) def PseudoDistance(you, it): return (you[0] - it[0])**2 + (you[1] - it[1])**2 # And the rest of the functions... def ProximityAlert(board, coords): for space in board.adjacent(coords): if (space == board.them()): return 1 return 0 def ItsNotATrap(board, coords): for space in board.adjacent(coords): if board[space] == tron.FLOOR: return 1 return 0 def PickBestDirection(a): tally = 0 ord = 0 for ii in range(1, 5): if bestOrFlipACoin(tally, a[ii]): tally = a[ii] ord = ii return ord def bestOrFlipACoin(currentBest, compareTo): return ((compareTo > currentBest) or (compareTo == currentBest and random.random() > .5)) for board in tron.Board.generate(): tron.move(BustAMove(board))

In don't think 321st is bad for 40 lines of sophomoric Python.

Congrats to the real winners and a big thanks to the University of Waterloo Computer Science Club for their quality work and for encouraging entrants to upload their mentally-impaired example bot as part of the registration procedure. (I am guessing most of my wins were against that.) I did not do well, but like when I ran the Detroit/Windsor Marathon in over 5 hours, at least I finished. I think that is something.