Monday, September 21, 2009

Robocode Battling: Battle 1

In my last entry, I wrote an analysis of the strategies used by a selection of the sample robots in Robocode, the battle robot program that I have been working with for the last three weeks. Over the last few days, I have worked to develop a robot that will generally defeat as many of these sample robots as possible, when placed in a 1-on-1 battle. This represents my first attempt to design a battle robot, after spending the last several weeks learning basic Robocode movements and studying sample strategies.

Before I began programming, I tried to think of what general strategy I should use. It seemed like it would be best to keep my robot constantly moving in some generally straight pattern, so as to avoid any bullets that are shot at me, as well as to avoid swerving back into stray bullets. Other than that, I decided to adopt one of the instructions from the basic robots that I constructed two weeks ago, to fire using power proportional to the enemy robot's distance.

I began by writing my own implementation of the sample robot Walls. Although this consistently beat all other sample robots as expected, I wasn't happy with the fact that I was simply copying the exact idea of a sample. Furthermore, my implementation of Walls had a very difficult time dealing with Corners.

I then decided to simplify my robot, by having it essentially pace back and forth along one wall, keeping the advantage of having fewer directions for enemies to target it from, as well as the advantage of being able to shoot at most enemies, since none could be directly behind my robot. However, again I had trouble dealing with Corners, since my robot generally shot straight ahead, and half of the time Corners would be to the side of me. I then gave my robot some evasion tactics, by having it move to the opposite wall when it hit another robot, and thus PacerEvader was born.

My robot's overall strategy can be summarized as follows:



PacerEvader
(Source code)
Movement: Moves back and forth along the top wall. If it hits a robot, it moves to the opposite wall and resumes moving back and forth.
Tracking: No sophisiticated tracking; it will look for enemies to target arbitrarily.
Firing: Fires when an enemy is spotted, using power proportional to the enemy's distance (more power for closer enemies).



Here are the results of 1-on-1 battles between my robot and each of the samples. As a note, points are awarded for a variety of battle elements, including successful shots, ramming into other robots, and surviving. The winner is based on overall score, and not the number of placings in survival. I have provided the score percentage, as well as the number of wins in actual battle.

Walls: score percent: 12; 3 wins, 97 losses
RamFire: score percent: 48; 66 wins, 34 losses
SpinBot: score percent: 73; 89 wins, 11 losses
Crazy: score percent: 78; 94 wins, 6 losses
Fire: score percent: 92; 99 wins, 1 loss
Corners: score percent: 85; 99 wins, 1 loss
Tracker: score percent: 55; 58 wins, 42 losses
SittingDuck: score percent: 100; 100 wins, 0 losses

So overall, my robot can win against SpinBot, Crazy, Fire, Corners, and SittingDuck. Furthermore, it approximately ties with RamFire and Tracker, leaving its only real problem opponent as Walls. I believe that PacerEvader is successful because it constantly moves, generally avoiding bullets from semi-stationary targets, and it does not waste power excessively on targets that it has little chance of hitting.

I had a lot of headaches while trying to develop my battle robot. Most of the problems occurred while I was still trying to implement a very close copy of Walls, and as I was trying to do too much with a single robot. I don't think I completely understand the order of events as they are triggered, since I was having trouble generating OnScannedRobot events when I needed them to be, despite putting in scan() commands when my robot's gun would be pointed directly at a target. This is still an unresolved problem, since I merely developed a crude, inefficient workaround before abandoning that battle strategy altogether. My main lesson learned from this was that it is impossible to program without having a firm grasp of what you are trying to do, as well as the tools that you're working with. Although the Robocode API was extremely helpful, I was thinking out of the scope of my programming abilities.

For future development, I would like to find a strategy that will reliably beat Walls without compromising results against too many of the other sample robots. If possible, I think that I should also look into other ways to earn more bonus points, since RamFire beats PacerEvader from the bonus points earned through ramming my robot, rather than surviving until the end of the battle.

No comments:

Post a Comment