HT.tut.aim.1
This Robot combines the aiming code of the advanced bot HT.SPY.4 with very simple tactics (choose one enemy and use the gun to the max) and a simple movement strategy that forces it's ennemies to use advanced algorithms to detect it. So it's really effective against many simple bots, but very bad against avoider-class-bots and robots that predict his movements. Only fully compatible with Robocode versions before 0.98. Works quite well with version 1.0.7, but some features don't work (this robot has never been ported to Robocode version 0.98).
The first HT.tut.aim.1 was published on 2001-09-30 here:
http://robocode.turbochicken.com/BotDetail.jsp?id=33.
This version (2001-10-03) is over 4 years old now: HT, 2005-10-12.
Hendrik Tessendorf
Code:
// HT.tut.aim.1
//
// For robot-details see "HT.tut.aim.1.readme.txt".
//
//
// Code written in 2001 by HT (some comments are newer).
// Last change: 2005-10-12 (comments by HT)
// Last code change: 2001-10-03
//
//
// This code was first published on 2001-10-06 at
// http://robocode.turbochicken.com/BotDetail.jsp?id=33
// Original description:
/*
Bot Name: HT.tut.aim.1
Package: HT.tut.aim
Derived From: HT.SPY.4 (lol, really!)
Categories: Advance Targeting, Avoiders, Extends AdvancedRobot, Level-Intermediate
Description:
changed to Version 0.96
!!!This bot is not designed to win battles!!!
It should show the math required for advanced aiming.
Hey, why is this bot so good in 1vs1?
Seems to be very effective against some bots!
(eg older bots, Jazzbot, Squigbot and HT.SPY.4
but not against Peryton1_1 or HT.SPY.>4)
I posted this bot because some people want to know the math used for aiming in HT.SPY. So you can say, HT.tut.aim.1 is the aiming of HT.SPY.4 (nearly), added a few jokes (funny;).
(I think: !aiming!=firing!)
*/
package HT.Tut.aim;
import robocode.*;
public class _1 extends AdvancedRobot
{
public void run(){init();loop();}
public void onScannedRobot (ScannedRobotEvent e){Event(e);} //I prefer this.
public void onHitWall (HitWallEvent e){Event(e);}
public void onRobotDeath (RobotDeathEvent e){Event(e);}
final static double bullet_speed(double power){return(20-3*power);}
final static double
//{game constants
bullet_power = 3
,bullet_speed =bullet_speed(bullet_power)
,robot_speed_max = 8
,Robot_Wall_Distance_min =0x12
//}game constants
,wp_accuracy_required =Robot_Wall_Distance_min
,PI=Math.PI
;
boolean turning =false;
void init() // Initialize data, ...
{
turning=!turning;out.println("Mode: turning="+turning);
setAdjustGunForRobotTurn(true); // not sure how often this has to be called,
setAdjustRadarForGunTurn(true); // but since you don't take damage by calling it;-)
// Find our enemy really fast:
setTurnLeftRadians (Double.POSITIVE_INFINITY);
setTurnGunLeftRadians (Double.POSITIVE_INFINITY);
setTurnRadarLeftRadians (Double.POSITIVE_INFINITY);
}
void loop()
{for/*ever*/(;;)
{
move_set();
if(getRadarTurnRemaining()==0)setTurnRadarLeftRadians (Double.POSITIVE_INFINITY);
if(e_name!=null&&(getGunTurnRemaining()*PI/180)<(wp_accuracy_required/e_distance_wh))
fire(bullet_power);
else execute();
}
}
void move_set()
{
if(getDistanceRemaining()==0)
setAhead(Double.POSITIVE_INFINITY);
setTurnLeftRadians(turning?1:(-.5+(double)(getTime()%2))); //"linear"
}
final static int Dist_iteration_max=0x10;
final static double Distd_epsilon=1./0x10;
double hit_angle()
{
e_distance_wh=e_distance;
double dx=e_x-getX(),dy=e_y-getY();
if(!(e_velocity==0&&e_velocityd==0)) //if the robot doesn't move, shoot to where he is.
for(int n=0;n<Dist_iteration_max;n++)
{ //Iterating e_distance_wh
double xl_=e_x,yl_=e_y
,Timed_=e_distance_wh/bullet_speed;
double Heading_ =e_heading,
Velocity_ =e_velocity;
for(long timed=0;timed<Timed_;timed++)
{
if(turning )Heading_ +=e_headingd;
Velocity_ +=e_velocityd; //experimental/untested
if(Velocity_> robot_speed_max)Velocity_= robot_speed_max;
if(Velocity_<-robot_speed_max)Velocity_=-robot_speed_max;
xl_ +=Velocity_*Math.sin(Heading_);
yl_ +=Velocity_*Math.cos(Heading_);
if(out_of_area(xl_,getBattleFieldWidth ())
||out_of_area(yl_,getBattleFieldHeight()))
break; //stop movement because we (the ennemy;-) hit a wall
}
dx=xl_-getX();
dy=yl_-getY();
double e_distance_wh_old=e_distance_wh;
e_distance_wh=Math.sqrt(dx*dx+dy*dy);
if(Math.abs(e_distance_wh-e_distance_wh_old)<Distd_epsilon)
break;
}
return(Math.atan2(dy,dx)-PI/2);
}
boolean out_of_area(double pos,double range){return(pos<Robot_Wall_Distance_min||pos>range-Robot_Wall_Distance_min);}
//{e_: Ennemy Information
String e_name; //the ennemy's name
double
e_time =-1 //e_time : the time of the last ScannedEvent
,e_timed //e_timed: the time passed since the last ScannedEvent
,e_bearing //absolute Bearing
,e_distance //distance from us to this bot
,e_heading ,e_headingd //heading , heading change per time
,e_velocity,e_velocityd //velocity, velocity change per time
,e_x,e_y //absolute position of this bot
//estimated parameters at the time our bullet should hit this bot:
,e_distance_wh //e_distance
,e_angle_wh //angle to this robot
;
//}
void Event(RobotDeathEvent ev)
{
if( e_name==ev.getName())
e_name=null;
}
void Event(HitWallEvent ev)
{
if (ev.getBearing() > -90 && ev.getBearing() <= 90)
setAhead(Double.NEGATIVE_INFINITY);
else setAhead(Double.POSITIVE_INFINITY);
}
void Event(ScannedRobotEvent ev)
{
if((e_name!=null)&&(e_name!=ev.getName()))
return; //if this isn't "our" robot.
//fill all information we need into our e_*
e_name =ev.getName();
e_timed =-e_time+(e_time=ev.getTime());
if(e_timed==0)
{
out.println("I detected \""+e_name+"\" multiple times in one time step!");
out.println("This should never happen, so please contact the author of this bot!");
return;
}
e_bearing =ev.getBearingRadians()+getHeadingRadians(); //translate from relative to absolute bearing
e_distance =ev.getDistance();
e_headingd =(-e_heading +(e_heading =ev.getHeadingRadians ()))/e_timed;
e_velocityd =(-e_velocity+(e_velocity=ev.getVelocity ()))/e_timed;
e_x =getX()+Math.sin(e_bearing)*e_distance;
e_y =getY()+Math.cos(e_bearing)*e_distance;
e_angle_wh =hit_angle();
setTurnGunLeftRadians(normalizeAngle(e_angle_wh+getGunHeadingRadians()));
double radar_turn=normalizeAngle(getRadarHeadingRadians()-e_bearing);
radar_turn+=(radar_turn>0)?(PI/8):(-PI/8); //you can spin your radar by (PI/(4*Ticks))
setTurnRadarLeftRadians (radar_turn);
}
static double normalizeAngle(double alpha)
{
while (alpha> PI)alpha-=2*PI;
while (alpha<-PI)alpha+=2*PI;
return(alpha);
}
}