Quantum/Source

From Robowiki
Jump to navigation Jump to search
// -------------------------------------------------------------------------------------------------
// ==============
// Quantum (Nano)
// ==============
// Author: David414
// License: RWPCL (https://robowiki.net/wiki/RWPCL)
// -------------------------------------------------------------------------------------------------

// -------------------------------------------------------------------------------------------------
// Credits
// -------------------------------------------------------------------------------------------------
// Quantum started out life as a tweaked version of Mike Dorgan's DustBunny before being heavily
// shrunk to make room for improved target tracking (inspired by Infinity, also by Mike).

// -------------------------------------------------------------------------------------------------
// Version History
// -------------------------------------------------------------------------------------------------
// =================================================================================================
// v0.2.2 (2024-04-06) Codesize: 249  | Colors: Yes | 1v1 capable: No
// =================================================================================================
// - Antigravity movement based on DustBunny, but with forces calculated based on
//   where we would aim to hit the enemy, rather than where they currently are
// - Aim like DustBunny but with different energy management based only on how
//   many enemies are still alive. Fire more agressively early on and much less
//   agressively in 1v1
// - Quite a bit of code shrinking to make room for Infinity style target tracking
//
// =================================================================================================
// v0.2.2a (2024-04-11) Codesize: 249  | Colors: Yes | 1v1 capable: No
// =================================================================================================
// - No functional changes, added credits, version history and commented the code
//
// =================================================================================================
// v0.2.3 (2024-05-14) Codesize: 245  | Colors: Yes | 1v1 capable: No
// =================================================================================================
// - Change to int for distance and targetDistance variables
// - Switch to a gunHeat radar lock that doesn't require an if statement
// - Switch from setTurnRight to setTurnLeft

package d414.nano;

import robocode.*;
import robocode.util.Utils;

import java.awt.Color;

public class Quantum extends AdvancedRobot {
    // ---------------------------------------------------------------------------------------------
    // Tuning Knobs
    // ---------------------------------------------------------------------------------------------
    static final double WALL_FORCE = 1.0;
    static final double AGRAV_DECAY = 0.9;
    static final double AHEAD_AMOUNT = 120.0;

    static final double AIM_START = 10.0;
    static final double AIM_FACTOR = 1.008;
    static final double RADAR_LOCK_THRESHOLD = 1.0;
    static final int POWER_FACTOR = 2;

    // ---------------------------------------------------------------------------------------------
    // Globals
    // ---------------------------------------------------------------------------------------------
    static String targetName;
    static int targetDistance;
    static double xForce;
    static double yForce;

    @Override
    public void run() {
        setAllColors(Color.cyan);
        setAdjustGunForRobotTurn(true);
        onRobotDeath(null);
        setTurnRadarRight(Double.POSITIVE_INFINITY);
    }

    @Override
    public void onRobotDeath(RobotDeathEvent r1e) {
        targetDistance = Integer.MAX_VALUE;
    }

    @Override
    public void onScannedRobot(ScannedRobotEvent r1e) {
        int r2i;
        double r3d;

        setTurnLeftRadians(Utils.normalRelativeAngle(
                    (r3d = getHeadingRadians())
                    - Math.atan2(
                        (xForce = xForce * AGRAV_DECAY
                         - Math.sin(r3d = (r3d += r1e.getBearingRadians())
                             + (r1e.getVelocity()
                                 * Math.sin(r1e.getHeadingRadians() - r3d)
                                 / (AIM_START + Math.pow(AIM_FACTOR, r2i = (int)r1e.getDistance()))
                               )
                             ) / r2i
                        )
                        + calcWallForce(getX())
                        , 
                        (yForce = yForce * AGRAV_DECAY - Math.cos(r3d) / r2i)
                        + calcWallForce(getY())
                        )
                    ));
        setAhead(AHEAD_AMOUNT - Math.abs(getTurnRemaining()));

        if (r2i < targetDistance || r1e.getName() == targetName) {
            targetName = r1e.getName();
            targetDistance = r2i;

            setTurnRadarRight((getGunHeat() - RADAR_LOCK_THRESHOLD) * getRadarTurnRemaining());
            setFire(getOthers() / POWER_FACTOR);
            setTurnGunRightRadians(Utils.normalRelativeAngle(r3d - getGunHeadingRadians()));
        }
    }

    public static double calcWallForce(double r0d) {
        return (WALL_FORCE / r0d) - (WALL_FORCE / (1000 - r0d));
    }
}