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.
