User:Chase-san/Ani

From Robowiki
Jump to navigation Jump to search
package cs;

import java.awt.Color;
import java.awt.geom.Point2D;
import java.util.Iterator;
import java.util.LinkedList;

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

/**
 * Prototype micro (ish) surfer. Broken currently.
 */
public class Ani extends AdvancedRobot {
	private static double lastEnergy;
	private LinkedList<double[]> waves = new LinkedList<double[]>();
	private static int direction = 1;
	private double avoidAngle = 0;
	private double[] bW = null;

	@Override
	public void run() {
		lastEnergy = 100;
		setAdjustRadarForGunTurn(true);
		setAdjustGunForRobotTurn(true);
		setAllColors(Color.decode("#33aa44"));

		turnRadarRightRadians(10);
		while(true) scan();
	}

	@Override
	public void onScannedRobot(ScannedRobotEvent e) {
		double bearing = e.getBearingRadians();
		double angleToEnemy = getHeadingRadians();
		double delta = lastEnergy - (lastEnergy=e.getEnergy());

		setTurnRadarRightRadians(1.9*Utils.normalRelativeAngle((angleToEnemy += bearing) - getRadarHeadingRadians()));

		setTurnGunRightRadians(Utils.normalRelativeAngle(angleToEnemy - getGunHeadingRadians()));
		setTurnRightRadians(Math.cos(bearing));


		if(delta > 0 && delta <= 3.0) {
			//Add wave
			waves.add(new double[] {
					getX() + Math.sin(angleToEnemy) * e.getDistance(),
					getY() + Math.cos(angleToEnemy) * e.getDistance(),
					angleToEnemy+Math.PI,
					Rules.getBulletSpeed(delta),
					e.getTime()
			});
		}


		if(!waves.isEmpty()) {

			//find the best wave, and use it (also remove old unused waves here)
			double etlv = 100;
			Iterator<double[]> it = waves.iterator();
			while(it.hasNext()) {
				double[] w = it.next();

				double eta = (Point2D.distance(getX(), getY(), w[0], w[1]) - w[3]*(getTime()-w[4]))/w[3];
				if(eta < 0) {
					it.remove();
					continue;
				}
				if(eta < etlv) {
					etlv = eta;
					bW = w;
				}
			}

			setAhead(direction*100);

			if(bW != null) {
				//found best wave to surf

				//linear velocity
				etlv = getVelocity()*Math.sin(bearing) > 0 ? 1 : 0;

				//the angle from wave origin to current location
				delta = Utils.normalRelativeAngle(angleFromTo(bW[0],bW[1],getX(),getY()) - bW[2]);

				//forward sensor
				double agl = delta + findThatFNAngle(e.getDistance(),32) * etlv;

				angleToEnemy = Math.abs(Utils.normalRelativeAngle(agl - avoidAngle));

				//reverse sensor
				agl = delta - findThatFNAngle(e.getDistance(),16) * etlv;

				if(Math.abs(Utils.normalRelativeAngle(agl - avoidAngle)) > angleToEnemy) {
					direction *= -1;
				}
			}
		}
	}

	@Override
	public void onHitByBullet(HitByBulletEvent e) {
		avoidAngle = Utils.normalRelativeAngle(e.getHeadingRadians() - bW[2]);
		System.out.println("New angle to avoid " + avoidAngle);
	}

	@Override
	public void onHitWall(HitWallEvent e) {
		direction *= -1;
	}

	public static final double findThatFNAngle(double d, double n) {
		return Math.asin(n/Math.sqrt(d*d+n*n));
	}

	public static final double angleFromTo(double fx, double fy, double toy, double tox) {
		return Math.atan2(tox - fx, toy - fy);
	}
}