Difference between revisions of "Talk:DemonicRage"

From Robowiki
Jump to navigation Jump to search
Line 25: Line 25:
 
== Source Code ==
 
== Source Code ==
 
::: I left it as is, with code commented out in case someOne wants to play with it..
 
::: I left it as is, with code commented out in case someOne wants to play with it..
 +
::: I have updated the Radar code to be more Inclusive and Robust -[[User:Jlm0924|Jlm0924]] 18:33, 28 April 2010 (UTC)
 
   
 
   
  
 
<pre>
 
<pre>
/* author: Justin
 
 
 
*/
 
 
package justin.radar;
 
package justin.radar;
  
 
+
import justin.Module;
 
+
import justin.Radar;
 +
import justin.Enemy;
 +
import robocode.DeathEvent;
 
import robocode.Event;
 
import robocode.Event;
 +
import robocode.HitRobotEvent;
 
import robocode.ScannedRobotEvent;
 
import robocode.ScannedRobotEvent;
 
import robocode.RobotDeathEvent;
 
import robocode.RobotDeathEvent;
 +
import robocode.WinEvent;
 
import robocode.util.Utils;
 
import robocode.util.Utils;
import justin.Module;
+
import java.util.Hashtable;
import justin.Radar;
 
import justin.Enemy;
 
 
import java.util.Iterator;
 
import java.util.Iterator;
//import java.awt.geom.Point2D;
 
//import java.awt.Graphics2D;
 
  
 +
