Tuesday, September 15, 2009

Learning from the Enemy: Analyses of Other Developers' Robots

Before I design my competitive robot, I thought it would be necessary to see what other people did with their robots first. In particular, I looked at the sample robots that came with the Robocode installation package. Specifically, I will talk about how the authors of the Corners, Crazy, Fire, RamFire, Sitting Duck, SpinBot, Tracker, and Walls robots implemented the movement, tracking, and firing functions for them.

Robot #1: Corners
The goCorner method handles the movement for the Corners robot. As its name implies, the robot will face perpendicular to the wall that is to the right of the corner that it chose to go to and then go to that wall. Then it will turn left ninety degrees and move to the chosen corner. It is worth mentioning that the number of pixels to move forward, which is specified in goCorner, is hard-coded, so if the battlefield size is gigantic (say, 20,000 x 20,000 pixels), the robot may not reach the chosen corner; in this case, it can easily be defeated by attacking it from behind.

The robot swings its gun from zero to ninety degrees once it reaches the chosen corner; it does not rotate its gun from zero to 360 degrees continuously. If it makes radar contact with an enemy, it will try to track the enemy with its gun and fire at it both at the same time. However, if an enemy is to the rear of it and stays there all the time, and the latter never reached the chosen corner, the enemy will never be found because of the constricted movement of the robot's gun. Even worse, the enemy will have the perfect opportunity to destroy the robot without taking any hits.

The robot will open fire once radar contact is made. If the robot's energy is below a certain level, or if the enemy is very far away, it will use low power for its bullets. On the other hand, if the enemy is very close, it will use maximum power.

Robot #2: Crazy
Based on my observation of the Crazy robot in action, it appears that the waitFor method that is called in run will make the robot turn and move ahead at the same time. These two actions are accomplished by calling setTurnRight (and setTurnLeft) and setAhead, respectively, before calling waitFor. Also, it is important to note that the Crazy class extends AdvancedRobot, not Robot. In classes that extend Robot, one must call turnRight (or turnLeft) and ahead to make the robots turn and move forward, respectively; however, unlike the Crazy robot, they will not do these two actions concurrently, only sequentially. By turning and moving forward concurrently all the time, the Crazy robot appears to be moving around randomly.

Because the robot's gun and radar are both stationary, and because of the way the robot moves, there is no tracking mechanism used to lock onto an enemy once radar contact is made; radar contact is made only when the robot is facing in the direction that the enemy is located, and radar contact is lost when the robot turns in another direction.

The robot uses low power for its bullets and opens fire at any enemy that comes into radar contact with it.

Robot #3: Fire
The code to make the Fire robot move is located in the onHitByBullet method; no other method contains code for movement. Thus, the robot will only move if a bullet hit it; the robot will turn perpendicular to where the bullet came from and move fifty pixels.

The robot sits still and rotates its gun throughout the entire battle until an enemy hits it with a bullet. Once radar contact is made, the robot will track the enemy with its gun and open fire at it both at the same time; however, radar contact can easily be lost once the enemy fires a bullet at the robot and the latter moves as a result of being hit.

If an enemy comes into radar contact and is very close to the robot, and the amount of energy left in the latter is greater than fifty, the robot will use maximum power for its bullets against that particular enemy. Otherwise, the robot will use low power. Also, it will use maximum power against the enemy that comes into physical contact with it.

Robot #4: RamFire
The RamFire robot is similar to my Tracking01 robot; the former will rotate its entire body until it comes into radar contact with an enemy. Once radar contact is made, the robot will move to the enemy's location and attempt to ram it. If the robot arrives at the enemy's location but the enemy is not there, the robot will rotate its body again until an enemy comes into radar contact. Basically, the robot will follow the enemy and try to ram it.

Both the robot's gun and radar remain stationary throughout the entire battle. Because the robot only moves to an enemy's location and does not track an enemy with its gun or radar, this strategy will be ineffective against enemies that move around a lot, e.g. Crazy and Walls, because the only way to fire at them is to come into physical contact with them (i.e. by ramming them).

