My first introduction to Robocode back in the fall of 2010 was a major fail. Not that my code was of lesser quality due to quality assurance tools usage, but I lacked the ability to truly conceptualize the algorithm that I truly wanted. If my memory serves me correctly, the Wall runner robot used blocking moves of the basic Robot, so I could not maneuver in a free manner. Fast forward to 2013, and let’s hope it is better this time.
The source code for this robot is available on this project page.
Movement, Targeting, and Firing Pattern
Like I had discussed in my previous post, this time around I understood the difference between blocking and non-blocking movement. With this in mind I sought to create a robot which could dodge bullets. Current the Hunter robot will circle around the board based in the enemies heading. Whenever Hunter comes close to a wall, it makes a tight turn away from the wall by slowing down. By continuously circling the battle field I hope to fool any robot which tries linear predictive firing.
Once the battle starts, Hunter will scan the battle field, and it will continue to scan until an enemy is sighted. The last enemy found during that scan turn will become Hunter’s first target. Hunter will not scan again until the targeted robot dies.
Since Hunter will target one robot until that robot’s death, Hunter can focus on calculating the expected location for linear predictive firing based upon the enemy’s scanned event details: heading, distance, and velocity. The time needed to calculate the expected distance is a random value between 17 and 23.
Using the RobocodeTestBed class, Hunter tested its battling ability against the following robots with theses results:
After looking at the results, Hunter does not do well with other robots that turns frequently.
I tried to separate as much as my algorithm and math as possible from my robot, so that it can be included inside my RobotHelper class. With the abstract method inside the RobotHelper class, I was able to unit test the methods using some mock values.
With the RobocodeTestBed, I focused on battle field behaviors such as firing at maximum force or avoiding the wall. This was easy to test as those values are returned in the event parameter. For testing the lock on feature of the robot, the debug property had to be set in order access which robot I am currently targeting. Although I have not done much investigation, the debug property values seems to reset after each turn. This introduced an error in my testing code as sometimes the value is not reset as the onRobotDeath seems to execute after the turn has ended.
This experience taught me to pay more attention to detail. Now that I am a bit more comfortable with JUnit, Check style, Findbugs, and PMD, I was able to focus on the relevance of Jacoco to augment my testing.
Previously, I thought that every piece of code need to be tested, since any visual verification did not have any written test. With some convenience wrappers in my RobotHelper class, I decided that visual verification was enough as I had tested the method that it wraps.