Difference between revisions of "Excession/DiveBomber"
Jump to navigation
Jump to search
(submitted code) |
m (moved Excession:DiveBomber to Excession/DiveBomber) |
||
(7 intermediate revisions by 4 users not shown) | |||
Line 1: | Line 1: | ||
− | < | + | A [[Drone]] by [[User:Excession]] |
+ | |||
+ | <syntaxhighlight> | ||
package excession.drones; | package excession.drones; | ||
import static java.lang.Math.PI; | import static java.lang.Math.PI; | ||
+ | import static java.lang.Math.atan; | ||
import static java.lang.Math.atan2; | import static java.lang.Math.atan2; | ||
+ | import static java.lang.Math.min; | ||
+ | import static java.lang.Math.exp; | ||
import static java.lang.Math.sqrt; | import static java.lang.Math.sqrt; | ||
− | |||
import static robocode.util.Utils.normalRelativeAngle; | import static robocode.util.Utils.normalRelativeAngle; | ||
import robocode.AdvancedRobot; | import robocode.AdvancedRobot; | ||
Line 14: | Line 18: | ||
* shots. | * shots. | ||
* | * | ||
− | * @author | + | * @author Excession |
− | * @version 1.0, 2008-06-04 | + | * @version 1.0, 2008-06-04, released as SpiralCircle |
+ | * @version 1.1, 2008-06-09, better spiraling with Gumpertz function, renamed to | ||
+ | * DiveBomber | ||
*/ | */ | ||
− | public class | + | public class DiveBomber extends AdvancedRobot { |
+ | private static final double DISTANCE = 200; | ||
+ | private static final double SPEED = 20.0; | ||
private int direction = 1; | private int direction = 1; | ||
Line 45: | Line 53: | ||
private void move(ScannedRobotEvent event) { | private void move(ScannedRobotEvent event) { | ||
double bearing = event.getBearingRadians(); | double bearing = event.getBearingRadians(); | ||
− | double | + | double range = event.getDistance(); |
− | if ( | + | if (stopped()) { |
− | + | switchDirection(); | |
} | } | ||
− | + | double delta = range - DISTANCE; | |
− | + | double spiral = gompertz(delta); | |
− | |||
− | |||
− | double spiral = | ||
− | |||
− | |||
− | |||
− | |||
− | |||
double d = SPEED; | double d = SPEED; | ||
− | + | double b = sqrt(range * range - (d * d) / 4); | |
− | double alpha = atan2(b, | + | double alpha = atan2(b, d / 2); |
double tankTurn = bearing - alpha + spiral * direction; | double tankTurn = bearing - alpha + spiral * direction; | ||
setTurnRightRadians(tankTurn); | setTurnRightRadians(tankTurn); | ||
setAhead(d * direction); | setAhead(d * direction); | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * Calculate Gompertz function with the following values. | ||
+ | * | ||
+ | * <ul> | ||
+ | * <li> a = PI/2 (90 degrees). | ||
+ | * <li> b = -PI | ||
+ | * <li> c = -0.01 | ||
+ | * </ul> | ||
+ | * | ||
+ | * This allows us to sprial in nicely and then stabilize in a circular | ||
+ | * orbit. | ||
+ | * | ||
+ | * @param x | ||
+ | * @return Gompertz function value for x | ||
+ | * @see http://en.wikipedia.org/wiki/Gompertz_function | ||
+ | */ | ||
+ | private double gompertz(double x) { | ||
+ | return PI / 2 * exp(-PI * exp(-x * 0.01)); | ||
+ | } | ||
+ | |||
+ | private boolean stopped() { | ||
+ | return getVelocity() == 0.0; | ||
+ | } | ||
+ | |||
+ | private void switchDirection() { | ||
+ | direction *= -1; | ||
} | } | ||
Line 77: | Line 105: | ||
double absoluteBearing = getHeadingRadians() + event.getBearingRadians(); | double absoluteBearing = getHeadingRadians() + event.getBearingRadians(); | ||
double radarTurn = normalRelativeAngle(absoluteBearing - getRadarHeadingRadians()); | double radarTurn = normalRelativeAngle(absoluteBearing - getRadarHeadingRadians()); | ||
− | double arcToScan = | + | double arcToScan = min(atan(36.0 / event.getDistance()), PI / 4.0); |
radarTurn += (radarTurn < 0) ? -arcToScan : arcToScan; | radarTurn += (radarTurn < 0) ? -arcToScan : arcToScan; | ||
setTurnRadarRightRadians(radarTurn); | setTurnRadarRightRadians(radarTurn); | ||
Line 93: | Line 121: | ||
} | } | ||
} | } | ||
− | </ | + | |
+ | </syntaxhighlight> | ||
+ | |||
+ | [[Category:Source Code]] |
Latest revision as of 18:30, 18 August 2011
A Drone by User:Excession
package excession.drones;
import static java.lang.Math.PI;
import static java.lang.Math.atan;
import static java.lang.Math.atan2;
import static java.lang.Math.min;
import static java.lang.Math.exp;
import static java.lang.Math.sqrt;
import static robocode.util.Utils.normalRelativeAngle;
import robocode.AdvancedRobot;
import robocode.ScannedRobotEvent;
/**
* A drone that spirals in towards and then circles its enemy and fires pot
* shots.
*
* @author Excession
* @version 1.0, 2008-06-04, released as SpiralCircle
* @version 1.1, 2008-06-09, better spiraling with Gumpertz function, renamed to
* DiveBomber
*/
public class DiveBomber extends AdvancedRobot {
private static final double DISTANCE = 200;
private static final double SPEED = 20.0;
private int direction = 1;
private void init() {
setAdjustRadarForRobotTurn(true);
setAdjustGunForRobotTurn(true);
setAdjustRadarForGunTurn(true);
}
@Override
public void run() {
init();
setTurnRadarRightRadians(2 * PI);
while (true) {
execute();
}
}
@Override
public void onScannedRobot(ScannedRobotEvent event) {
lockOnTarget(event);
aimAndFire(event);
move(event);
}
private void move(ScannedRobotEvent event) {
double bearing = event.getBearingRadians();
double range = event.getDistance();
if (stopped()) {
switchDirection();
}
double delta = range - DISTANCE;
double spiral = gompertz(delta);
double d = SPEED;
double b = sqrt(range * range - (d * d) / 4);
double alpha = atan2(b, d / 2);
double tankTurn = bearing - alpha + spiral * direction;
setTurnRightRadians(tankTurn);
setAhead(d * direction);
}
/**
* Calculate Gompertz function with the following values.
*
* <ul>
* <li> a = PI/2 (90 degrees).
* <li> b = -PI
* <li> c = -0.01
* </ul>
*
* This allows us to sprial in nicely and then stabilize in a circular
* orbit.
*
* @param x
* @return Gompertz function value for x
* @see http://en.wikipedia.org/wiki/Gompertz_function
*/
private double gompertz(double x) {
return PI / 2 * exp(-PI * exp(-x * 0.01));
}
private boolean stopped() {
return getVelocity() == 0.0;
}
private void switchDirection() {
direction *= -1;
}
/**
* @see http://testwiki.roborumble.org/w/index.php?title=Radar#Wide_lock
*/
private void lockOnTarget(ScannedRobotEvent event) {
double absoluteBearing = getHeadingRadians() + event.getBearingRadians();
double radarTurn = normalRelativeAngle(absoluteBearing - getRadarHeadingRadians());
double arcToScan = min(atan(36.0 / event.getDistance()), PI / 4.0);
radarTurn += (radarTurn < 0) ? -arcToScan : arcToScan;
setTurnRadarRightRadians(radarTurn);
}
private void aimAndFire(ScannedRobotEvent event) {
double absoluteBearing = getHeadingRadians() + event.getBearingRadians();
double gunTurn = normalRelativeAngle(absoluteBearing - getGunHeadingRadians());
setTurnGunRightRadians(gunTurn);
final double power = 3.0;
if (getGunHeat() == 0.0) {
setFire(power);
}
}
}