Wednesday, September 28, 2011

Building Systems with Ant

Introduction

Ever wish there was an easier way to build your Java projects?  Tired of using the command line to manually run all of your fancy tools?  Well wait no longer as Ant can automate your build processes with the help of a few user-defined XML files.  These XML files are created using a special subset of the XML language and to learn this we shall once again use the concept of code katas.

Tasks
  1. Ant Hello World - Print Hello World.  Learn the <echo> element
  2. Ant Immutable Properties - Show that Ant properties are immutable once they are set.  Learn the <property> element.
  3. Ant Dependencies - Learn how the depends attribute of the <target> tag works.
  4. Hello Ant Compilation - Use the <javac> element to compile a Java program.
  5. Hello Ant Execution - Use the <java> element to run a Java program.
  6. Hello Ant Documentation - Use the <javadoc> element to generate the documentation for a Java program.
  7. Cleaning Hello Ant - Create a target that deletes the build directory to clean the system.
  8. Packaging Hello Ant - Clean the system and pack it into a zip for distribution.

Experiences

Most of the katas were simple and easy to complete using a few targets and lines of code.  The only kata that gave me problems was the Packaging Hello Ant kata.  While it was simple to package all of the contents of the working directory into a zip archive, it was slightly more tricky to pack all of those contents within a folder inside of the zip archive.  To do this, I had to use the <copy> element to copy the contents of the working directory to a new temporary directory.  Then I could specify that I wanted the new directory and all its contents to be included by the <zip> element to create a zip archive with the desired structure and delete that temporary folder.  Hence, this exercise took a little more thinking as to how I would get the appropriate structure for the zip archive.

From these exercises, I learned how convenient build systems can be.  With a single command, I could compile a program, run it, generate documentation for it, clean the project, and pack it for distribution.  This would take many command-line operations and being able to do it just by typing "ant -f dist.build.xml" saves a lot of effort and time.

Overall, these exercises have given me a better appreciation for build systems, especially Ant.  Not only are they extremely convenient, they are also quite simple to use as the basic XML language used to direct Ant is rather simple and well documented.  Consequently, I am definitely looking forward to seeing Ant's true power as I start to work on bigger and bigger systems and see just how much simpler it makes the building process.

Tuesday, September 20, 2011

Code Katas and Robocode

How does one become great at something?   Of course, there are many possible factors, but the bulk of one's progress towards greatness comes from practice.  From learning a musical instrument to martial arts, practice is a key component to becoming better at whatever task is at hand.   Programming is no different, but developers tend to do most of their practicing on the job  leading to mistakes and difficulties as they work on real projects. To combat this, developers can use what are called code katas. These are short, open-ended programming problems to be solved outside of a project environment and are designed to serve as practice sessions for software developers.  There are many different katas for many different systems and languages, but here we shall focus on a set of 13 katas for the Robocode system in the Java programming language (Learn more about code katas!).  Now what is Robocode you may be thinking?  Robocode is an open source software system that allows users to build software tanks that can move, find enemies using its radar, and fight using its gun and these katas help to introduce new users, such as myself, to the basics needed to create an unbeatable fighting machine.  (Learn more about and download Robocode)


The Katas

  • 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). 

Completing the Katas


While working on the katas, it became apparent that the difficulty level between exercises varied quite a bit.  Position01 and Position03 were quite straight forward as only simple calls to the Robocode library functions were needed and others like Position02, Boom01 to Boom03, and the Follow katas added the use simple event handling concepts.  These were quickly completed after a few looks at the Robocode API documentation and served as a stepping stone for the harder katas.

However, Boom04 was slightly more complicated as the gun and the robot could have different headings, hence the heading that the gun needed to point to had to be calculated.  The only way to find the position of an enemy is to use the getBearing() method which returns the angle of the enemy relative to the robot's current heading.  Hence, I had to calculate what heading that bearing corresponded to so that I could rotate the gun to the enemy's position.  I also decided to add some checks to ensure that the gun took the shortest path possible to the enemy's position as any turns greater than 180 degrees would be changed to a turn in the opposite direction.




Furthermore, Position04 and Position05 introduced more complications.  These two katas ask for a robot that can move to a point and the library does not provide any functions like that.  Consequently, I had to create my own moveToPoint functions.  These function use trigonometry (http://www.clarku.edu/~djoyce/trig/ was a big help!) to determine the heading and distance to the point, turn the robot to that heading, and moves the determined distance.  Initially, these functions had a bug where the robot would get on top of the point, but slowly move even though it should have detected that it was on the point and stopped.  This problem took a while to debug and it was due to the fact that the Robocode system uses double floating point values for the coordinates of the battlefield which made finding exact positions a little tricky.  For example, if I told to robot to go to (400, 600) and the Robocode system had the robot's position at (400.0000000000001, 600.0) it would constantly try to adjust and never stop as the coordinates are not equal.  As a result, I decided to round the coordinates to integer values of the long data-type to prevent such precision errors as the fraction-of-a-pixel differences are unnoticeable.  Position05 also introduced another problem in that a robot cannot actually reach the corners of the battlefield due to its body dimensions and would push against the wall ad infinitum.  Therefore, I had to modify the moveToPoint functions to adjust points that are outside of the reachable range.  Since these functions are shared by the last three Position katas, I decided to put them in a separate subclass of the Robot class to prevent a lot of copy and pasting (You may find the source code for this subclass here).

Finally, there is Position06.  This kata built on the problems from Position04 and Position05 with the added requirement that the robot must go in a circle with a radius of ~100 pixels.  Initially, I thought that I could use the circling method of the Spinbot provided in the samples, but realized that it was just constantly turning so that its circling radius was unknown.  Instead, I had to use the circle equation to calculate the points to move to.  I decided to provide the x coordinates and the radius to find the y coordinates of the target points, but this introduced another problem as the circle equation accounts for both positive and negative square roots which made the robot stall at points where the sign would change if only the Math.sqrt function is used.  To combat this, my robot changes the sign of the square roots when it reaches the points where the square root should change signs (90 and 270 degrees).

Conclusion


Now that I have completed these 13 code katas, I feel that I have the knowledge needed to create a competitive robot.  These exercises familiarized me with the basic movement, detection, and gun-use functions and has given me some ideas as to how to create a competitive robot.  For instance, I know that a competitive robot will need a lot of movement as dodging enemy bullets makes them waste energy and saves your own (some of the Position robots actually beat some of the sample robots by making them run out of energy even though they themselves did not even fire a single shot!).  I also understand that I will need to create a good tracking scheme so that most of my bullets hit.  Perhaps I could lead the target if it is moving to increase the accuracy of my robot's shots.  Finally, I think that code katas are a good learning device.  As said by many people, the best way to learn how to program is to actually do it and these katas provide short and interesting tasks to hone one's programming skills without the pressures provided in a project setting.  Thus, code katas like these are a good way to work on one's programming abilities off of the job.