package blarg; import java.util.Hashtable; import java.util.Vector; import robocode.AdvancedRobot; import robocode.Bullet; import robocode.HitByBulletEvent; import robocode.HitRobotEvent; import robocode.HitWallEvent; import robocode.ScannedRobotEvent; import robocode.util.Utils; public class Bwaarggll extends AdvancedRobot { Vector targets; Hashtable bullets; boolean openFire; double firePower; boolean leftHand; boolean forward; void dodge() { if (Math.abs(this.getDistanceRemaining()) < 1.0) { if (this.forward) { this.setAhead(100.0); this.forward = false; } else { this.setBack(100.0); this.forward = true; } } } void getClose(Bwaarggll.MyTarget target) { if (target != null && target.getDistance() > 4.0 * this.getEnergy()) { double bearing = target.getBearing(); this.setTurnRight(target.getDistance() / 10.0 + (double)(this.leftHand ? -1 : 1) * bearing); if (this.leftHand) { this.setBack(100.0); } else { this.setAhead(100.0); } } } public void run() { this.openFire = false; this.forward = true; this.targets = new Vector(); this.bullets = new Hashtable(); this.setAdjustGunForRobotTurn(true); this.setAdjustRadarForRobotTurn(true); this.setAdjustRadarForGunTurn(true); while(true) { Bwaarggll.MyTarget target = this.findTarget(); this.getClose(target); this.dodge(); if (this.getGunTurnRemaining() < 1.0 && this.openFire) { this.setFireBullet(this.firePower); this.openFire = false; } this.setTurnRadarRight(360.0); this.execute(); } } Bwaarggll.MyTarget findTarget() { if (this.targets.isEmpty()) { return null; } else { int shots = 0; Bwaarggll.MyTarget tar = null; for(Bwaarggll.MyTarget t : new Vector(this.targets)) { if (this.getTime() - t.lastSeen > 20L) { this.targets.remove(t); } else if (t.shots > shots) { tar = t; shots = t.shots; } } double distance = 1.0E4; if (tar == null) { for(Bwaarggll.MyTarget t : this.targets) { if (t.getDistance() < distance) { tar = t; distance = t.getDistance(); } } } if (tar == null) { return null; } else { double grt = Utils.normalRelativeAngleDegrees(tar.whereToShoot() - this.getGunHeading()); if (grt > 0.0) { this.setTurnGunRight(grt); } else { this.setTurnGunLeft(-grt); } this.firePower = tar.howHardToShoot(); this.openFire = true; return tar; } } } boolean targetKnown(String name) { for(Bwaarggll.MyTarget t : this.targets) { if (t.name == name) { return true; } } return false; } void addTarget(String name) { this.targets.add(new Bwaarggll.MyTarget(name)); } void updateTarget(ScannedRobotEvent e) { Bwaarggll.MyTarget tar = null; for(Bwaarggll.MyTarget t : this.targets) { if (t.name == e.getName()) { tar = t; break; } } if (tar != null) { tar.update(e); } } Bwaarggll.MyTarget getTarget(String name) { for(Bwaarggll.MyTarget t : this.targets) { if (t.name == name) { return t; } } return null; } public void onHitWall(HitWallEvent e) { this.leftHand = !this.leftHand; } public void onHitRobot(HitRobotEvent e) { this.leftHand = !this.leftHand; } public void onScannedRobot(ScannedRobotEvent e) { if (!this.targetKnown(e.getName())) { this.addTarget(e.getName()); } this.updateTarget(e); } public void onHitByBullet(HitByBulletEvent e) { if (!this.targetKnown(e.getName())) { this.addTarget(e.getName()); } Bwaarggll.MyTarget tar = this.getTarget(e.getName()); ++tar.shots; this.setTurnLeft(90.0 - e.getBearing()); } class MyTarget { String name; double x; double y; double heading; double velocity; double energy; int fired; int hits; int shots; long lastSeen; public String getName() { return this.name; } public MyTarget(String name) { this.name = name; this.fired = 0; this.hits = 0; this.shots = 0; } public void update(ScannedRobotEvent e) { this.x = Bwaarggll.this.getX() + e.getDistance() * Math.cos(Math.toRadians(-e.getBearing() + 90.0 - Bwaarggll.this.getHeading())); this.y = Bwaarggll.this.getY() + e.getDistance() * Math.sin(Math.toRadians(-e.getBearing() + 90.0 - Bwaarggll.this.getHeading())); this.heading = 90.0 - e.getHeading(); this.velocity = e.getVelocity(); this.energy = e.getEnergy(); this.lastSeen = Bwaarggll.this.getTime(); } public double howHardToShoot() { double dx = this.x - Bwaarggll.this.getX(); double dy = this.y - Bwaarggll.this.getY(); double d2 = dx * dx + dy * dy; if (d2 < 10000.0) { return 3.0; } else { return d2 < 200000.0 ? 2.0 : 1.0; } } public double getBearing() { double dx = this.x - Bwaarggll.this.getX(); double dy = this.y - Bwaarggll.this.getY(); double ang = 90.0 - Math.toDegrees(Math.atan2(dy, dx)) - Bwaarggll.this.getHeading(); return Utils.normalRelativeAngleDegrees(ang); } public double getDistance() { double dx = this.x - Bwaarggll.this.getX(); double dy = this.y - Bwaarggll.this.getY(); return Math.sqrt(dx * dx + dy * dy); } public double whereToShoot() { double TRUST = 0.5; double dx = this.x - Bwaarggll.this.getX(); double dy = this.y - Bwaarggll.this.getY(); double d = Math.sqrt(dx * dx + dy * dy); double th = d / (20.0 - 3.0 * this.howHardToShoot()); double v = this.velocity; double xh = dx + TRUST * th * v * Math.cos(Math.toRadians(this.heading)); double yh = dy + TRUST * th * v * Math.sin(Math.toRadians(this.heading)); return 90.0 - Math.toDegrees(Math.atan2(yh, xh)); } } }