[Home]Starrynte/Lightning

Robo Home | Starrynte | Changes | Preferences | AllPages

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

/**
 * Lightning - a robot by Starrynte
 * Changes
 * ------------------------------------------------------------------
 * Version 0.1
 *     Created!
 *     
 * 
 */
public class Lightning extends AdvancedRobot
{
	static Hashtable enemies=new Hashtable();
	static Point2D.Double nextDestination,lastPosition,myPos,center;
	static Rectangle2D.Double field;
	static Enemy target;
	static double myEnergy,myGunHeat,myGunHeading,myHeading;
	static int timeSinceLastScan;
	
	public void run() {
		initBattle();
		while(true){
			doMovement();
			doGun();
			execute();
		}
	}

	public void onScannedRobot(ScannedRobotEvent e) {
		myPos=new Point2D.Double(getX(),getY());
		myEnergy=getEnergy();
		myGunHeat=getGunHeat();	
		myGunHeading=getGunHeadingRadians();
		myHeading=getHeadingRadians();
		Enemy en=(Enemy)enemies.get(e.getName());
		if(en==null){
			en=new Enemy();
			enemies.put(e.getName(),en);
		}
		en.name=e.getName();
		en.energy=e.getEnergy();
		en.location=projectPoint(myPos,e.getBearingRadians()+getHeadingRadians(),e.getDistance());
		en.distance=e.getDistance();
		en.heading=e.getHeadingRadians();
		en.velocity=e.getVelocity();
		en.ctime=e.getTime();
		en.live=true;
		if((!target.live) || getTime()-target.ctime>20 || (en.distance<target.distance*0.9 && myGunHeat/getGunCoolingRate()>5)){
			if(!target.name.equals(en.name)){
				target=en;
			}
		}
	}

	public void onHitByBullet(HitByBulletEvent e) {
	}
	
	public boolean initBattle(){
		enemies=new Hashtable();
		nextDestination=lastPosition=myPos=new Point2D.Double(getX(),getY());
		field=new Rectangle2D.Double(36,getBattleFieldHeight()-36,getBattleFieldWidth()-72,getBattleFieldHeight()-72);
		target=new Enemy();
		center=new Point2D.Double(getBattleFieldWidth()/2,getBattleFieldHeight()/2);
		timeSinceLastScan=0;
		
		setTurnRadarRightRadians(Double.POSITIVE_INFINITY);
		
		setAdjustGunForRobotTurn(true);
		setAdjustRadarForRobotTurn(true);
		return true;
	}

	public boolean doMovement(){
		if(nextDestination.distanceSq(myPos)<1000 || target.extrapolate(getTime()).location.distance(myPos)<90){
			boolean changed=false;
			for(int i=0;i<100;i++){
				double ang=(2*Math.PI)*Math.random();
				double dist=Math.min(target.extrapolate(getTime()).location.distance(myPos)*0.8,100+200*Math.random());
				Point2D.Double testPoint=projectPoint(myPos,ang,dist);
				if(field.contains(testPoint) && evaluate(testPoint)<evaluate(nextDestination)){
					nextDestination=testPoint;
					changed=true;
				}
				if(timeSinceLastScan>20 && field.contains(testPoint)){
					nextDestination=testPoint;
					break;
				}				
			}			
			if(changed){
				lastPosition=myPos;
			}
		}else{
			double dir=1;
			double ang=calcAngle(myPos,nextDestination)-getHeadingRadians();
			double dist=nextDestination.distance(myPos);
			if(Math.cos(ang)<0){
				dir=-1;
				ang+=Math.PI;
			}
			ang=Utils.normalRelativeAngle(ang);
			setTurnRightRadians(ang);
			setAhead(dist*dir);		
			setMaxVelocity((Math.abs(ang)>1) ? 0.1 : 8);			
		}
		return true;
	}

	public boolean doGun(){
		if(target.location!=null){
			double absBearing=calcAngle(myPos,target.location);
			double bulletPower=Math.min(Math.min(target.energy/4,1200/target.distance),myEnergy/10)/Math.max(getTime()-target.ctime,0);
			if(Math.abs(getGunTurnRemainingRadians())<0.01){
				setTurnGunRightRadians(Utils.normalRelativeAngle(absBearing-myGunHeading));
			}
			if(myGunHeat==0){
				setFire(bulletPower);
			}
		}
		return true;
	}

	public double evaluate(Point2D.Double point){
		long time=getTime();
		double risk=0;
		Enumeration e=enemies.elements();
		while(e.hasMoreElements()){
			Enemy en=(Enemy)e.nextElement();
			double eval=(en.energy+25)/en.extrapolate(time).location.distanceSq(myPos);
			
			int enTargets=0;
			Enumeration enEn=enemies.elements();
			while(enEn.hasMoreElements()){
				Enemy enE=(Enemy)enEn.nextElement();
				if((!enE.name.equals(en.name)) && enE.live && enE.extrapolate(time).location.distanceSq(en.extrapolate(time).location)*0.9<point.distanceSq(en.extrapolate(time).location)){
					enTargets++;
				}
			}
			if(enTargets<=1){
				eval*=2;
				eval*=1+Math.abs(Math.cos(calcAngle(point,myPos)-calcAngle(point,en.extrapolate(time).location)));
			}
			if(new Line2D.Double(myPos,point).intersects(new Rectangle2D.Double(en.extrapolate(time).location.getX()-18,en.extrapolate(time).location.getY()-18,36,36))){
				eval*=2;
			}
			risk+=eval;
		}
		risk+=1/lastPosition.distanceSq(point) + 0.8/myPos.distanceSq(point) + 0.5/center.distanceSq(point);
		return risk;
	}					

	public double calcAngle(Point2D.Double source,Point2D.Double target){
		return Math.atan2(target.getX()-source.getX(),target.getY()-source.getY());
	}

	public Point2D.Double projectPoint(Point2D.Double sourceLocation, double angle, double length) {
        return new Point2D.Double(sourceLocation.getX() + Math.sin(angle) * length,
            sourceLocation.getY() + Math.cos(angle) * length);
    }
}	
I need help on this as well! --Starrynte

The problem I see is that Lightning sometimes divides by zero when computing bullet power, giving an unreal answer. When it shoots the same tick as it scanned its target, getTime() - target.ctime is 0. -- Kev


Robo Home | Starrynte | Changes | Preferences | AllPages
Edit text of this page | View other revisions
Last edited January 14, 2007 0:12 EST by Starrynte (diff)
Search: