Tuesday, September 29, 2009

Automated Quality Assurance and Robocode Ant Build

Ant and Ivy are a great combination to automate your build for distribution. Think of Ant as what Make is to C/C++, and think of Ivy as what FreeBSD Ports is to automated dependency resolution. The reason why Ant and Ivy are so popular is because of its simplicity and flexibility. Instead of downloading all packages manually and configuring the software, Ant and Ivy do this automatically which helps in accomplishing the Three Prime Directives of Open Source Software.

Quality Assurance is not an entirely fun task, so I used PMD, CheckStyle and FindBugs to aid in this process. Here is a quick overview of what these tools can help you accomplish:

PMD scans Java source code and looks for potential problems like:

  • Possible bugs - empty try/catch/finally/switch statements
  • Dead code - unused local variables, parameters and private methods
  • Suboptimal code - wasteful String/StringBuffer usage
  • Overcomplicated expressions - unnecessary if statements, for loops that could be while loops
  • Duplicate code - copied/pasted code means copied/pasted bug

CheckStyle also scans Java source code and looks for style violations among various others.

FindBugs checks Java bytecode for known bugs. This static analysis tool can spot null pointers, problems with equals() and hashcode() implementations and many other issues that may have been overlooked.

While these tools should not replace a person doing line by line code analysis and review, it does help automate catching the low hanging fruit.

Along with creating a fully automated build that has been tested with junit test cases ready for you to download and run instantly, I have also improved FlankBot, my Robocode battle bot, to be more intelligent against Walls based robots. Some of the improvements are:

Conserving Energy (only shooting when close, only shoots if miss is below n)
Detection of Walls Bots ( 95% winning against sample Walls)

Download Flankbot with Robocode here.

Sunday, September 20, 2009

FlankBot Crushes the Opponents!

I recently finished developing FlankBot, a robot that battles other robots in RoboCode http://robocode.sourceforge.net. The purpose of this bot was explained in my previous blog entry and my design paid off in the end, consistently beating all sample bots.

Here is a video clip of FlankBot in action:




FlankBot has a defensive strategy that is used to passively attack its opponents while maintaining distance. When FlankBot scans an enemy, it moves to its side and fires. Once it stops, it aims at the enemy and fires, the strength of its shot depends on the distance from the target. Since the distance of the target depends on its ability to reliably hit the target, FlankBot shoots at minimal power if the target is far away.

This strategy paid off well as you can see from the following statistics. Each set of data is taken from an average of 100 rounds.


Rank

Robot Name

Total Score

Survival

Surv Bonus

Bullet Dmg

Bullet Bonus

Ram Dmg * 2

Ram Bonus


1st

rlb.FlankBot

5419 (81%)

4400

880

114

18

7

0

2nd

Walls

1287 (19%)

600

120

502

57

8

0



1st

rlb.FlankBot

11198 (81%)

4900

980

4335

853

110

19

2nd

Crazy

2561 (19%)

100

20

2192

20

229

0



1st

rlb.FlankBot

19059 (72%)

4500

900

11353

2111

196

0

2nd

Fire

7439 (28%)

500

100

6537

262

40

0



1st

rlb.FlankBot

15911 (79%)

4750

950

8571

1625

14

0

2nd

Corners

4166 (21%)

250

50

3726

135

5

0



1st

rlb.FlankBot

10804 (55%)

3450

690

5730

811

102

21

2nd

SpinBot

8817 (45%)

1550

310

5822

510

506

118



1st

rlb.FlankBot

17527 (88%)

4800

960

9810

1920

37

0

2nd

Tracker

2497 (12%)

200

40

2135

70

13

39



1st

rlb.FlankBot

18101 (100%)

5000

1000

9910

1980

181

30

2nd

SittingDuck

0 (0%)

0

0

0

0

0

0



1st

rlb.FlankBot

14171 (51%)

2800

560

9442

1219

115

36

2nd

RamFire

13353 (49%)

2200

440

6978

162

2221

1352



I learned that it is quite difficult to develop a strategy that consistently defeats other robots. It's best to think about developing a defensive strategy and maintaining a little bit of distance, as many other bots will eventually die from spending too much energy.

