Tuesday, October 11, 2011

Robot Rumble!!!



It is time!  The robocode competition is here, and we are all ready to have fun!  After spending hours going through the API source code, as well as trying some "Java cracking" attempts only to find the API being pretty secure, I settled on using the AdvancedRobot API.  I followed the robocode lessons and created an enemy robot tracker, which allows me to track other robots' movements and make prediction based on existing movement patterns.  The radar tracking code keeps all the robots being tracked in an array, and locks on to the first robot it sees.  The locking is done using the minimum radar turn assuming robot and gun is turned in the opposite direction.  Finally, the motion is a simple circular movement, with the added random reversal of direction whenever a continuous decrease of distance to target is observed.  Also, a "gutter" region around the battlefield is defined to try to keep the robot away from the wall, thus minimizing self-inflicted damage.

The competition is happening now!  In the meantime, here's some performance statistics against sample bots:

In one-on-one battle, the approach used was able to beat all the sample robots consistently.  One of the initial problem I had was with the "gutter" logic.  I initially set it to reverse every time it finds itself in the gutter. This is problematic most of the time because it ends up changing direction constantly and being stuck in the gutter.  This is fixed by putting a timestamp on each reverse, and set a period of timeout for consecutive reversal, thus allowing it enough time to exit the "gutter" condition.

Finally, like most of the students, I struggled the most with understanding the underlying robocode execution/event model.  The game physics page tries to explain the execution model, but is still unclear for in-depth exploitation.  In my attempt to go through the API sources and trace the event model, here is what I have as my notes:


Function calls per turn:
performLoadCommands()
  - fireBullets() => add bullets to battle field
updateBullets() => update and remove
updateRobots()
  - performMove()
    - updateGunHeat()
    - updateGunHeading()
    - updateRadarHeading()
    - updateMovement()
    - checkWallCollision()
    - checkRobotCollision()
    - update scan flag if moved or turned
  - performScan()
handleDeadRobots()
  - compute scores
  - update survival on the remaining bots
computeActiveRobots() => count how many is alive
publishStatuses()
  - energy, x, y, bodyheading, gunheading, radarheading, velocity, remaining moves/turns, gunheat, roundNum, time, etc.
wakeUpRobots()
  - waitWakeUp()
  - waitSleeping()


One needs to look at the event model in a cyclic manner.  During the last step, wakeUpRobots(), that's when your custom code is executed/evaluated.  I think that during your code execution, whenever you call a function that correlates to execution of an action (i.e. execute(), ahead(), turnRight(), turnRadarRight(), etc.) the action is registered and the robot code is put to sleep.  Then the event model starts evaluation from the top, by first updating bullet firing.  Note that in this case, for each turn, the standard Robot API only allows the registering of one of the various actions in the event model.  The AdvancedRobot API, on the other hand, have set*() functions to register multiple actions per turn before being interrupted and put to sleep by the call to execute().  I hope this notes could help the next generation of robocode hackers!  Enjoy and have fun!

0 comments:

Post a Comment