Talk:DemonicRage

From Robowiki
Jump to navigation Jump to search
Recently I have build DemonicRage a new DCgun from the ground up that uses linked list and targets everyOne..(ver 2.5+) It performs very well untuned, but first I am addressing some speed issues ..(I get skipped turn event after 60,000 scan, but notice poor performance much sooner) I have not tested to confirm, but i believe the distancing calculation is the main bottle neck.. I'm going to try caching the distance calculations. I figure it should work well, the percise distance isn't even important. Do you guys do this when using kd-Trees?? perhaps within a tree? -Jlm0924
I'm not sure what you mean by caching, unless you start doing approximations which would really defeat the whole point of not just using bins like VCS. No distance calculations are cached with Kd-Trees. The point of the Kd-Tree is create groups of scans in a tree, as to be able to discard whole branches of the tree at once without needing to calculate the distance to every scan. --Rednaxela 06:20, 7 January 2010 (UTC)
Each time you aim, you are using a new/current scan, so I'm not sure what kind of caching you can do with that. I would definitely suggest trying out Red's kd-tree, as that should help a lot and probably isn't even that much work. Suboptimal play-it-forward simulation (if you do that) comes to mind, too, or just using too many scans when aiming. For reference: I fire extra gun waves from the locations of every other bot on the field, so I have like 5x as many total scans as you normally would, and I start to hit skipped turns near the end of a 35-round battle (with my own, slower kd-tree). --Voidious 14:51, 7 January 2010 (UTC)
My initial thought with caching was; I only needed to identify the best 300 scans or so.

My initial idea of code is below. Yeah, I'm sure Kd Trees are the best way to go... I still could try something like this to at least filter which scans needed to calculate. ( maybe see how it pans out) -Jlm0924

  
/*	
	public static class fastDistance{
		public static final int DIVISIONS = 80000;
		public static final double K = 1 / DIVISIONS; 		
                public static double[][] manhattanDistanceTable;
		
		public static final void init() {
			if (manhattanDistanceTable == null) {
				manhattanDistanceTable = new double[DIVISIONS][DIVISIONS];
				double d1;
				double d2;
				for (int i=0; i<DIVISIONS; i++) 
			 		for (int j=0; i<DIVISIONS; i++) {
						d1 = i*K;
						d2 = j*K;
						manhattanDistanceTable[i][j] = Math.abs(d1-d2);
					}
				}
			}
		}
		
			
		public static double manhattanDistance(Dist[] d) {
		        double sum = 0;
		        for (int x = 0; x < d.length; x++) {
		            sum += manhattanDistanceTable[(d.value1*80000)][d.value2*80000];
		        }
		        
		        return sum;
		 }

	}
	
	public  class Dist{
		double value1;
		double value2;
		double weight;
	}
	
	
	*/

Ahh, so precalculating some distances with a table, kind of like FastTrig. Well, I doubt it'll help much really, particularly for manhattan distance as you have there. Taking differences and summing them is such a quick operation that I think that unless the number of dimensions is huge, the function call overhead of this would make it's benefit minimal if not non-existent. It wouldn't hurt to benchmark it though, maybe I'm being too pessimistic. Since you already have the code here, might as well try it. One note is at least with the number of divisions you specify there, it would take a huge amount of memory really... 80000*80000*4bytesperdouble = 23.84GB --Rednaxela 19:30, 11 January 2010 (UTC)

Not to be a smartass here, but actually a double is 8 bytes. :P So that would actually be 47.68 GB. —Preceding unsigned comment added by Positive (talkcontribs)
Oh yeah... I got that mixed up... I thought "64 bits per double" in my head and have no clue how that turned to 4 bytes, haha :) --Rednaxela 21:36, 11 January 2010 (UTC)
smart ass :P I didn't bother much with it. A small gain wouldn't likely be enough to add back in some disabled code in the gun .. so I went ahead and released what I had. (v2.5d) It will skip 4-5 turns in 50 rounds. unlikely in 35. There is no scan size limiting so I wouldn't test it above the 50 rounds :P I'm hoping to give Glacier a scare with this one ;) -Jlm0924
Rather nice result there with version 2.5d... As I regain the spot of top Canadian bot in 1v1, it looks like the top Canadian melee bot maybe be under threat soon... I'm unlikely to update Glacier for a while though, because my next plans for it (Melee surfing that seamlessly works as good 1v1 surfing too) will likely take quite some time for me to fully flesh out and debug. --Rednaxela 16:21, 13 January 2010 (UTC)
Thx Red; v2.5 hasn't lived up to expectation though; It may be skipping turns. I suspect with some more battles it will likely drop below Aleph. On a good note Version 2.5, I think is prettier :) AnyOne dislike the new powerDown color change? Good luck Red owith the melee surfing. I think theres untapped potiental there. A while back I did try abit to combine melee surfing with minimum Risk.. DR's base movement liked to move around too much. Now I notice Portia also dodges linear Targeting. You may want to keep that in mind if you run into the same issue. I think it's time I try and make use of your kick-butt Tree. (You'll have time for Glacier !) :) I'm sure I'll have a few Q's along the way. I assumed a while back when I first peeked at it. Does the number of Dimensions in the tree corrispond to the number of items in the scan Object you are 'segmenting' on?
Congrats on MidBoss by the way, the bullet power selection is impressive :) -Jlm0924
Yes, the number of dimension is the number of things you use to calculate the distance. Thanks, and yeah, it looks like Midboss 1k might get to 10th place. Still a ways to go to catch up to DrussGT and Diamond though... --Rednaxela 02:58, 14 January 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 left it as is, with code commented out in case someOne wants to play with it..
Radar code:
/* author: Justin Mallais
  
*/
package justin.radar;



import robocode.Event;
import robocode.ScannedRobotEvent;
import robocode.RobotDeathEvent;
import robocode.util.Utils;
import justin.Module;
import justin.Radar;
import justin.Enemy;
import java.util.Iterator;
//import java.awt.geom.Point2D;
//import java.awt.Graphics2D;


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();;
	
	
	public void scan(){  
		
		if(bot.getRadarTurnRemaining()==0 ){	
			double radarTurn = Double.POSITIVE_INFINITY * radarDirection;
			bot.setTurnRadarRightRadians(radarTurn);// the scan
			
		}
	}
	
	
	
	public void listen(Event e){
	if (e instanceof RobotDeathEvent && (( RobotDeathEvent)e).getName()== lookingFor.name){
		if(bot.enemy!=null) lookingFor.name=bot.enemy.name;
	}
		if (e instanceof ScannedRobotEvent){
			if(Module.enemies.size() < bot.getOthers()) return; // not perfect
			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){	 // choose next tank to scan
						double time = tank.scanTime;
						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
						distance = ( distance ==3 && bot.getOthers()>4 ) ? 10 : 0; 	// farthest 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;
					
						}	
					}
				}

				
				
				// the 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;
				//	int timeSinceScanned = (int) bot.getTime()-lookingFor.timeScanned;
				
				// radar Lock
				if(lookingFor.deltaScanTime < 1.1 && turnsTillScanBot < 1){ 
					//System.out.println(lookingFor.deltaBearing+"  ss  "+lookingFor.timeSinceLastScan+"  d  " +lookingFor.distance);			
					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);// the scan
			
			}
		}
	}
/*		
	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
/*	
	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 ;// 
    }

*/
    
    
    

}			


//Play It Forward  ///// DataLog is a linked list of scan info(I should rename it to HistoryLog). //Enemy is additional scan info (current) 
	
	
	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;
	}