1)What is erasure?
It refers to the fact that information of parameter type instantiation of generic Java classes does not exist at run time, but only at compile time.
2) What three properties should be satisfied by objects with respect to the .equals() method?
Reflexivity, symmetry, and transitivity.
3) How does test-driven development affect interface and API design?
Since the tests are written before their respective testee modules, the module interface and API are first formulated in writing the tests for those modules. Therefore, the interfaces and API"s are designed for usability and testability from the outset, and take into account the perspective from the outside of the class, as opposed to just the internal implementation oriented perspective.
4)Does inheritance hold with respect to the parameterized type in instantiations of generic classes in Java?
No, it only holds with respect to the container type. So, for example, List<Object> is not a superclass of List<String>, but Collection<String> is a superclass of List<String>, with the consequent implications for assignability.
5)What are the three levels of granularity for which we can disable PMD error testing?
Annotation level(classes or methods annotated with @SuppressWarnings), and line level (lines followed by //NOPMD).
For more info see: http://pmd.sourceforge.net/suppressing.html
Tuesday, October 25, 2011
Friday, October 21, 2011
Adventures in Google Project Hosting
I set up a google project hosting page for my robocode Diablo robot, and it was a cinch. Like any helpful IDE, the project hosting website steps you through the process, by providing among other things, repository connection parameter and sample commands.
First things first. Google Project Hosting (which I'll call GPH ) uses the Subversion version and configuration control system. I happened to already be somewhat fluent in Subversion (SVN) and whatever rust I had wasn't much of a problem since many of the commands for SVN and Git (which I've been using at the expense of SVN for the past year), are identical.
The toughest part of getting my project hosted was just making sure I didn't create that extra directory at the top level that I end up making so often by mistake whether it's via creating a project in an IDE or importing one via version control. In this case, it just comes down to making sure to dump your project files directory into the repository's trunk directory. A little birdie told me about a neat trick to get this right: just checkout an empty skeleton project onto your local machine and then put the initial project contents into the folder created by SVN. After that, just commit the whole thing and the files will be back up. Walla: now you have avoided the extra directory problem.
The GPH site uses a specialized markup language for user documentation authoring, that is more leightweight and more easy on the eyes than html, and is similar to other markup languages in the market. Once you learn a few quirks, these languages have pretty low ceremony and pretty good utility for getting all the headers and paragraphs to look right.
First things first. Google Project Hosting (which I'll call GPH ) uses the Subversion version and configuration control system. I happened to already be somewhat fluent in Subversion (SVN) and whatever rust I had wasn't much of a problem since many of the commands for SVN and Git (which I've been using at the expense of SVN for the past year), are identical.
The toughest part of getting my project hosted was just making sure I didn't create that extra directory at the top level that I end up making so often by mistake whether it's via creating a project in an IDE or importing one via version control. In this case, it just comes down to making sure to dump your project files directory into the repository's trunk directory. A little birdie told me about a neat trick to get this right: just checkout an empty skeleton project onto your local machine and then put the initial project contents into the folder created by SVN. After that, just commit the whole thing and the files will be back up. Walla: now you have avoided the extra directory problem.
The GPH site uses a specialized markup language for user documentation authoring, that is more leightweight and more easy on the eyes than html, and is similar to other markup languages in the market. Once you learn a few quirks, these languages have pretty low ceremony and pretty good utility for getting all the headers and paragraphs to look right.
Thursday, October 20, 2011
Diablo in details
It's been a few weeks now that I've been tinkering with Robocode. Like I mentioned in a previous entry, there's quite a bit of stuff to grok before you can start sporting a graceful robot with the elegant movements of a ballerina, and that doesn't get stuck the first time it hits a wall, or get confused by the geometrical subtleties of that most difficult of entities: the dreaded corner.
In the meantime I've been brushing up on all the attendant geometry and trigonometry issues that arise when trying to navigate and turn intelligently. I've been frequently referring back to a helpful series of tutorials and sample code at at http://mark.random-article.com/weber/java/robocode/lesson2.html
The one downside is that most of the examples in these tutorials assume you are extending a more complex robot class called AdvancedRobot. I resisted the urge to do that, and stuck with extending the more basic Robot, since I try to avoid premature optimization and also try to follow the KISS principle. The difference between Robt and AdvancedRobot is basically that Robot actions are blocking and AdvancedRobot actions aren't: the Robocode platform allows the non-blocking actions of an AdvancedRobot to be executed simultaneously, while the regular Robot can't walk and chew gum at the same time, but can fake it if he alternates the two fast enough.
One of the first things I did was shamelessly "borrow" two real real nifty and convenient classes from these tutorials, called EnemyRobot and AdvancedEnemyRobot. The former accomplishes the basic function of taking a snapshot of the robot that was just scanned and putting the information from that snapshot in a convenient object. The latter adds basic target prediction by linear two point extrapolation. Not terribly impressive, but a good jumping-off point for moving on to the higher level tactics and strategy.
Speaking of good old strategery, mine is basically a variation of strafing. Strafing means squaring off against your opponent, in other words pointing your tank perpendicular to the imaginary line joining you and your opponent. If you just keep going like this and in small enough increments, you end up "circling" your opponent (in reality you are traversing a bunch of small line segments that look like a curve but are just a series of line segments).
The two obvious variations on strafing are spiraling, or incrementally getting closer to the opponent like you are a satellite crashing into a planet, and veering away in an inverse spiral. The variation I devised, is simply to alternate between coming closer and going farther. This seems like a logical choice since I didn't want to design my robot for close quarters combat, which seems like a potshot anyway, and neither did I want to design my robot to run away like a bullied robot. The alternating motion between closing in and and veering out, also has the nice side-effect of making the robot's movements harder to predict and therefore making the robot harder to target.
I also added some probabilistic firing to make my robot stingy when dealing with a distant target. After all, in robocode, the energy expanded in shooting a bullet comes right out of the robot's life reserve, and if necessary, I want my robot to be able to play it cool and wait for the enemy to have no more gas in the tank, so to speak.
Finally, I added some wall avoidance code adopted from equivalent code in AdvancedRobot modules, and though it doesn't perform as well as its prototype, I didn't expect it to, since executing one action at a time does impose some limitations.
Presto, facto, finito. My robot was easily beating sample robots with intimidating names such as Walls, Ramfire, Fire, Corners, Tracker, and SittingDuck. Actually SittingDuck only sounds scary, in reality all it does it sit there like some slow bird. My robot comes up the victor most of the time against two other robots, called Spinbot and Crazy, but not always. But hey, my robot is rational and I didn't design it to face crazy people or their crazy robots. Spinbot, I should be able to beat, and I'm tweaking my robot intermittently, between taking breaks writing this blog entry. What is does well is to mave around fast in a circle, and I haven't yet added code to my robot to defeat that exact behavior.
At this point, I should mention that I did not write most of my tests until after I wrote most of my code and let the robot loose on the battlefield, and as usual, I ended up regretting that. Regardless, I did eventually add a few tests, of the unit, behavioral, and acceptance types.
I test that line between robot and enemy and one time instant is perpendicular to line between robot and itself at that time instant and at the time instant two ticks in the future. This is because it takes a robot in Robocode two ticks to react: one to get the information and one to take action.
I also test that the robot never stops (that it never occupies the same spot in N consecutive time instants, where I test the case of n=5).
Perhaps it's trivial, but I also test that the robot fires at lest 5 shots in each battle.
A useful sanity-check type test is to test that the robot detects the enemy at least once for every 360 degree turn of the radar. These are the types of checks that are useful, if nothing else, than for conforming intuition and understanding of the robocode rules and event model.
Finally, I test that the robot does not stop permanently after hitting a wall.
The most diffucult thing about testing robocode robot behavior is the lack of a one-time-click simulator. It would be useful to have a robocode module that allows the visualization of a robot at one tick and at the next one or at the nest n time ticks, to see the effects of different actions.
As with any simulation framework, there's an inherent inefficiency in testing behavior since the framework is not designed to show snapshots but to show the evolution of a battle in time.
The most important lesson I came away with from my robocode coding and testing, is that especially in a simulation environment, where environment variables can influence the behavior of the programmed module, it pays to make small changes incremetally, and test them as you go. Isolating specific behaviors can allow the testing of them independently, and to do this, it pays to have a modular design that allows the switching on and off of features, if only for testing purposes. Good thing I was using version control and that allowed me to have the piece of mind of knowing I could always revert back to a reasonably efficient robot if I got ahead of myself and ended up crippling my robot with too much complexity.
In the meantime I've been brushing up on all the attendant geometry and trigonometry issues that arise when trying to navigate and turn intelligently. I've been frequently referring back to a helpful series of tutorials and sample code at at http://mark.random-article.com/weber/java/robocode/lesson2.html
The one downside is that most of the examples in these tutorials assume you are extending a more complex robot class called AdvancedRobot. I resisted the urge to do that, and stuck with extending the more basic Robot, since I try to avoid premature optimization and also try to follow the KISS principle. The difference between Robt and AdvancedRobot is basically that Robot actions are blocking and AdvancedRobot actions aren't: the Robocode platform allows the non-blocking actions of an AdvancedRobot to be executed simultaneously, while the regular Robot can't walk and chew gum at the same time, but can fake it if he alternates the two fast enough.
One of the first things I did was shamelessly "borrow" two real real nifty and convenient classes from these tutorials, called EnemyRobot and AdvancedEnemyRobot. The former accomplishes the basic function of taking a snapshot of the robot that was just scanned and putting the information from that snapshot in a convenient object. The latter adds basic target prediction by linear two point extrapolation. Not terribly impressive, but a good jumping-off point for moving on to the higher level tactics and strategy.
Speaking of good old strategery, mine is basically a variation of strafing. Strafing means squaring off against your opponent, in other words pointing your tank perpendicular to the imaginary line joining you and your opponent. If you just keep going like this and in small enough increments, you end up "circling" your opponent (in reality you are traversing a bunch of small line segments that look like a curve but are just a series of line segments).
The two obvious variations on strafing are spiraling, or incrementally getting closer to the opponent like you are a satellite crashing into a planet, and veering away in an inverse spiral. The variation I devised, is simply to alternate between coming closer and going farther. This seems like a logical choice since I didn't want to design my robot for close quarters combat, which seems like a potshot anyway, and neither did I want to design my robot to run away like a bullied robot. The alternating motion between closing in and and veering out, also has the nice side-effect of making the robot's movements harder to predict and therefore making the robot harder to target.
I also added some probabilistic firing to make my robot stingy when dealing with a distant target. After all, in robocode, the energy expanded in shooting a bullet comes right out of the robot's life reserve, and if necessary, I want my robot to be able to play it cool and wait for the enemy to have no more gas in the tank, so to speak.
Finally, I added some wall avoidance code adopted from equivalent code in AdvancedRobot modules, and though it doesn't perform as well as its prototype, I didn't expect it to, since executing one action at a time does impose some limitations.
Presto, facto, finito. My robot was easily beating sample robots with intimidating names such as Walls, Ramfire, Fire, Corners, Tracker, and SittingDuck. Actually SittingDuck only sounds scary, in reality all it does it sit there like some slow bird. My robot comes up the victor most of the time against two other robots, called Spinbot and Crazy, but not always. But hey, my robot is rational and I didn't design it to face crazy people or their crazy robots. Spinbot, I should be able to beat, and I'm tweaking my robot intermittently, between taking breaks writing this blog entry. What is does well is to mave around fast in a circle, and I haven't yet added code to my robot to defeat that exact behavior.
At this point, I should mention that I did not write most of my tests until after I wrote most of my code and let the robot loose on the battlefield, and as usual, I ended up regretting that. Regardless, I did eventually add a few tests, of the unit, behavioral, and acceptance types.
I test that line between robot and enemy and one time instant is perpendicular to line between robot and itself at that time instant and at the time instant two ticks in the future. This is because it takes a robot in Robocode two ticks to react: one to get the information and one to take action.
I also test that the robot never stops (that it never occupies the same spot in N consecutive time instants, where I test the case of n=5).
Perhaps it's trivial, but I also test that the robot fires at lest 5 shots in each battle.
A useful sanity-check type test is to test that the robot detects the enemy at least once for every 360 degree turn of the radar. These are the types of checks that are useful, if nothing else, than for conforming intuition and understanding of the robocode rules and event model.
Finally, I test that the robot does not stop permanently after hitting a wall.
The most diffucult thing about testing robocode robot behavior is the lack of a one-time-click simulator. It would be useful to have a robocode module that allows the visualization of a robot at one tick and at the next one or at the nest n time ticks, to see the effects of different actions.
As with any simulation framework, there's an inherent inefficiency in testing behavior since the framework is not designed to show snapshots but to show the evolution of a battle in time.
The most important lesson I came away with from my robocode coding and testing, is that especially in a simulation environment, where environment variables can influence the behavior of the programmed module, it pays to make small changes incremetally, and test them as you go. Isolating specific behaviors can allow the testing of them independently, and to do this, it pays to have a modular design that allows the switching on and off of features, if only for testing purposes. Good thing I was using version control and that allowed me to have the piece of mind of knowing I could always revert back to a reasonably efficient robot if I got ahead of myself and ended up crippling my robot with too much complexity.
Ant aint just XML
So, after having used rake a few times, I jumped head first into the Java build/deploy tool called Ant. It came out of the Apache project and was originally a custom build tool for Tomcat.
Put simply, Ant is Xml. A lot like Xslt (which it itself Xml), an Ant file embodies tasks that are meant to be executed. These tasks are executed in Java or in the language of the underlying shell. Like Xslt, and unlike Html, Ant seems to be Turing complete, meaning you theoretically can use it to perform whatever calculations you want.
Unlike Xslt though, Ant is partly a declarative language that lets the programmer specify tasks and dependencies, and figures out how to execute those tasks without violating the dependencies. In other words, with some of its features (like dependencies), it lets you specify the what, instead of specifying the how. Other features ares plainly procedural and are just code in Xml clothing: for example the tasks to create, and delete directories, and to compile and run code.
It takes a bit of getting used to the declarative programming paradigm, but it does save a bit of work to just declare stuff and let Ant figure out how to execute it. In particular, the dependency information is specified declaratively, and Ant figures out the dependency graph, makes sure there are no cycles in it, and finds a serialization to execute it.
There were no major surprises for me, except for the fact that even Ant couldn't prevent me from wasting 5-10 minutes of my time figuring out a ClassNotFound exception. I had neglected to remove the .class suffix from the main class specifier string, and Ant happily fed the wrong classname argument to java.
Some useful features I ended up using over and over were the tasks to build and delete directories, the import feature that allows the importing of other Ant files and the property task that allows the creation of immutable variables.
I was able to write a series of Ant files to compile, create javadoc for, run, and package into a zip file, a simple Java project consisting of one source file.
The cool thing about the zip file output, is that you can unzip it (or unjar it since jar files are zip files), and run ant from within the unzipped directory to create a new zip file. This is what allows people to easily and portably share, extend, and modify, Ant based projects.
The only feature I wasn't able to find the the Ant documentation is about how to create a top level directory in the zip file to include all the files you actually want to zip up. I know from many unpleasant surprises, that unzipping a zip file with no single top level directory can inadvertently flood your current directory with a bunch of files you don't want there.
Put simply, Ant is Xml. A lot like Xslt (which it itself Xml), an Ant file embodies tasks that are meant to be executed. These tasks are executed in Java or in the language of the underlying shell. Like Xslt, and unlike Html, Ant seems to be Turing complete, meaning you theoretically can use it to perform whatever calculations you want.
Unlike Xslt though, Ant is partly a declarative language that lets the programmer specify tasks and dependencies, and figures out how to execute those tasks without violating the dependencies. In other words, with some of its features (like dependencies), it lets you specify the what, instead of specifying the how. Other features ares plainly procedural and are just code in Xml clothing: for example the tasks to create, and delete directories, and to compile and run code.
It takes a bit of getting used to the declarative programming paradigm, but it does save a bit of work to just declare stuff and let Ant figure out how to execute it. In particular, the dependency information is specified declaratively, and Ant figures out the dependency graph, makes sure there are no cycles in it, and finds a serialization to execute it.
There were no major surprises for me, except for the fact that even Ant couldn't prevent me from wasting 5-10 minutes of my time figuring out a ClassNotFound exception. I had neglected to remove the .class suffix from the main class specifier string, and Ant happily fed the wrong classname argument to java.
Some useful features I ended up using over and over were the tasks to build and delete directories, the import feature that allows the importing of other Ant files and the property task that allows the creation of immutable variables.
I was able to write a series of Ant files to compile, create javadoc for, run, and package into a zip file, a simple Java project consisting of one source file.
The cool thing about the zip file output, is that you can unzip it (or unjar it since jar files are zip files), and run ant from within the unzipped directory to create a new zip file. This is what allows people to easily and portably share, extend, and modify, Ant based projects.
The only feature I wasn't able to find the the Ant documentation is about how to create a top level directory in the zip file to include all the files you actually want to zip up. I know from many unpleasant surprises, that unzipping a zip file with no single top level directory can inadvertently flood your current directory with a bunch of files you don't want there.
Subscribe to:
Posts (Atom)