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; }