Thursday, September 16, 2010

Competitive Robocode Robot

In this next segment of my experience with Robocode, I developed a competitive robot called RobotFighter that could reliably beat most non-advanced robots.  Secondary objectives were to improve my Java and Eclipse skills, and also to improve my ability to write code that adhered to standards.

The main feature of this bot is its random movement system.  First, RobotFighter calculates the distance between itself and the enemy bot.  If this distance is over 150 pixels, RobotFighter turns at a seemingly random angle and rushes toward the enemy bot.  If the distance is less than 150 pixels, RobotFighter turns at a random angle and retreats up to 450 pixels away from the enemy bot.  By introducing randomness into its movements, RobotFighter is able to evade enemy bot fire while closing in for short-distance attacks or retreating from ram-style attacks.

RobotFighter scans in a right-ward direction at 45 degrees per tick and with a wide arc.  Upon detection of an enemy bot, it fires a bullet and moves in a random direction.  Due to the limitations of Robot class, all actions are performed in serial, and thus, RobotFighter cannot maintain a perfect lock on the enemy bot.

Since RobotFighter uses a linear firing system, it only fires when it is within 500 pixels of an enemy bot.  It also varies the power behind its shots in proportion to the distance to the enemy bot.  The strength of its bullets are 0.9 at a distance of 500 pixels, and 3.0 (the maximum) at distances of less than 150 pixels.

RobotFighter was tested against 8 different sample robots in 100 rounds each.

Walls     Win: 64%     Loss: 36%

The movement system worked nicely in this match-up.  RobotFighter evaded most of Wall's bullets until it wore itself down to 0 energy.

RamFire     Win: 62%     Loss: 38%

The movement system overwhelmed RamFire's slow rotation rate.  RobotFighter backed away from RamFire in sharp angles, leaving it vulnerable to fire while it rotated.

SpinBot     Win: 21%     Loss: 79%

RobotFighter's linear firing system does not work well against bots that do not stop.  It is also inaccurate against circular movements.  If this robot were to be redesigned, it would have a pattern-finding system to predict the enemy's next movements.

Crazy     Win: 97%     Loss: 3%

Similar to the match-up against Walls, RobotFighter evaded most of Crazy's bullets until it wore itself down to 0 energy.

Fire     Win: 100%     Loss: 0%

RobotFighter is extremely effective against opponents that remain still for long periods of time.

Corners     Win: 82%     Loss: 18%

Like Fire, Corners remained still in a corner of the map, leaving it completely vulnerable to all bullets.

Tracker     Win: 76%     Loss: 24%

Tracker and RobotFighter used very similar movement systems.  The difference was that RobotFighter evaded more bullets by moving in non-right angles and it fired more powerful bullets up close.

SittingDuck     Win: 100%     Loss: 0%

SittingDuck literally did nothing but sit, so a 100% win percentage was expected.

Lessons Learned:
  1. From a documentation perspective, I learned that ALL methods need to be documented regardless of how trivial and straightforward they may seem.  To another developer, any missing documentation is far from trivial or straightforward.
  2. Eclipse provides a bunch of useful tools that make development times much quicker.  Some of these tools include automatic import statements, code formatting according to a standards template, refactoring, and built-in Javadocs.
  3. Every developer can learn to "listen" better.  In my previous experience with Robocode, I failed to "listen" when I did not notice the link to ICS 413 Robocode Standards.  This time around, I made sure to "listen" by double-checking that all requirements have been met.
A packaged version of RobotFighter is available here.

Tuesday, September 14, 2010


Robocode is an open source educational game designed to help people learn the Java programming language.  Much of the work is already done behind the scenes to provide the GUI and screen overlay.  One simply needs to refer to the API to begin coding their robot to move, use its radar, and shoot.

To learn basic movement, targeting, and firing behaviors, I programmed numerous robots to perform the following:

  • Position01: The minimal robot.  Does absolutely nothing at all. 
  • Position02: Move forward a total of 100 pixels per turn.  When you hit a wall, reverse direction.
  • Position03: Each turn, move forward a total of N pixels per turn, then turn right.  N is initialized to 15, and increases by 15 per turn.
  • Position04: Move to the center of the playing field, spin around in a circle,  and stop.
  • Position05: Move to the upper right corner.  Then move to the lower left corner.  Then move to the upper left corner. Then move to the lower right corner.
  • Position06: Move to the center, then move in a circle with a radius of approximately 100 pixels, ending up where you started.
  • Follow01: Pick one enemy and follow them.
  • Follow02: Pick one enemy and follow them, but stop if your robot gets within 50 pixels of them.
  • Follow03: Each turn, Find the closest enemy, and move in the opposite direction by 100 pixels, then stop.
  • Boom01: Sit still.  Rotate gun.  When it is pointing at an enemy, fire.
  • Boom02: Sit still.  Pick one enemy.  Only fire your gun when it is pointing at the chosen enemy.
  • Boom03:  Sit still. Rotate gun.  When it is pointing at an enemy, use bullet power proportional to the distance of the enemy from you. The farther away the enemy, the less power your bullet should use (since far targets increase the odds that the bullet will miss). 
  • Boom04: Sit still.  Pick one enemy and attempt to track it with your gun. In other words, try to have your gun always pointing at that enemy.  Don't fire (you don't want to kill it). 

I successfully coded all behaviors.  My implementations are available here.

At first, I was frustrated at the lack of a definitive guide that detailed specific robot behaviors and its code.  The wiki was not particularly helpful as the information was scattered throughout dozens of pages and mostly contained advanced behaviors.  The API became my golden guide from Position04 and onwards.

Position04 and Position05 presented the greatest challenge due to the necessity of trigonometric concepts and the awkward "compass" system that Robocode uses.  I completed Position04 by simply having the robot move in right angles until it reached the center.  In Position05, I used trigonometric functions such as arc tangent to have the robot move directly to its destination.  A problem I encountered was that the body of the robot is considered to be a square, not a single point.  Thus, my robot would occasionally run into a wall before hitting the corner of the map.

Other robots that exhibited interesting behaviors were Follow02 and Boom02.  I learned that by adjusting movement and radar rotation rates, I could affect how well the robots performed their tasks.  For example, I discovered that a radar rotation rate of 45 degrees per tick and 100 pixels per movement resulted in a potentially optimal robot that could quickly track down another robot.

Since positioning and predicting robot movements are the main strategies in Robocode, a competitive robot would strike a balance between radar rotation and movement rates.  In addition, techniques such as statistical analysis would be beneficial in predicting enemy movement patterns.