/**
 +
* - An Efficient and Robust RADAR system that should easily drop into Module by jab.
 +
 +
* @author Justin Mallais
 +
 +
*/
  
 
public class DynamicLocking extends Radar {
 
public class DynamicLocking extends Radar {
Line 56: Line 60:
 
static final double PI = Math.PI;
 
static final double PI = Math.PI;
 
static double radarDirection = 1;
 
static double radarDirection = 1;
static Enemy lookingFor = new Enemy();;
 
 
 
 
 
public void scan(){
+
static Enemy lookingFor = new Enemy();
 +
// List of enemy names that empties every new round  (the boolean is not used)
 +
private Hashtable<String, Boolean> knownEnemiesList = new Hashtable<String, Boolean>();
 +
public boolean knownEnemiesListFull = false;
 +
 +
 +
public void scan(){
 
 
if(bot.getRadarTurnRemaining()==0 ){
+
// Only executed once at beginning of new round.
 +
if(bot.getRadarTurnRemaining()==0 ){
 +
// initial radar direction is towards the center of Battle field.
 +
radarDirection =(Utils.normalRelativeAngle(absbearing(bot.getX(),bot.getY(),bot.getBattleFieldWidth()/2,bot.getBattleFieldHeight()/2) - bot.getRadarHeadingRadians())
 +
> 0 ? 1 : -1);
 
double radarTurn = Double.POSITIVE_INFINITY * radarDirection;
 
double radarTurn = Double.POSITIVE_INFINITY * radarDirection;
 
bot.setTurnRadarRightRadians(radarTurn);// the scan
 
bot.setTurnRadarRightRadians(radarTurn);// the scan
 
 
}
 
}
 
}
 
}
Line 71: Line 83:
 
 
 
public void listen(Event e){
 
public void listen(Event e){
if (e instanceof RobotDeathEvent && (( RobotDeathEvent)e).getName()== lookingFor.name){
+
if(bot.enemy!=null) lookingFor.name=bot.enemy.name;
+
// These aren't necessary but HitRobot event could help
}
+
if (e instanceof WinEvent) cleanUpRound();
 +
if (e instanceof DeathEvent) cleanUpRound();
 +
if (e instanceof HitRobotEvent) lookingFor = Module.enemies.get(((HitRobotEvent) e).getName());
 +
 +
// If who we are lookingFor has died
 +
if (e instanceof RobotDeathEvent && (( RobotDeathEvent)e).getName()== lookingFor.name){
 +
lookingFor.name = null;
 +
}
 +
 +
// RADAR SCANNED ROBOT EVENT
 
if (e instanceof ScannedRobotEvent){
 
if (e instanceof ScannedRobotEvent){
if(Module.enemies.size() < bot.getOthers()) return; // not perfect
+
// Check we've found all the enemies
 +
if(! knownEnemiesListFull){
 +
// Insure Enemy is marked alive;
 +
Module.enemies.get(((ScannedRobotEvent) e).getName()).alive = true;
 +
knownEnemiesList.put(((ScannedRobotEvent) e).getName(), true);
 +
knownEnemiesListFull = (knownEnemiesList.size() >= bot.getOthers())? true : false;
 +
bot.out.println(" found "+knownEnemiesList.size()+" bots, and found all is "+knownEnemiesListFull);
 +
if( !knownEnemiesListFull ) return;  
 +
}
 +
 +
// We've found all the robots, now we can choose who to lookFor next
 
if(lookingFor.name == null)lookingFor.name = ((ScannedRobotEvent) e).getName();
 
if(lookingFor.name == null)lookingFor.name = ((ScannedRobotEvent) e).getName();
if( ((ScannedRobotEvent) e).getName()==lookingFor.name) {
+
if( ((ScannedRobotEvent) e).getName() == lookingFor.name) {
 
Iterator<Enemy> iterator= Module.enemies.values().iterator();
 
Iterator<Enemy> iterator= Module.enemies.values().iterator();
 
double bestScore=Double.POSITIVE_INFINITY;
 
double bestScore=Double.POSITIVE_INFINITY;
 
 
while (iterator.hasNext()){
 
while (iterator.hasNext()){
 
Enemy tank= iterator.next();
 
Enemy tank= iterator.next();
if(tank.alive){ // choose next tank to scan
+
if(tank.alive){  
 
double time = tank.scanTime;
 
double time = tank.scanTime;
 
double sweepSize = (Math.abs(Utils.normalRelativeAngle(tank.absBearingRadians - bot.getRadarHeadingRadians())) /PI); //1 needs the scan
 
double sweepSize = (Math.abs(Utils.normalRelativeAngle(tank.absBearingRadians - bot.getRadarHeadingRadians())) /PI); //1 needs the scan
int distance = (int)Math.round((Math.min(1000,tank.distance)/1000*3)); // 1  needs the scan
+
// NOTE: The commented out options below are for reference. (may be broken)
distance = ( distance ==3 && bot.getOthers()>4 ) ? 10 : 0; // farthest not a concern
+
// prioritise based on distance
// int priority = 0;
+
/* int distance = (int)Math.round((Math.min(1000,tank.distance)/1000*3)); // 1  needs the scan
// if( (tank.name==bot.enemy.name || tank.name == bot.myClosestBot.name || bot.myLocation.distance(tank.location)<tank.cbD || bot.getOthers()<4)){
+
distance = ( distance ==3 && bot.getOthers()>4 ) ? 10 : 0; // farthest bots not a concern
// priority = -5;
+
int priority = 0;
// }
+
if( (tank.name==bot.enemy.name || tank.name == bot.myClosestBot.name || bot.myLocation.distance(tank.location)<tank.cbD || bot.getOthers()<4)){
+
priority = -5;
double score = time - sweepSize;// + distance + priority;
+
}
 +
 +
*/ double score = time - sweepSize;// + distance + priority;
 
// scan target before he fires
 
// scan target before he fires
 
/* double ang = lookingFor.absBearing + (lookingFor.deltaAbsBearing);
 
/* double ang = lookingFor.absBearing + (lookingFor.deltaAbsBearing);
Line 99: Line 131:
 
double sS = bot.getTime()-lookingFor.timeScanned;
 
double sS = bot.getTime()-lookingFor.timeScanned;
 
if(enemy.name == lookingFor.name && (bot.getGunHeat()/bot.getGunCoolingRate())-turnsB4ScanBot < 2 && sS > 1)score=score-25;
 
if(enemy.name == lookingFor.name && (bot.getGunHeat()/bot.getGunCoolingRate())-turnsB4ScanBot < 2 && sS > 1)score=score-25;
*/
+
*/
// scan Target before we fire at him
+
// scan Target before we fire at him
/* if (tank.name==bot.enemy.name  &&  ticksUntilGunCool() < bot.enemy.timeSinceLastScan +2 ) {  
+
/* if (tank.name==bot.enemy.name  &&  ticksUntilGunCool() < bot.enemy.timeSinceLastScan +2 ) {  
 
score = score - 10; // score is based on time
 
score = score - 10; // score is based on time
 
}
 
}
*/
+
*/
 
if(score < bestScore){
 
if(score < bestScore){
 
bestScore = score;
 
bestScore = score;
 
lookingFor = tank;
 
lookingFor = tank;
 
 
}
 
}
 
}
 
}
 
}
 
}
  
+
// New scan
 
// the scan
 
 
 
double angle = lookingFor.absBearingRadians-(lookingFor.deltaAbsBearingRadians*2); // + lookingFor.deltaBearing;// should be much more accurate to use below
 
double angle = lookingFor.absBearingRadians-(lookingFor.deltaAbsBearingRadians*2); // + lookingFor.deltaBearing;// should be much more accurate to use below
 
radarDirection =(int) Math.signum(Utils.normalRelativeAngle(angle - bot.getRadarHeadingRadians()));
 
radarDirection =(int) Math.signum(Utils.normalRelativeAngle(angle - bot.getRadarHeadingRadians()));
 
    double turnsTillScanBot = Utils.normalRelativeAngle(Math.abs( (bot.getRadarHeadingRadians()-angle) ))/.7;
 
    double turnsTillScanBot = Utils.normalRelativeAngle(Math.abs( (bot.getRadarHeadingRadians()-angle) ))/.7;
 
double radarTurn = Double.POSITIVE_INFINITY * radarDirection;
 
double radarTurn = Double.POSITIVE_INFINITY * radarDirection;
// int timeSinceScanned = (int) bot.getTime()-lookingFor.timeScanned;
 
 
 
// radar Lock
+
// When to enable Radar Lock  
 
if(lookingFor.deltaScanTime < 1.1 && turnsTillScanBot < 1){  
 
if(lookingFor.deltaScanTime < 1.1 && turnsTillScanBot < 1){  
//System.out.println(lookingFor.deltaBearing+"  ss  "+lookingFor.timeSinceLastScan+"  d  " +lookingFor.distance);
+
// A small Offset is needed.  
double offset =0;// = radarsMaxEscapeAngle(lookingFor.distance,sinceScanned) * radarDirection;  //  a small offset based on escape angle
+
//A few different types are here for bling bling :)  
 +
double offset =0; // = radarsMaxEscapeAngle(lookingFor.distance,sinceScanned) * radarDirection;  //  a small offset based on escape angle
 
offset = offset + ( Math.abs(lookingFor.deltaAbsBearingRadians * 3 )  ); // greater offset for lateral speed
 
offset = offset + ( Math.abs(lookingFor.deltaAbsBearingRadians * 3 )  ); // greater offset for lateral speed
 
offset = offset +  (20* (lookingFor.deltaScanTime))  / (lookingFor.distance); // greater offset for smaller distance
 
offset = offset +  (20* (lookingFor.deltaScanTime))  / (lookingFor.distance); // greater offset for smaller distance
Line 133: Line 161:
 
radarTurn =(Utils.normalRelativeAngle(angle - bot.getRadarHeadingRadians()+offset));
 
radarTurn =(Utils.normalRelativeAngle(angle - bot.getRadarHeadingRadians()+offset));
 
}
 
}
+
bot.setTurnRadarRightRadians(radarTurn);// set scan
bot.setTurnRadarRightRadians(radarTurn);// the scan
 
 
 
}
 
}
 
}
 
}
 
}
 
}
/*
+
 +
// Fail Safe
 +
public void cleanUpRound() {
 +
knownEnemiesList = null; // fail safe
 +
knownEnemiesListFull = false; // fail safe
 +
Iterator<Enemy> iterator= Module.enemies.values().iterator();
 +
while (iterator.hasNext()){
 +
Enemy him= iterator.next();
 +
if(him.alive){
 +
// clean Ups'
 +
}
 +
else him.alive = true; // fail safe
 +
}
 +
}
 +
 +
 +
/* // PAINT LookingFor
 
public void onPaint(Graphics2D g){
 
public void onPaint(Graphics2D g){
 
if(lookingFor!=null&&lookingFor.location !=null){
 
if(lookingFor!=null&&lookingFor.location !=null){
Line 148: Line 190:
 
}
 
}
 
*/
 
*/
// utils
+
// Utils
 +
 +
//gets the absolute bearing between to x,y coordinates (not sure of Author)
 +
public double absbearing( double x1,double y1, double x2,double y2 ){
 +
double xo = x2-x1;
 +
double yo = y2-y1;
 +
double h = getRange( x1,y1, x2,y2 );
 +
if( xo > 0 && yo > 0 ){ return Math.asin( xo / h ); }
 +
if( xo > 0 && yo < 0 ){ return Math.PI - Math.asin( xo / h );}
 +
if( xo < 0 && yo < 0 ){ return Math.PI + Math.asin( -xo / h );}
 +
if( xo < 0 && yo > 0 ){ return 2.0*Math.PI - Math.asin( -xo / h );}
 +
return 0;
 +
}
 +
public double getRange( double x1,double y1, double x2,double y2 ){
 +
double xo = x2-x1;
 +
double yo = y2-y1;
 +
double h = Math.sqrt( xo*xo + yo*yo );
 +
return h;
 +
}
 
/*
 
/*
 
protected long ticksUntilGunCool() {
 
protected long ticksUntilGunCool() {
 
        return Math.round(Math.ceil(bot.getGunHeat() / bot.getGunCoolingRate()));
 
        return Math.round(Math.ceil(bot.getGunHeat() / bot.getGunCoolingRate()));
 
}
 
}
 
 
 
 
 
 
 
public static double radarsMaxEscapeAngle(double distance, double sinceScanned) {
 
public static double radarsMaxEscapeAngle(double distance, double sinceScanned) {

Revision as of 19:33, 28 April 2010

DemonicRagev3.05

despite finding a small bug in DR3.03 1vr1 movement, It's still performing sub par. I will need some time to improve DR's 1vr1 waveSurfing ( i've never spent much time there before.) Till then; I slapped the old random 1vrs1 movement back in to see what happens in the rumble. —Preceding unsigned comment added by Jlm0924 (talkcontribs)
Well, personally, I'd put one HawkOnFire vs DR3 in 1v1, and attempt to fix the remaining times DR gets hit since HOF is just a "Head-On" targeter. In some tests I saw it dodge well enough that it's clearly surfing, however got hit often enough to indicate the surfing is flawed in some manner or another. --Rednaxela 23:52, 25 April 2010 (UTC)

yeah the bug in 1vrs1 : DR3.03 was accidently not just surfing the closest wave.. (It might have choosen a high risk part of the closest wave if that position was low risk on the waves behind it.) Without that flaw (unsegemented) works great for the first 10 rounds or so. Then the big guns start gaining ground back.. I tried simple segmenting, but it learns too slow to compete with the better Guns. I know nothing about the more advanced wavesurfers.( Whats going on in Druss/Diamond or Glacier?) ..but I'm going to avoid the segment setup, and try surfing with DC. `Jlm0924 06:42, 26 April 2010 (UTC)

Well, Glacier isn't a surfer (in fact, it's 1v1 movement is terrible, just see it's non-melee ranking). Well, how to set up learning for surfing is basically the same as building a gun. I'm sure DC will work better than a single segmentation, though some like Druss have success with overlaying multiple segmentations. One note is usually one segments surfing less heavily due to the reduced amount of data. The other note, is that the particularly good guns start gaining back ground, even with segmented/DC surfing really, and what is usually done to counter this is enable a "flattener" when the enemy hit rate is high enough. The "flattener" basically keeps stats of where you've been, instead of where you've been hit, and you dodge that as well. This works well because it avoids going to the same place twice even if you haven't been hit there yet. Note though, a flattener isn't really necessary. Midboss and RougeDC in 1v1, both lack a "flattener" yet still score high (though not so high against the strong bots due to the lack of such). One thought, is because melee gives much less time to learn than 1v1, perhaps it would make sense switch to pure-flattener against the final remaining bot? I say such because I think chances are the final remaining bot is strong enough that flattener could be best. --Rednaxela 13:33, 26 April 2010 (UTC)

From Portia's stats that was posted sometimes ago (I can't remember where), there is only a few bullets that actually fell into your escape angle and actually hit (the one you can save stats), so your should combine it with your old MR movement to be competitive. My two cents anyway. --Nat Pavasant 14:00, 26 April 2010 (UTC)

Thx for your wisdom Rednexala. DR has a flattener. But it worked better always off, then alway on :) so I will try enabling it as you suggest. When I get Home, I will release DRv3.06 with (NO-SEG, NO1vr1 bugg, and properly activated flattener) into the (Non-Melee) Rumble for the first time..and go from there. :)-Jlm0924 00:35, 27 April 2010 (UTC)

DemonicRagev3.06

VR3.06 released.. ( still no segment, removed small 1vr1 bug and found bigger melee stats bug, played with the flattener (the stats to enable it were swayed by melee/ so I disabled for now) I also removed 2 gun distancing functions (distance and angle) and enabled painting waves. I've come to realise there is alot I can improve still. Currently Dr is selective on which waves it 'sees'. TODO list : allow DR to see more waves and weight them. Precise escape angle. -Jlm0924 00:35, 27 April 2010 (UTC)

DemonicRagev3.0

Lately I have completely rebuilt and improved Demonics foundation (still based on Module) I implemented Rednaxela's tree into a bare bones version of D's gun, which I plan to later expand after the new movement is fleshed out. The gun's new PIF I made should be quite quick. I'm not sure how it compares to displacement vectors or if it's type has been done before, but I will post it and D's Radar source code next chance I have.
I released DR3.0 early. I just got the melee movement working and the gun is untuned. 1vrs1 is temperarily random. I should of disabled some painting and tested for skipping turns, but it seems fine. -Jlm0924 17:11, 20 April 2010 (UTC)


Source Code

I left it as is, with code commented out in case someOne wants to play with it..
I have updated the Radar code to be more Inclusive and Robust -Jlm0924 18:33, 28 April 2010 (UTC)


package justin.radar;

import justin.Module;
import justin.Radar;
import justin.Enemy;
import robocode.DeathEvent;
import robocode.Event;
import robocode.HitRobotEvent;
import robocode.ScannedRobotEvent;
import robocode.RobotDeathEvent;
import robocode.WinEvent;
import robocode.util.Utils;
import java.util.Hashtable;
import java.util.Iterator;

/**
 * - An Efficient and Robust RADAR system that should easily drop into Module by jab. 
 *   
 * @author Justin Mallais
 *  
 */

public class DynamicLocking extends Radar {
	
	public DynamicLocking(Module bot) {
		super(bot);
	}
	
	
	static final double PI = Math.PI;
	static double radarDirection = 1;
	
	
	static Enemy lookingFor = new Enemy();
	// List of enemy names that empties every new round   (the boolean is not used)
	private Hashtable<String, Boolean> knownEnemiesList = new Hashtable<String, Boolean>();
	public boolean knownEnemiesListFull = false; 
	
	
	public void scan(){
		
		// Only executed once at beginning of new round.
		if(bot.getRadarTurnRemaining()==0 ){
			// initial radar direction is towards the center of Battle field.
			radarDirection =(Utils.normalRelativeAngle(absbearing(bot.getX(),bot.getY(),bot.getBattleFieldWidth()/2,bot.getBattleFieldHeight()/2) - bot.getRadarHeadingRadians())
					> 0 ? 1 : -1);
			double radarTurn = Double.POSITIVE_INFINITY * radarDirection;
			bot.setTurnRadarRightRadians(radarTurn);// the scan
		}
	}
	
	
	
	public void listen(Event e){
		
		// These aren't necessary but HitRobot event could help
		if (e instanceof WinEvent) cleanUpRound(); 
		if (e instanceof DeathEvent) cleanUpRound();
		if (e instanceof HitRobotEvent) lookingFor = Module.enemies.get(((HitRobotEvent) e).getName());
		
		// If who we are lookingFor has died 	
		if (e instanceof RobotDeathEvent && (( RobotDeathEvent)e).getName()== lookingFor.name){
			lookingFor.name = null;
		}
		
		// RADAR SCANNED ROBOT EVENT
		if (e instanceof ScannedRobotEvent){
			// Check we've found all the enemies
			if(! knownEnemiesListFull){ 
				// Insure Enemy is marked alive;
				Module.enemies.get(((ScannedRobotEvent) e).getName()).alive = true;
				knownEnemiesList.put(((ScannedRobotEvent) e).getName(), true);
				knownEnemiesListFull = (knownEnemiesList.size() >= bot.getOthers())? true : false;
				bot.out.println(" found "+knownEnemiesList.size()+" bots, and found all is "+knownEnemiesListFull);
				if( !knownEnemiesListFull ) return; 
			}
			
			// We've found all the robots, now we can choose who to lookFor next	
			if(lookingFor.name == null)lookingFor.name = ((ScannedRobotEvent) e).getName();
			if( ((ScannedRobotEvent) e).getName() == lookingFor.name) {
				Iterator<Enemy> iterator= Module.enemies.values().iterator();
				double bestScore=Double.POSITIVE_INFINITY;
				while (iterator.hasNext()){
					Enemy tank= iterator.next();
					if(tank.alive){	 
						double time = tank.scanTime;
						double sweepSize = (Math.abs(Utils.normalRelativeAngle(tank.absBearingRadians - bot.getRadarHeadingRadians())) /PI); //1 needs the scan
						// NOTE: The commented out options below are for reference. (may be broken)
						// prioritise based on distance
/*						int distance = (int)Math.round((Math.min(1000,tank.distance)/1000*3)); // 1  needs the scan
						distance = ( distance ==3 && bot.getOthers()>4 ) ? 10 : 0; 	// farthest bots not a concern
						int priority = 0;
						if( (tank.name==bot.enemy.name || tank.name == bot.myClosestBot.name || bot.myLocation.distance(tank.location)<tank.cbD || bot.getOthers()<4)){
							priority = -5;
						}
						
*/						double score = time - sweepSize;// + distance + priority;
						// scan target before he fires
/*						double ang = lookingFor.absBearing + (lookingFor.deltaAbsBearing);
						double turnsB4ScanBot = Utils.normalRelativeAngle(Math.abs( (bot.getRadarHeadingRadians()-ang) ))/.785;
						double sS = bot.getTime()-lookingFor.timeScanned;
						if(enemy.name == lookingFor.name && (bot.getGunHeat()/bot.getGunCoolingRate())-turnsB4ScanBot < 2 && sS > 1)score=score-25;
*/						
						// scan Target before we fire at him
/*						if (tank.name==bot.enemy.name  &&  ticksUntilGunCool() < bot.enemy.timeSinceLastScan +2 ) { 
							score = score - 10; // score is based on time
						}
*/			
						if(score < bestScore){
							bestScore = score;
							lookingFor = tank;
						}	
					}
				}

				// New scan
				double angle = lookingFor.absBearingRadians-(lookingFor.deltaAbsBearingRadians*2); // + lookingFor.deltaBearing;// should be much more accurate to use below
				radarDirection =(int) Math.signum(Utils.normalRelativeAngle(angle - bot.getRadarHeadingRadians()));
			    double turnsTillScanBot = Utils.normalRelativeAngle(Math.abs( (bot.getRadarHeadingRadians()-angle) ))/.7;	
				double radarTurn = Double.POSITIVE_INFINITY * radarDirection;
				
				// When to enable Radar Lock 
				if(lookingFor.deltaScanTime < 1.1 && turnsTillScanBot < 1){ 
					// A small Offset is needed. 
					//A few different types are here for bling bling :) 
					double offset =0; // = radarsMaxEscapeAngle(lookingFor.distance,sinceScanned) * radarDirection;   //  a small offset based on escape angle
					offset = offset + ( Math.abs(lookingFor.deltaAbsBearingRadians * 3 )   ); // greater offset for lateral speed
					offset = offset +  (20* (lookingFor.deltaScanTime))  / (lookingFor.distance); // greater offset for smaller distance
					offset = offset * radarDirection;	
					
					radarTurn =(Utils.normalRelativeAngle(angle - bot.getRadarHeadingRadians()+offset));
				}
				bot.setTurnRadarRightRadians(radarTurn);// set scan
			}
		}
	}
	