The robot fires at the enemy only when the former makes physical contact with it. Despite this strategy's ineffectiveness when it comes to very mobile enemies, the robot makes up for it by using maximum power for its bullets when it fires.

Robot #5: Sitting Duck
The Sitting Duck robot sits still throughout the battle. In the code file, there is only one method, run, but no method is called that will make the robot move; the only things that are done in this method are reading in a file that contains the total number of rounds and battles that the robot has been in, incrementing the two numbers, and displaying the results to the screen.

The robot does not move both its gun and radar at all during the battle. No methods are called in run that will make the robot move either of them.

The robot does not fire its gun at all during the battle. Surely, the robot is a sitting duck, perfect for target practice, because it does absolutely nothing at all.

Robot #6: SpinBot
The SpinBot robot moves in a circle throughout the entire battle. After examining the code file for the robot, I saw that, like the Crazy class, the SpinBot class also extends the AdvancedRobot class, and it uses the setTurnRight method, which, according to the API documentation, will execute when an action takes place or the execute method is called. In this case, ahead is the next method that causes the robot to take action, so both turning and moving ahead are executed at the same time, concurrently.

The robot's gun and radar remain stationary throughout the battle, so no tracking mechanism is implemented.

Once radar contact is made with an enemy, the robot will open fire at it with maximum power. However, it is important to note that because the robot is firing with maximum power, if there are two or more enemies on the battlefield (say, two Sitting Duck robots) and are in close proximity to each other, not every enemy will be fired upon until the gun cools down.

Robot #7: Tracker
The Tracker robot will rotate its radar until radar contact is made. Like my Tracking02 robot, once radar contact is made, the robot will turn its body towards the enemy and move to the enemy's location, stopping when it is 150 pixels away from the enemy. If it gets too close, the robot will back up forty pixels.

Once the robot arrives at a location 150 pixels away from the enemy but the latter moved to another location, the robot will try to find it again by moving its radar ten degrees to the left and right. If it did not find the enemy that it was tracking, it will rotate its radar until it makes radar contact, either with the same enemy or a different one. The tracking mechanism implemented here is similar to the one I used in my Tracking02 robot, but instead of using a string to keep track of an enemy and setting it to null once radar contact is lost, I used an integer, which I set to one once radar contact is made and zero once radar contact is lost or my robot is not tracking an enemy at the moment.

The robot will open fire with maximum power once it is 150 pixels away from an enemy's location. If another enemy bumps into the robot, the latter will back up, open fire with maximum power at that enemy, and track it until radar contact is lost.

Robot #8: Walls
The Walls robot will face perpendicular to a wall and then go to that wall. Then it will follow the edge of the wall in a clockwise fashion.

The robot's gun and radar remain stationary throughout the entire battle, so no tracking mechanism is implemented.

Once the robot reaches the edge of the battlefield, its gun will be perpendicular to the wall, and it will open fire with medium power once radar contact is made.

My Final Analysis
The robots that remain stationary (Corners, Fire, and Sitting Duck) are more at risk than the other robots, all of which are mobile, no matter how good their tracking mechanisms are. Why? Think of battles involving three, four, or more robots. I do not think they would last very long.

The tracking mechanism that the Corners robot uses is not a good one because it does not cover a wide area--that is, its radar sweep only covers only one-fourth of the battlefield, not all of it--and like I mentioned before, the robot's most vulnerable area is its rear.

If no tracking mechanism is going to be implemented, the robot should be on the move at all times (Crazy, SpinBot, Tracker, and Walls); even better, the robot should move randomly (e.g. Crazy) and quickly.

Hopefully, I did not give away too much information... ;)

--BJ Peter DeLaCruz

Saturday, August 29, 2009

The Three Prime Directives for Open Source Software Engineering

In today's post, I will talk about my experience using a Java application that I found on SourceForge. Open-source software developers use SourceForge to host their applications, and this website hosts many different varieties of software (e.g., games, file management utilities, and even screen savers).

I took a look at a file management application called Data Crow, which was written by Robert Jan van der Waals, a Dutchman.

Data Crow
Installing this program was easy; in Mac OS X, I just downloaded the zip file, double-clicked it, and then double-clicked the jar file that was extracted, and then the installer was executed. After following the steps for installing Data Crow, I was presented with the pop-up window in Figure 1 when I opened it.

Figure 1. Selecting an experience level (beginner or expert)

I like how applications have two types of modes, particularly beginner and expert modes. This kind of design gives users like me, who never used file management programs before to organize media like photographs and music, a chance to play around with the program. Fortunately, the interface is very intuitive, as one can see in Figure 2.

Figure 2. The user interface

I used the Item Wizard to guide me through the process of adding an audio CD that I wished I owned to Data Crow. In Figure 3, I typed the name "SNSD" (which is a Korean pop girl band) and clicked on Find to look up information about them on Amazon's website (e.g., the year that this group's most recent CD was released). The results of that search are also listed in that figure.

Figure 3. Finding information about SNSD on Amazon using the Item Wizard

In Figure 4, one can see that the information found from the search for SNSD are inserted into the appropriate text boxes in Step 2 of the Item Wizard.

Figure 4. The Title, Artists, and Description text boxes are automatically filled out using the Item Wizard

Finally, after finishing the Item Wizard for SNSD, I performed another search, this time for Tim McGraw (I am also a country music fan). After adding information about him and his CD (Southern Voice) to Data Crow, I clicked on Audio CDs in the Modules area on the left-hand side of the program and was presented with a neat hierarchical structure, which is shown in Figure 5 to the right of the Modules area. I clicked on Country in that structure, and the picture that is used on the cover of CD cases along with information about that particular album were displayed; see Figure 5.

Figure 5. Information about Tim McGraw's album is shown

Prime Directive #1
This prime directive states that "the system successfully accomplishes a useful task." Data Crow certainly does. If I were to organize the millions of audio CDs that I own (yeah, right), this program would suffice: my CD collection would be arranged such that I can click on a genre and then scroll down to view each artist's album that fits into that genre. Data such as title, description, year, rating, and website from which Data Crow used to gather the information along with the cover art are definitely important things to include when organizing a collection, and this program certainly did what it was designed to do by providing them to the user in a readable, organized fashion.

Prime Directive #2
The second prime directive for open-source software engineering mentions that "an external user can successfully install and use the system." I mentioned earlier that installing Data Crow was extremely easy to do; it was all a matter of unzipping and unpacking files, and running the installer. As far as user documentation is concerned, the help file can be found within the program itself. The topics are arranged in a hierarchical structure similar to the way genres were displayed in Figure 5. Included with each topic are subtopics, summaries, screen shots, and step-by-step instructions on how to do things, like how to create a new item. In Figure 6, for instance, the grouping pane is described, a brief summary is given, and a screen shot is provided that helps explain its purpose in this application.

Figure 6. Information about the grouping pane is described in the help file

Prime Directive #3
Finally, the last prime directive states: "an external developer can successfully understand and enhance the system." Van der Waals wrote that Data Crow is free software; he invited people to redistribute/modify the code in his program and mentioned that he included the GNU Public License with it. (Actually, I did not see it in the main or readme directories for the program, but he did link to the one on the Free Software Foundation's website just in case.) In the readme directory, he included a text file called tasklist that lists the features that he implemented and also the ones that he would like to add later in the future. By looking at this file, an external developer could generate some ideas of his or her own as to what he or she wants to do with Data Crow, or he or she could simply implement those features for van der Waals and save him the trouble of creating them himself.

Before I forget, I want to mention that I just found out that although I initially used Data Crow in Mac OS X to import SNSD's and Tim McGraw's albums, when I opened that same program in Windows Vista, I can still see my audio CD collection. (To run Data Crow in the latter operating system, double-click on the exe file; in Mac OS X, double-click on the jar file. At first, I thought that the separate files were separate instances or versions of the program.) It is definitely a good idea to code an application in a cross-platform programming language like Java because I could take this program with me on my USB thumb drive wherever I go, plug it into any computer that has version 5.0 or higher of Java installed, and still see and work on my data.

Maybe I should organize my CD collection after all; I cannot remember the name of this one album by George Strait that I have...

--BJ Peter DeLaCruz