Sunday, September 7, 2008

Lessons learned from CodeRuler

Intro to CodeRuler

As a bit of a warm-up exercise to get my software engineering class acquainted and reacquainted with Java and Eclipse we were recently assigned to work on a project using the CodeRuler plug-in from IBM. The plug-in contains a fairly complete framework of Java classes that implement a simple game of knights, peasants, castles, and their rulers. World domination is, of course, the goal. Everything is in place except for the implementation of a strategy. This is where my classmates and I come in. So my partner, Arthur Shum, and I set out to create an AI that would give the provided computer strategies a solid challenge and then later this week we set out to conquer the avatars of our classmates as well.

Teamwork

Arthur and myself started off with a slightly disorganized approach to the project. Initially we just wanted to play around and get familiar with the tools available in the CodeRuler interfaces. From there we individually progressed to various simple strategies and incrementally improved certain ideas and tossed out those that didn't work. Eventually I dedicated myself to programming the behavior of the peasants while he worked on strategy for the knights. I'm proud of my little peasants, but I must admit, his knights are quite impressive and I felt as though I may not have contributed as much to the team. Nevertheless, we worked well together despite not meeting up in person. Communication was done online; we would simply email changes to the code back and forth as we discussed strategies, problems, and solutions on gtalk. Eventually, though we both have numerous ideas that we would like to implement, we got to a point where our strategy was quite successful against the provided computers. We feel it will also be competitive against other teams in the class.

Results

Here are some of the results versus the provided AIs.

aricwest-atshumMigrate Ruler
Test 18290
Test 28220
Test 38270
Gang Up Ruler
Test 180448
Test 2792100
Test 3779112
Split Up Ruler
Test 180564
Test 282714
Test 380144

You can find the product of our programming efforts, as well as associated javadocs, here.

Strategy

The basic strategy can be broken up into three parts - one for each unit.

First we have the knights. Arthur came up with a two-team knight approach that sends a small team of knights to capture castles, while the large team goes for enemy knights. To help protect our own castles, the large team prioritizes knights that are closer to our castles. Once the large team wipes out all the knights then it will work on capturing castles, then capturing peasants. The small team instead captures castles, then goes after peasants, then knights. Of course, if either team comes across something else in their path to their main objective they won't hesitate to capture that too. There are some slight variations, but this is the essence of the knight strategy.

Next we have the peasant strategy which I implemented. At first it looks like Random Ruler, and it certainly started out that way. However our peasants are a bit more aware of their surroundings. A peasants basic strategy is to examine the squares around him and randomly pick one that has not been claimed by our team, and is otherwise unoccupied and available. This on its own gives the peasants a quick and rapid start. At some point a peasant will likely become surrounded by land it or another peasant has already captured for our team. At this point our peasant will start moving toward an enemy peasant, since that area will obviously have land belonging to the enemy team. It is also programmed in such a way that our peasants will divide up and chase after different enemy peasants, not cluster after one. Also, if no peasants are available to chase, it will move toward enemy castles. These chase behaviors only last as long as there's no new land to capture. At any point there is new land to capture, the peasants continue with the prime objective - adjacent land. Unfortunately the peasants lack the code to help them evade enemy knights.

The third part of the strategy is simply whether castles should produce knights or peasants. Arthur came up with a simple and effective strategy. Our castles produce knights until we have 50% more than there are enemy knights, then switches to peasants for as long as the 50% more rule holds. A basic overpower-the-enemy strategy, which works thanks to the efficient gathering of land by our peasants, so more are not needed immediately.

Lessons Learned

Over all it was a decent warm-up to Java and Eclipse, both of which I do not have any recent or extensive experience with. However, I think that I didn't take advantage of many features of both that might have made the process easier. Part of it is just not realizing what is available so I work with things I know and understand without branching out enough. I definitely enjoyed using some of the features that had been discussed in our recent software engineering class including the for each and some of basic work with Collections. Working with a partner worked out well and favorably despite never actually meeting in person. In the future I hope to avoid some of the difficulties of emailing our code changes back and forth to merge our additions and changes. An SVN type system would definitely be preferable, but this was a small enough project as to not be a large issue. Our end product is competitive, but I definitely feel it could use some refining in several areas. I would like to add some knight evasion code to the peasant AI. Also there have been time out issues when large numbers of units are in play. Some code could be added to tone down movement when the time out limit is being approached. I'm sure there are also some code that could be more efficient which would help keep the processing time down. Overall though I am pleased with the results and process of this experience.

No comments: