BlitzBat/Code
< BlitzBat
Jump to navigation
Jump to search
- BlitzBat Sub-pages:
- BlitzBat - Version History - Code
Code for BlitzBat 1.05. Code Size is 741 when compiled with Jikes. (I think 20+ for the colors.)
package voidious.micro;
import robocode.*;
import robocode.util.Utils;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.Color;
import java.util.Iterator;
import java.util.HashMap;
import java.util.ArrayList;
/**
* BlizBat - a robot by Voidious
*
* A MicroBot melee specialist. Uses Minimum Risk movement and Head-On
* Targeting. Initially whipped up one afternoon while working on
* Diamond and waiting for test beds to run.
*
* Code is open source, released under the RoboWiki Public Code License:
* http://robowiki.net/cgi-bin/robowiki?RWPCL
*/
public class BlitzBat extends AdvancedRobot {
protected static final double TWO_PI = Math.PI * 2;
protected static Rectangle2D.Double _fieldRect;
protected static Point2D.Double _destination;
protected static String _targetName;
protected static double _targetDistance;
protected static HashMap _enemies = new HashMap();
protected static Point2D.Double _myLocation;
protected ArrayList _recentLocations;
public void run() {
setAdjustGunForRobotTurn(true);
setAdjustRadarForGunTurn(true);
setColors(new Color(90, 40, 12), Color.black, Color.black);
_fieldRect = new Rectangle2D.Double(50, 50,
getBattleFieldWidth() - 100, getBattleFieldHeight() - 100);
_recentLocations = new ArrayList();
_targetDistance = Double.POSITIVE_INFINITY;
_destination = null;
do {
Point2D.Double myLocation = _myLocation =
new Point2D.Double(getX(), getY());
_recentLocations.add(0, myLocation);
EnemyData targetData = (EnemyData)_enemies.get(_targetName);
/////////////////////////////////
// Gun
try {
setTurnGunRightRadians(Utils.normalRelativeAngle(
absoluteBearing(myLocation, targetData) -
getGunHeadingRadians()));
} catch (NullPointerException ex) { }
setFire(3 - ((20 - getEnergy()) / 6));
/////////////////////////////////
// Movement
double bestRisk;
try {
bestRisk = evalDestinationRisk(_destination) * .85;
} catch (NullPointerException ex) {
bestRisk = Double.POSITIVE_INFINITY;
}
try {
for (double d = 0; d < TWO_PI; d += 0.1) {
Point2D.Double newDest = project(myLocation, d,
Math.min(_targetDistance, 100 + Math.random() * 200));
double thisRisk = evalDestinationRisk(newDest);
if (_fieldRect.contains(newDest) &&
thisRisk < bestRisk) {
bestRisk = thisRisk;
_destination = newDest;
}
}
double angle = Utils.normalRelativeAngle(
absoluteBearing(myLocation, _destination) -
getHeadingRadians());
setTurnRightRadians(Math.tan(angle));
setAhead(Math.cos(angle) * Double.POSITIVE_INFINITY);
} catch (NullPointerException ex) { }
/////////////////////////////////
// Radar and execute
setTurnRadarRightRadians(1);
execute();
/////////////////////////////////
} while (true);
}
public void onScannedRobot(ScannedRobotEvent e) {
double eDistance = e.getDistance();
EnemyData eData = new EnemyData();
eData.setLocation(project(_myLocation, e.getBearingRadians() +
getHeadingRadians(), eDistance));
eData.energy = e.getEnergy();
_enemies.put(e.getName(), eData);
if (eDistance < _targetDistance ||
e.getName().equals(_targetName)) {
_targetDistance = eDistance;
_targetName = e.getName();
}
}
public void onRobotDeath(RobotDeathEvent e) {
_enemies.remove(e.getName());
_targetDistance = Double.POSITIVE_INFINITY;
}
protected double evalDestinationRisk(Point2D.Double d) {
double risk = 0;
Iterator enemiesIterator = _enemies.values().iterator();
while (enemiesIterator.hasNext()) {
EnemyData ed = (EnemyData)enemiesIterator.next();
double distSq = ed.distanceSq(d);
int closer = 0;
Iterator enemiesIterator2 = _enemies.values().iterator();
while (enemiesIterator2.hasNext()) {
if (ed.distanceSq((EnemyData)enemiesIterator2.next())
< distSq) {
closer++;
}
}
risk += Math.max(0.5, Math.min(ed.energy / getEnergy(), 2))
* (1 + Math.abs(Math.cos(absoluteBearing(_myLocation, d) -
absoluteBearing(_myLocation, ed))))
// * (12 + Math.sqrt(cornerDistance(d)))
/ closer
/ distSq
/ (200000 + d.distanceSq(
getBattleFieldWidth() / 2, getBattleFieldHeight() / 2));
}
for (int x = 1; x < 6; x++) {
try {
risk *= 1 + (500 / x /
((Point2D.Double)_recentLocations.get(x * 10))
.distanceSq(d));
} catch (Exception ex) { }
}
return risk;
}
protected static double absoluteBearing(Point2D.Double source, Point2D.Double target) {
return Math.atan2(target.x - source.x, target.y - source.y);
}
public static Point2D.Double project(Point2D.Double sourceLocation,
double angle, double length) {
return new Point2D.Double(sourceLocation.x + Math.sin(angle) * length,
sourceLocation.y + Math.cos(angle) * length);
}
}
class EnemyData extends Point2D.Double{
double energy;
}