The next robot I develop, which I think will be a supercharged version of FlankBot, will employ a more aggressive approach if it can be done right. I'd like to get behind the enemy and incorporate a RamFire-like behavior. I'd also like to have a few different modes. For example, if my energy is consistently decreasing, I'd like FlankBot to try something new to outflank the enemy, or just become more defensive.

If you'd like to try out FlankBot you can download it here:
Download FlankBot (includes source)



Tuesday, September 15, 2009

RoboCode Sample Bots Review


I choose to study the movements, targeting and firing techniques of other sample robots in order to gain some insight in my quest to build a competitive robot for the upcoming competition. Here is my review of 8 simple sample bots.

Walls: This is a surprisingly effective bot with a simple idea. Walls finds the distance to the nearest wall and turns to face it. It then moves toward the wall and when it gets there, it starts moving along the walls shooting at any enemy with medium fire power that it scans with its radar. This bot is hard to hit and its bullets come at weird angles because of its movement.

RamFire: This bot charges at the enemy and fires when the enemy is in its target path. It is only effective against bots like the Sitting Duck. Bots, like Walls, avoid RamFire's actions entirely. A good tactic about this bot is that it fires proportionally to the amount of energy left on the enemy. So if the enemy has high health RamFire will fire at its maximum potential and ram the target for extra bonus points instead of shooting it.

SpinBot: Spinbot is quite ineffective as it spins in circles shooting wildly at its target. If it scans another bot, it will fire at its maximum power. However, this doesn't work too well since the bot is spinning. An interesting fact about this not so interesting bot is that if it hits another bot it checks to see if it "isMyFault". This means that if the SpinBot hits the enemy, the bot will turn to the right 10 pixels instead of firing.

Crazy: This bots movements will make you sick if you watch it too long. However, you can't ignore the fact that Crazy's defensive strategy is pretty darn effective. A new technique I saw in this code is the setTurnRight and waitFor methods. What's interesting about this, is that you can 'set' the next action based on another action. For example if setTurnLeft is called, it will waitFor a TurnCompleteCondition on its self (this). I found this a great tactic, and I may use it for my competition robot. Crazy also features a reverseDirection method when it hits a wall that calculates where it is and reverses direction based on boolean values. It also has other common characteristics like isMyFault and firing upon a scanned event.

Fire: Fire is a basic bot where it turns its gun in a circle until an event is triggered. When onScannedRobot is called, it will shoot at its full power if the other bot is close and it has a lot of energy left. This is a smart move in order to conserve strength. It also has a defensive mechanism that takes place after the fact it has been hit by a bullet. It will move in a horizontal direction away from the bullet that hit it. If another bot rams into it, it will turn its gun toward the bot and fire full strength.

Sitting Duck: An interesting bot that does more then you might think. Along with sitting still and doing absolutely nothing, this bot keeps a score in a file that allows its stats to be read long after the bot has died. It opens a file, "count.dat" and increments the number of rounds and battles it has fought.

Corners: This bot goes North. When it reaches the wall it goes all the way to the left corner. It then faces the playing field and shoots at the enemy when it scans it. It fires at the enemy depending on its distance. If the enemy is far away it shoots weakly, if it's close then it fires hard. An interesting thing about it is that it uses the stop method to stop what it is doing and then fires continuously at the enemy. This is quite effective because it has visible range over the whole playing field and can easily overwhelm the enemy with firepower. Corners also checks the amount of other robots left and will switch corners for the next round.

Tracker: This bot is pretty impressive in logic, but is not so effective against enemies. It will look for an enemy and if it doesn't find it, Tracker will turn its gun, effectively moving its radar. If Tracker can't find the enemy, it will stop tracking that enemy. If it finds another enemy while it has an enemy, it will ignore it using its trackName String and turn and move towards it if it is too far to have an effective shot, otherwise it will shoot at its full power. Tracker also incorporates defensive movement as to not get rammed or fired upon at too close of a distance by the enemy. What I really found entertaining was that if another enemy rams into it, as we would find in the behavior of RamFire, it then sets it's target to that bot as sort of a retaliation.

Code review has been an excellent process to learn new techniques and thinking patterns of other coders. It helped me start thinking about new strategies for my competitive robot. I can't wait to start looking at the more advanced robots.