	// Fail Safe
	public void cleanUpRound() {
		knownEnemiesList = null; // fail safe
		knownEnemiesListFull = false; // fail safe
		Iterator<Enemy> iterator= Module.enemies.values().iterator();
		while (iterator.hasNext()){
				Enemy him= iterator.next();
				if(him.alive){
					// clean Ups' 
				}
				else him.alive = true; // fail safe
		}
	}
	
	
/*	// PAINT LookingFor	
	public void onPaint(Graphics2D g){
		if(lookingFor!=null&&lookingFor.location !=null){
		g.setColor(new Color(0, 0, 255, 70));	
		g.fillRect((int)lookingFor.location.x-25,(int)lookingFor.location.y-25,50,50);
		}
		
	}
*/	
	// Utils
	
	//gets the absolute bearing between to x,y coordinates (not sure of Author)
	public double absbearing( double x1,double y1, double x2,double y2 ){
		double xo = x2-x1;
		double yo = y2-y1;
		double h = getRange( x1,y1, x2,y2 );
		if( xo > 0 && yo > 0 ){ return Math.asin( xo / h );	}
		if( xo > 0 && yo < 0 ){	return Math.PI - Math.asin( xo / h );}
		if( xo < 0 && yo < 0 ){	return Math.PI + Math.asin( -xo / h );}
		if( xo < 0 && yo > 0 ){	return 2.0*Math.PI - Math.asin( -xo / h );}
		return 0;
	}
	public double getRange( double x1,double y1, double x2,double y2 ){
		double xo = x2-x1;
		double yo = y2-y1;
		double h = Math.sqrt( xo*xo + yo*yo );
		return h;	
	}
/*	
	protected long ticksUntilGunCool() {
	        return Math.round(Math.ceil(bot.getGunHeat() / bot.getGunCoolingRate()));
	}
	
	public static double radarsMaxEscapeAngle(double distance, double sinceScanned) {
        return Math.asin( 8/    (distance-(8*sinceScanned))) * sinceScanned ;// 
    }

*/
    
    
    

}			

///// DataLog is a linked list of scan info(I should rename it to HistoryLog). //Enemy is additional scan info (current)
//Play It Forward by Justin  , (Using Rednexnala's FastTrig)	
	
