Difference between revisions of "Excession/DiveBomber"

From Robowiki
Jump to navigation Jump to search
m (updated author tag)
(updated to v1.1 and renamed DiveBomber)
Line 4: Line 4:
 
package excession.drones;
 
package excession.drones;
  
 +
import static java.lang.Math.E;
 
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.pow;
 
import static java.lang.Math.sqrt;
 
import static java.lang.Math.sqrt;
import static java.lang.Math.toRadians;
 
 
import static robocode.util.Utils.normalRelativeAngle;
 
import static robocode.util.Utils.normalRelativeAngle;
 
import robocode.AdvancedRobot;
 
import robocode.AdvancedRobot;
Line 17: Line 20:
 
  *  
 
  *  
 
  * @author Excession
 
  * @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 SpiralCircle extends AdvancedRobot {
+
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 47: Line 54:
 
     private void move(ScannedRobotEvent event) {
 
     private void move(ScannedRobotEvent event) {
 
         double bearing = event.getBearingRadians();
 
         double bearing = event.getBearingRadians();
         double r = event.getDistance();
+
         double range = event.getDistance();
  
         if (getVelocity() == 0.0) {
+
         if (stopped()) {
             direction *= -1;
+
             switchDirection();
 
         }
 
         }
  
         final double SPEED = 20.0;
+
         double delta = range - DISTANCE;
        final double DISTANCE_MAX = 50;
+
         double spiral = gompertz(delta);
        final double DISTANCE_MIN = 40;
 
 
 
         double spiral = 0;
 
        if (r > DISTANCE_MAX) {
 
            spiral = toRadians(45);
 
        } else if (r < DISTANCE_MIN) {
 
            spiral = toRadians(-5);
 
        }
 
  
 
         double d = SPEED;
 
         double d = SPEED;
         final double b = sqrt(r * r - (d * d) / 4);
+
         double b = sqrt(range * range - (d * d) / 4);
 
         double alpha = atan2(b, (d / 2));
 
         double alpha = atan2(b, (d / 2));
 
         double tankTurn = bearing - alpha + spiral * direction;
 
         double tankTurn = bearing - alpha + spiral * direction;
Line 71: Line 70:
 
         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) {
 +
        double spiral = PI / 2 * (pow(E, (-PI * pow(E, -x * 0.01))));
 +
        return spiral;
 +
    }
 +
 +
    private boolean stopped() {
 +
        return getVelocity() == 0.0;
 +
    }
 +
 +
    private void switchDirection() {
 +
        direction *= -1;
 
     }
 
     }
  
Line 79: Line 107:
 
         double absoluteBearing = getHeadingRadians() + event.getBearingRadians();
 
         double absoluteBearing = getHeadingRadians() + event.getBearingRadians();
 
         double radarTurn = normalRelativeAngle(absoluteBearing - getRadarHeadingRadians());
 
         double radarTurn = normalRelativeAngle(absoluteBearing - getRadarHeadingRadians());
         double arcToScan = Math.min(Math.atan(36.0 / event.getDistance()), PI / 4.0);
+
         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 95: Line 123:
 
     }
 
     }
 
}
 
}
 +
 
</pre>
 
</pre>

Revision as of 14:21, 13 June 2008

A Drone by User:Excession

package excession.drones;

import static java.lang.Math.E;
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.pow;
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) {
        double spiral = PI / 2 * (pow(E, (-PI * pow(E, -x * 0.01))));
        return spiral;
    }

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