Saturday, September 12, 2009

Why Bother with Coding Standards?


Coding standards can be annoying but they serve a good purpose. If everyone in a project adheres to the same coding standard guidelines it's much easier to dive into the code and get things done. If coding standards are not in place it may take longer to understand what the programmer is trying to do. This comes into play especially for developers who are just joining the project.

Another aspect of why coding standards are good is because it's easier to spot bugs if the style is in line with the rest of the project. Documentation generators like JDOC and Doxygen provide a really good reason to enforce coding standards since those tools are used to provide other developers easier access for helping the project grow.

For the Robocode project I choose 3 guidelines to follow:

Robocode Guidelines overrides the prior two, as does ICS-SE Coding Standards to The Elements of Java Style. A really useful tool that helps with formatting code is distributing an xml file that contains formatting rules and importing that into Eclipse IDE. If everyone uses this file to format their document, it saves a lot of trouble and awkward situations where a member would have to confront the other person because they were using 4 space tabs instead of 2. No one really wants to be this picky so it helps for the IDE to do it automatically.

Here's an example of what a format file looks like:


<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>

<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>


Once you have imported the projects Eclipse XML formatting file, you simply select Format from the Source menu.

I have updated my Robocode Sample bots according to the standards:

Wednesday, September 9, 2009

Robocode: The Battle Bot Arena!


Robocode is an excellent way to learn intermediate Java in a fun interactive way. It lets you see what your doing instead of guessing with a traditional debugger.

So what is Robocode?

Robocode is a game where you program a robot that fights other robots in an on screen arena. You extend the Robocode Class which lets you inherit a wide variety of methods to use to attack your enemy. The API specifies many classes, but the most interesting is the ScannedRobotEvent Class. While using this Class, if the radar on your robot scans an enemy, it triggers the ScannedRobotEvent event. Most of the code you put into your robot will typically go in this method.

My Experience

To start my Robocode adventure I engaged in creating some simple robots for basic movement, tracking and firing after setting up Eclipse IDE for OSX. I didn't encounter any problems but that may be because I am familiar with Eclipse. Robocode also gives you a refresher on your trigonometry skills if its been a while and forces you to get really familiar with the Robocode API and the Java Math Class. With the skills I've learned after completing these robots, I feel I am about ready to start thinking about more advanced strategies for competition. Here is a list of the robots I've implemented so far successively:

Movement01: The minimal robot. Does absolutely nothing at all.
Movement02: Move forward a total of 50 pixels per turn. If you hit a wall, reverse direction.
Movement03: Each turn, move forward a total of N pixels per turn, then turn left. N is initialized to 10, and increases by 10 per turn.
Movement04: Move to the center of the playing field and stop.
Movement05: Move to the upper left corner. Then move to the lower right corner. Then move to the upper right corner. Then move to the lower left corner.
Movement06: Move to the center, then move in a circle, ending up where you started.
Tracking01: Pick one enemy and follow them.
Tracking02: Pick one enemy and follow them, but stop if your robot gets within 20 pixels of them.
Tracking03: Each turn, Find the closest enemy, and move in the opposite direction by 100 pixels, then stop.
Firing01: Sit still. Rotate gun. When it is pointing at an enemy, fire.
Firing02: Sit still. Pick one enemy. Only fire your gun when it is pointing at the chosen enemy.
Firing03: 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).
Firing04: 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).


What's Next?

My next task is to create a competitive robot. I have been practicing and reading about techniques for a one on one competition against other classmates. Even though I still have a bit to go before I can produce a really competitive robot, I have a few ideas. One of them consists of creating a robot that zig-zags side ways, perpendicular to the enemy to avoid being hit. My robot will remain at a striking distance but not get too close. If the other robot attacks me, I will flank it and hit it from behind. A circular zig-zag pattern seems to be a great way to play defensively and offensively at the same time. When I check the health of the other robot and notice that it is getting closer to death, my robot will play a bit more aggressive and get closer to the enemy while increasing fire power.

For More Information and Sample Code

If you want to see what this Robocode fuss is all about a great link to get you started is here:
http://robocode.sourceforge.net/

If you want to take a look at the robots I've implemented you can do so by downloading the package here:
Download My Robocode Samples

-Remy