Jen/Code

From Robowiki
< Jen
Revision as of 17:15, 27 May 2009 by Voidious (talk | contribs) (Jen's source)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search
Jen Sub-pages:
JenVersion History - Code - Archived Talk 20090527

This is the code to Jen 1.10. Code size is 716 when compiled with Jikes.


package voidious.micro;

import robocode.*;
import robocode.util.Utils;
import java.awt.geom.*;

/**
 * Jen - a MicroBot by Voidious
 *
 * She's a duelist, and assumes it's a 1 on 1.
 *
 * CREDITS:
 *   Jamougha - gun based on Komarious, which is based on RaikoMicro 1.44
 *   Iiley - small codesize BackAsFront method
 *   PEZ - iterative WallSmoothing algorithm
 *
 * Code is open source, released under the RoboWiki Public Code License:
 * http://robowiki.net/cgi-bin/robowiki?RWPCL
 */

public class Jen extends AdvancedRobot {
    public static Point2D.Double _enemyLocation;

    static final double WALL_STICK = 160;
    static final double A_LITTLE_MORE_THAN_HALF_PI = 1.9;
    static final double A_LOT_MORE_THAN_HALF_PI = 2.2;
    static final double WAVE_MAX_ESCAPE_ANGLE = 0.60824557891021;
    static final double SINGLE_GF_ANGLE = .03379142105057;
    static final double LOG_BASE_E_TO_2_CONVERSION_CONSTANT = 1.4427;
    static final int GF_ZERO = 18;
    static final int GF_ONE = 36;
    
    private static int _orbitDirection = 1;
    private static boolean _movingRandomly;
    private static long _timeSinceEnemyFired;
    private static double _oppEnergy;
    
    static double[][][][] _gunStats = new double[2][5][5][GF_ONE+1];

    public void run() {
        setAdjustGunForRobotTurn(true);
        setAdjustRadarForGunTurn(true);

        do {
            turnRadarRightRadians(1);
        } while (true);

    }

    public void onScannedRobot(ScannedRobotEvent e) {
        Wave w;
        int bestGF;
        double enemyAbsoluteBearing;
        double eDistance = e.getDistance();
        Point2D.Double myLocation;
        
        java.awt.geom.Rectangle2D.Double fieldRect
            = new java.awt.geom.Rectangle2D.Double(18, 18, 764, 564);

        addCustomEvent(w = new Wave());
        setTurnRadarRightRadians(Utils.normalRelativeAngle(
            (w.directAngle = enemyAbsoluteBearing = 
                getHeadingRadians() + e.getBearingRadians()) - 
                    getRadarHeadingRadians()) * 2);
        _enemyLocation =
            project((w.sourceLocation = myLocation = 
                new Point2D.Double(getX(), getY())), enemyAbsoluteBearing, 
                    eDistance);

        double bulletPower;
        if ((bulletPower = _oppEnergy - (_oppEnergy = e.getEnergy())) <= 3
            && bulletPower > 0) {
            if ((!_movingRandomly) && 
                Math.abs(Math.sin(e.getBearingRadians())) < 
                    (.8 - (eDistance / 1000))) {
                _orbitDirection *= -1;
            }

            _timeSinceEnemyFired = 0;
        }

        _timeSinceEnemyFired++;
        setMaxVelocity(8);
        if (_movingRandomly) {
            if (Math.random() < 1.0 / (_timeSinceEnemyFired + 8)) {
                _orbitDirection *= -1;
            }
        } else {
            if (_timeSinceEnemyFired >= 9 && eDistance > 100) {
                setMaxVelocity(0);
            }
        }
        
        double goAngle = enemyAbsoluteBearing - 
            (_orbitDirection * (eDistance < 200 ? 
                A_LOT_MORE_THAN_HALF_PI : A_LITTLE_MORE_THAN_HALF_PI));
        
        // CREDIT: Iterative WallSmoothing by PEZ
        // http://robowiki.net?WallSmoothing
        while (!fieldRect.contains(project(myLocation, goAngle, WALL_STICK))) {
            goAngle += _orbitDirection*0.05;
        }
        
        // CREDIT: code by Iiley, optimized with idea from ChaseSan
        // http://robowiki.net?BackAsFront
        setTurnRightRadians(Math.tan(goAngle -= getHeadingRadians()));
        setAhead(Math.cos(goAngle) * Double.POSITIVE_INFINITY);

        ////////////////////////////////////////////////////////
        // CREDIT: RaikoMicro's gun, by Jamougha
        // http://robowiki.net?RaikoMicro

        // ------------- Fire control -------
        double enemyLatVel = 
            (e.getVelocity())*Math.sin(e.getHeadingRadians() - 
                enemyAbsoluteBearing);
        int orientation = 1;
        if (enemyLatVel < 0) { orientation = -1; }

        w.waveGuessFactors = _gunStats[fieldRect.contains(project(myLocation, enemyAbsoluteBearing + (orientation*.4), eDistance)) ? 1 : 0][(int)((Math.abs(enemyLatVel)+1)/2)][(int)(eDistance/200)];
//        w.waveGuessFactors = _gunStats[(int)(wallDistance * 3)][(int)(Math.abs(enemyLatVel)/2)][(int)(eDistance/167)]; // TC

        bestGF = GF_ZERO;

        for (int gf = GF_ONE; gf >= 0 && (e.getEnergy()) > 0; gf--) // Jamougha: Saves one byte compared to going up, weird
            if (w.waveGuessFactors[gf] > w.waveGuessFactors[bestGF])
                bestGF = gf;

        setTurnGunRightRadians(Utils.normalRelativeAngle(enemyAbsoluteBearing - getGunHeadingRadians() + (((w.orientation = orientation)*(SINGLE_GF_ANGLE))*(bestGF-GF_ZERO)) ));
//        setTurnGunRightRadians(Utils.normalRelativeAngle(_enemyAbsoluteBearing - getGunHeadingRadians() + ((orientation*.035406)*(bestGF-GF_ZERO)) )); // TC

        setFireBullet(eDistance < 150 ? 3 : 2);
//      setFireBullet(3); // TC

        ////////////////////////////////////////////////////////

    }

    public void onCustomEvent(CustomEvent e) {
        removeCustomEvent(e.getCondition());
    }
    
    public void onDeath(DeathEvent e) {
        if (getRoundNum() < 3) {
            _movingRandomly = true;
        }
    }

    // CREDIT: ganked from CassiusClay, by PEZ
    // http://robowiki.net?CassiusClay
    private static Point2D.Double project(Point2D.Double sourceLocation, double angle, double length) {
        return new Point2D.Double(sourceLocation.x + Math.sin(angle) * length,
            sourceLocation.y + Math.cos(angle) * length);
    }
}

class Wave extends Condition {
    Point2D.Double sourceLocation;
    double[] waveGuessFactors;
    double directAngle, distance;
    int orientation;

    public boolean test() {
        if (sourceLocation.distance(Jen._enemyLocation) <= (distance+=14)) {
            waveGuessFactors[(int)
                ((((Utils.normalRelativeAngle(
                    Math.atan2(Jen._enemyLocation.x - sourceLocation.x, 
                        Jen._enemyLocation.y - sourceLocation.y)
                    - directAngle) * orientation)
                    / Jen.WAVE_MAX_ESCAPE_ANGLE)
                    * (Jen.GF_ZERO)) + (Jen.GF_ZERO))]++;
            return true;
        }
        return false;
    }
}