package crazy;
import robocode.*;
import java.awt.Color;
import java.awt.geom.Point2D;
import robocode.util.Utils;
/**
* CrazyTracker2 - a robot by Ben Pringle
*/
public class CrazyTracker2 extends AdvancedRobot
{
boolean ally = true; //will we work together with other
//Crazy robots?
static double FORWARD = 1;//choose forward or backward
static double rand = 185;//a random number that changes
static int targetStrategy = 1; //1 is Linear
//2 is Head On Targeting
int misscount; //how many times my shots missed
/**
* CrazyTracker2's run method
*/
public void run() {
setColors(Color.blue,Color.black,Color.yellow);
setAdjustGunForRobotTurn(true);//allow gun to move
//freely
while (true)
{
turnRadarRight(360);//scan for enemies
}
}
/**
* onScannedRobot: We have a target. Go get it.
*/
public void onScannedRobot(ScannedRobotEvent e) {
//ensure that we don't fire upon other
//Crazy robots
if(e.getName().length() >= 5 && getOthers() > 1){
if((getName().subSequence(0,5))
.equals(e.getName().subSequence(0,5))){
if(ally==true){//if they have fired at us, we will
return; //not ally with them
}
}
}
//here I use an oscillating movement pattern, but
//I use a constant "rand" that I change randomly
//so that Patternmatchers can't lock onto me
if (getDistanceRemaining() == 0) { FORWARD =
-FORWARD; setAhead(rand * FORWARD);}
setTurnRightRadians(e.getBearingRadians()
+Math.PI/2-0.5236*FORWARD
*(e.getDistance()>200?1:-1));
//here I get my enemy's statistics so that I can use
//linear targeting
if(targetStrategy == 1){
double bulletPower = Math.min(3.0,getEnergy());
double myX = getX();
double myY = getY();
double absoluteBearing =
getHeadingRadians() + e.getBearingRadians();
double enemyX = getX()
+ e.getDistance() * Math.sin(absoluteBearing);
double enemyY = getY()
+ e.getDistance() * Math.cos(absoluteBearing);
double enemyHeading = e.getHeadingRadians();
double enemyVelocity = e.getVelocity();
//now I do my calculations for linear targeting so that
//I know where my enemy will be once my bullet gets there
double deltaTime = 0;
double battleFieldHeight=
getBattleFieldHeight(),battleFieldWidth=
getBattleFieldWidth();
double predictedX = enemyX, predictedY = enemyY;
while((++deltaTime)*(20.0
- 3.0*bulletPower)
<Point2D.Double.distance(myX, myY, predictedX, predictedY)){
predictedX += Math.sin(enemyHeading)
* enemyVelocity;
predictedY += Math.cos(enemyHeading)
* enemyVelocity;
if( predictedX < 18.0
|| predictedY < 18.0
|| predictedX > battleFieldWidth - 18.0
|| predictedY > battleFieldHeight - 18.0){
predictedX =
Math.min(Math.max(18.0, predictedX), battleFieldWidth
- 18.0);
predictedY =
Math.min(Math.max(18.0, predictedY), battleFieldHeight
- 18.0);
break;}}
double theta = Utils.normalAbsoluteAngle(Math.atan2(predictedX
- getX(), predictedY - getY()));
//now I can turn my gun...
setTurnRadarRightRadians
(Utils.normalRelativeAngle(absoluteBearing
- getRadarHeadingRadians()));
setTurnGunRightRadians(Utils.normalRelativeAngle(theta
- getGunHeadingRadians()));
//...and fire!
fire(3);
}
if(targetStrategy==2||getOthers()>3){
// Calculate exact location of the robot
double absoluteBearing =
getHeading() + e.getBearing();
double bearingFromGun =
normalRelativeAngle(absoluteBearing -
getGunHeading());
// If it's close enough, fire!
if (Math.abs(bearingFromGun) <= 3) {
turnGunRight(bearingFromGun);
// We check gun heat here, because calling fire()
// uses a turn, which could cause us to lose track
// of the other robot.
if (getGunHeat() == 0)
fire (Math.min(3
- Math.abs(bearingFromGun),getEnergy()
- .1));
}
// otherwise just set the gun to turn.
// Note: This will have no effect until we call scan()
else {
turnGunRight(bearingFromGun);
}
// Generates another scan event if we see a robot.
// We only need to call this if the gun (and therefore radar)
// are not turning. Otherwise, scan is called automatically.
if (bearingFromGun == 0)
scan();
}
}
public void onWin(WinEvent e)
{
//My favorite little victory dance.
setAdjustRadarForRobotTurn(true);
setAdjustRadarForGunTurn(true);
setAdjustGunForRobotTurn(true);
for(;;){
setTurnRadarRight(360);
setTurnGunLeft(180);
setTurnLeft(90);
if(getEnergy() > 0.1)
fire(0.1);
}
}
// Helper function
public double normalRelativeAngle(double angle) {
if (angle > -180 && angle <= 180)
return angle;
double fixedAngle = angle;
while (fixedAngle <= -180)
fixedAngle += 360;
while (fixedAngle > 180)
fixedAngle -= 360;
return fixedAngle;
}
/**
* onHitByBullet: Randomize my movement
*/
public void onBulletMissed(BulletMissedEvent e) {
misscount++;
if(misscount > 5){
if(targetStrategy==1)
targetStrategy=2;
if(targetStrategy==2)
targetStrategy=1;
}
}
/**
* onHitByBullet: Randomize my movement
*/
public void onHitByBullet(HitByBulletEvent e) {
//change my movement to throw off patternmatchers
rand += Math.random()*5*FORWARD;
//make sure my allies aren't firing on me, and if
//they are, I will cut short our alliance
if(e.getName().length() >= 5 && getOthers() > 1){
if((getName().subSequence(0,5))
.equals(e.getName().subSequence(0,5))){
if(ally==true){ally = false;}}}
}}