Thursday, September 16, 2010

Competitive Robot

Overview:
Assignment 9 was to create a competitive Robot using the lessons learned from the "starter" bots.  The competative bot is to be reasonably sophisticated, but does not have to beat all of the starter bots.  The main objective is to practice implementing programing and documentation standards. 

Design:

Movement:
Compbot's (my Competative Robot) movement mi micks that of sample.Walls.  Basically, the bot hugs the walls and moves clockwise around the arena.  In testing, I found that Walls had the highest likely hood of surviving a fight, as most bots don't implement shooting algorithms that account for corners. 

Building off of Walls, I set my movement to increments of 200 so that compbot can frequently scan for enemies.  Ideally, compbot would scan and move at the same time, alas it doesn't work that way.  Using this method, compbot should be able to scan at pretty frequently as it moves along each wall.  The trade off is sacrificing speed (which can help in avoiding bullets) for the ability to counter attack more often. 

The onHitWall() method (which triggers whenever the bot runs into a wall) lets compbot scan and fire before moving along the next wall.  This little trick should thwart any other would be wall-crawlers, as compbot shoots down the current wall, then scoots around the corner, avoiding any counter fire. 

Targeting:
Compbot's targeting uses a nice little method called normalRelativeAngleDegrees().  The method takes in a 360 degree angle, and returns an angle between -180 and 180, effectively dividing the robot into two arcs (the right arc gets a positive value, and the left arc, a negative value).  Simply put, it makes my life a lot easier.  All I have to do is figure out how far my gun is turned from dead center, add the method's output, and bullets go flying with high degrees of accuracy. 

Firing:
The idea behind compbot's shooting is to save energy up until an enemy is either very close, moving very slowly, or moving along a wall.  Compbot fires strong shots against an enemy that is either directly ahead, directly behind, or directly to the side.  Compbot also fires strong shots against enemy's that have a velocity less than 3(moving slowly), and are fairly close (<800 pixels).  Otherwise, compbot's shots are proportional to the opponent's distance, with lower power for more distant opponents.

Results:
                        Win        Loss    
Walls:              ~50%      ~50%
RamFire:          ~60%      ~40%
SpinBot:           ~70%      ~30%
Crazy:              ~80%      ~20%
Fire:                 ~90%      ~20%
Corners:           ~50%      ~50%
Tracker:           ~85%      ~15%
SittingDuck:      100%          0%

and I'll throw in Velocibot because I consider it to be
the a very good standard to test against.
Velocibot:         ~50%       ~50%



Lessons Learned:
1. Keep it simple.
An earlier version of compbot actually kept track of the opponents last known position, and its current position, using these to estimate the enemy's next position.  Unfortunately, I've forgotten much of the trig. involved with targeting, and compbot ended up flailing its gun around, not hitting anything.  As it turns out, the simpler approach worked best.

2. Documentation is your friend.
At one point, one of my methods made absolutely no sense.  The code should have caused the robot to fire in exactly the opposite direction, but it was performing beautifully.  After half an hour of frantic searching, I realized that the error lay in the fact that one of my variables was being altered during another method call.  Writing notes to oneself isn't a bad idea.

3. Save versions
I kept trying to mess with compbot, but eventually it reached a point where I was hurting my performance.  It would have helped to have separate visioning files for each modification.

Download:
*for some reason, the .jar won't load the source file, so I have included it in the directory "Failbot".
http://www2.hawaii.edu/~gburgess/Failbot/

Tuesday, September 14, 2010

Introduction to RoboCode

I had a blast this past week while working on our newest assignment: RoboCode.  I wish someone had turned me on to this sooner.  RoboCode, for the uninformed, is a BattleBots-esq, Open-Source platform released by IBM.  Basically, you program a robot to move, aim and fire at other robots.  Once you look past the silly testbots, you really start to see the deep-rooted strategy, and elegance of programming.  Some developers went so far as to implement neural net systems in their bots, but I opted stayed in the shallow end of the pool. 

Our assignment was to complete 12 "starter" bots, see the link here for the specifics. 

Overview:
Basically, all of our robots are extending the Robot class.  Battles consist of a series of turns, and Robots should have a run() method which is called each turn.  While running, Robots may experience various Event flags (such as being hit, shot, running into walls, running into other robots, etc).  Robots may (but aren't required to) have methods that deal with these Events, and allow the robot to respond accordingly.  RoboCode tactics consist of three major areas: targeting, movement, and firing.  Targeting is done by whirling around a radar dish that sits atop the Robot's gun.  When it finds another Robot, an Event flag is raised, and the Robot will execute the appropriate method (which usually involves firing).  Movement is the final component of the Robot, and is the simplest defensive tactic the Robot can employ.


I finished all 12 bots in about a week (realistically it was two days with a long hiatus in between).  Once I started planning out my competitive robot, my progress on the "starter" bots dropped all but stopped.  I learned a few tricks while working on my competitive bot, and half wanted to go back and apply them to my "starter" bots.  The main one was an elegant little targeting method that effectively keeps the gun fixed on a single target.  (I'll post more details after the big tournament).  The magic method that makes the algorithm work is normalRelativeAngleDegrees() which turns a given 360 degree angle into an angle between -180 and 180.  My plan for the competitive bot is to use this tracking algorithm, along with a targeting algorithm that sets bullet power proportional to the distance of a target.  This should save energy, and effectively hit any robot that:
  1. Tries to double back on its path
  2. Moves too slowly
  3. Ventures too close
To avoid getting shot, I plan to implement the movement pattern of the testbot "walls".  I found that in a free-for-all matchup, walls had the greatest survivability of any of the other testbots.  Hopefully the combination of these three elements will win the day. 

My "starter" bots:
http://www2.hawaii.edu/~gburgess/glb.zip