/** * */ package rampancy.mini; import java.awt.Color; import java.awt.geom.Line2D; import java.awt.geom.Point2D; import rampancy.util.RPoint; import robocode.*; import robocode.util.Utils; /** * @author Matthew Chun-Lum * */ public class Swingline extends AdvancedRobot { double shotsFired; double shotsHit; double hitPercentage; double lastHeading; RPoint targetLocation; RPoint myLocation; public void run() { setColors(new Color(0xED1A1A), new Color(0x911a10), new Color(0x911a10), Color.white, new Color(0x911a10)); setAdjustGunForRobotTurn(true); setAdjustRadarForRobotTurn(true); setAdjustRadarForGunTurn(true); shotsFired = 0; shotsHit = 0; hitPercentage = 0; while(getRadarTurnRemainingRadians() == 0) { setTurnRadarRightRadians(Math.PI * 5); } } public void onScannedRobot(ScannedRobotEvent e) { myLocation = new RPoint(getX(), getY()); doRadar(e); doGun(e); lastHeading = e.getHeadingRadians(); } public void doRadar(ScannedRobotEvent e) { double radarBearingOffset = Utils.normalRelativeAngle(getRadarHeadingRadians() - (e.getBearingRadians() + getHeadingRadians())); int sign = (radarBearingOffset < 0 ? -1 : 1 ); setTurnRadarLeftRadians(radarBearingOffset + sign * (Math.PI / 6)); } public void doGun(ScannedRobotEvent e) { double absBearing = e.getBearingRadians() + getHeadingRadians(); targetLocation = project(myLocation, absBearing, e.getDistance()); double heading = e.getHeadingRadians(); double dh = heading - lastHeading; double bestPower = 0.5; double maxPower = computeMaxPower(e); double gunAngle = absBearing - getGunHeadingRadians(); if(e.getEnergy() != 0) { for(int i = 0; i < 100; i++) { heading += dh; targetLocation = project(targetLocation, heading, e.getVelocity()); double power = computeBulletPower(targetLocation.distance(myLocation) / (i + 1)); if(power > maxPower || targetLocation.x > getBattleFieldWidth() || targetLocation.x < 0 || targetLocation.y < 0 || targetLocation.y > getBattleFieldHeight()) { break; } if(power > bestPower) { gunAngle = Utils.normalRelativeAngle(computeAbsoluteBearing(myLocation, targetLocation) - getGunHeadingRadians()); bestPower = power; } } } setTurnGunRightRadians(gunAngle); if(setFireBullet(bestPower) != null) { shotsFired++; } } private double computeMaxPower(ScannedRobotEvent e) { if(e.getEnergy() == 0) { return 0.1; } if(e.getDistance() < 30) { return 3.0; } if(hitPercentage == 0) { return 2.5; } return Math.max(0.1, Math.min((hitPercentage + 0.3) * 3.0, 3.0)); } public void onBulletHit(BulletHitEvent e) { shotsHit++; hitPercentage = shotsHit / shotsFired; } public RPoint project(RPoint source, double angle, double length) { double x = source.x + Math.sin(angle) * length; double y = source.y + Math.cos(angle) * length; return new RPoint(x, y); } public double computeAbsoluteBearing(Point2D.Double source, Point2D.Double target) { return Utils.normalAbsoluteAngle(Math.atan2(target.x - source.x, target.y - source.y)); } public double computeBulletPower(double velocity) { return Math.max(0.1, (20.0 - velocity) / 3.0); } }