	public Angle getGunAngle(DataLog similar, Enemy e ,double bulletSpeed, long time, double weight){// GunData predictedInfo, Enemy e) {
		
		final DataLog  predictedInfo =  similar;
		final DataLog currInfo = e.last;
		DataLog endInfo = predictedInfo;
		double bulletTime;
		long timeDelta = (time  - currInfo.scanTime);
		double  predDist = 0, predAng;
		Point2D.Double myRelativePosition = project(predictedInfo.location, Utils.normalRelativeAngle(currInfo.absBearingRadians + FastTrig.PI-currInfo.headingRadians+predictedInfo.headingRadians), currInfo.distance);
			while (endInfo.next != null && endInfo.round == predictedInfo.round && endInfo.scanTime >= predictedInfo.scanTime ) {
				
				endInfo = endInfo.next; 
				bulletTime = (myRelativePosition.distance(endInfo.location) / bulletSpeed) +1;
			    if (Math.abs(endInfo.scanTime - predictedInfo.scanTime - timeDelta - bulletTime) <= 1) break;
			}
			if ( endInfo.next == null | endInfo.round != predictedInfo.round )return null; 
			
			predAng = Utils.normalRelativeAngle(DRUtils.absoluteBearing(predictedInfo.location, endInfo.location)
					- predictedInfo.headingRadians );
			predDist = predictedInfo.location.distance(endInfo.location);
			Point2D.Double predLocation = project(currInfo.location,Utils.normalRelativeAngle(predAng+currInfo.headingRadians),predDist);
			if(!Module.bf.contains(predLocation)) return null;
			
			predAng = DRUtils.absoluteBearing(bot.myData.location, predLocation);
			predDist = bot.myData.location.distance( predLocation);
			
			Angle angle = new Angle( predAng, FastTrig.atan(18 / predDist), 0, weight );
		// returns:  predicted angle,  tolerence,  
		return angle;
	}
	


Comments

Very nice! Seems you've won the race to melee surfing? (EDIT: To melee surfing that collects stats I meant. Since apparently Shadow does do non-learning wave surfing in melee, and while I believe Portia learns a little about enemy targeting it's not technically a wave surfer) I'm a little surprised by DemonicRage still performing behind Glacier though. Perhaps do some 1v1 tests of the surfing to see how well it's working in a more basic situation? --Rednaxela 15:16, 23 April 2010 (UTC)

Thanks, your right... I haven't really tested the 1vrs1. The only difference between the melee and 1vrs1 is seperate Stats, which are both non-Segmented. I haven't tried segmenting yet, but I'm sure the 1vrs1 needs it. -Jlm0924 17:35, 23 April 2010 (UTC)