Help:Help
Help!, in both meanings of the term
This is a page for help, please edit the page and add the link to your problem, and maybe one of the more experienced coders will have a solution. This is a potluck help page so, bring your problems, and be ready to share your expertise and knowledge with the less fortunate!
--Pkdeken 15:38, 29 April 2009 (UTC)
I suggest to create another page as subpages and make a link would be easier. » Nat | Talk » 16:01, 29 April 2009 (UTC)
How do I implement HTML colors? --KDH 13:41, 5 June 2010 (UTC)
I know it says post a link, but this is easier
package tutorials; import robocode.*; import robocode.util.Utils; import java.util.ArrayList; import java.awt.geom.Point2D; public class GFTTutorial extends AdvancedRobot { public final static int BINS = 47; public final static int MIDDLE_BIN = (BINS - 1) / 2; public final static double MAX_ESC_ANGLE = 0.8143399421265254D; public final static double BIN_WIDTH = MAX_ESC_ANGLE / MIDDLE_BIN; public static ArrayList aimFactors = new ArrayList(); public double prevVelocity = 0; public double t = 0; public Point2D.Double enemyLoc; public void run() { while (true) { turnRadarRightRadians(Double.POSITIVE_INFINITY); } } public void onScannedRobot(ScannedRobotEvent e) { double absBearing = getHeadingRadians() + e.getBearingRadians(); double firePower = 3D; BulletWave w = new BulletWave(); w.firedLocation = new Point2D.Double(getX(), getY()); enemyLoc = new Point2D.Double(getX() + Math.sin(absBearing) * e.getDistance(), getY() + Math.cos(absBearing) * e.getDistance()); w.bearingDir = (e.getVelocity() * Math.sin(e.getHeadingRadians() - absBearing) < 0 ? -BIN_WIDTH : BIN_WIDTH); w.bearing = absBearing; w.velocity = bulletVelocity(firePower); //originalDistance,wall,acceleration,myVelocity,time,timeSinceAccel; w.originalDistance = e.getDistance(); w.wallX = getX() + Math.sin(absBearing) * e.getDistance() > 400 ? 800 - getX() + Math.sin(absBearing) * e.getDistance() : getX() + Math.sin(absBearing) * e.getDistance() == 0 ? 0 : getX() + Math.sin(absBearing) * e.getDistance(); w.wallY = getY()+ Math.cos(absBearing) * e.getDistance() > 300 ? 600 - getY()+ Math.cos(absBearing) * e.getDistance() : getY()+ Math.cos(absBearing) * e.getDistance() == 0 ? 0 : getY()+ Math.cos(absBearing) * e.getDistance(); w.acceleration = e.getVelocity() - prevVelocity; w.time = getTime(); t = w.acceleration == 0 ? t++ : 0; w.timeSinceAccel = t; prevVelocity = e.getVelocity(); int XX = 100; int[] TopXX = new int[XX]; double[] TopDiff = new double[XX]; for (int i=0;i<aimFactors.size();i++){ double diff = findDifference(w,(AimFactor)aimFactors.get(i)); for (int r=XX - 1;r>=0;r--) { if (diff < TopDiff[r]){ TopXX[r] = ((AimFactor)aimFactors.get(i)).angle; TopDiff[r] = diff; break; } } } double[] stats = new double[BINS]; for (int i = 0; i < XX; i++) { stats[TopXX[i]]++; } int mostVisited = MIDDLE_BIN; for (int i = 0; i < BINS; i++) { if (stats[i] > stats[mostVisited]) mostVisited = i; } setTurnGunRightRadians(Utils.normalRelativeAngle(absBearing - getGunHeadingRadians() + w.bearingDir * (mostVisited - MIDDLE_BIN))); if (setFireBullet(firePower) != null) addCustomEvent(w); setTurnRadarRightRadians(Utils.normalRelativeAngle(absBearing - getRadarHeadingRadians()) * 2); } double findDifference(BulletWave w, AimFactor a) { double diff = 0; diff += Math.sqrt(Math.pow((1-(w.originalDistance/a.distanceIndex)),2)); diff += Math.sqrt(Math.pow((1-(w.wallX/a.wallIndexX)),2)); diff += Math.sqrt(Math.pow((1-(w.wallY/a.wallIndexY)),2)); diff += Math.sqrt(Math.pow((1-(w.acceleration/a.accelerationIndex)),2)); diff += Math.sqrt(Math.pow((1-(w.myVelocity/a.velocityIndex)),2)); diff += Math.sqrt(Math.pow((1-(w.time/a.time)),2)); diff += Math.sqrt(Math.pow((1-(w.timeSinceAccel/a.timeSinceAccel)),2)); return diff; } double absoluteBearing(Point2D.Double p, Point2D.Double q) { return Math.atan2(q.x - p.x, q.y - p.y); } double bulletVelocity(double power) { return 20 - 3 * power; } public class BulletWave extends Condition { Point2D.Double firedLocation; double velocity, distanceTraveled, bearing, bearingDir; double originalDistance,wallX,wallY,acceleration,myVelocity,time,timeSinceAccel; public boolean test() { distanceTraveled += velocity; double distance = firedLocation.distance(enemyLoc); if (distanceTraveled > distance - 18) { try { aimFactors.add(new AimFactor(originalDistance,wallX,wallY,acceleration,myVelocity,time,timeSinceAccel,(int) ((Utils.normalRelativeAngle(absoluteBearing(firedLocation, enemyLoc)) - bearing) / bearingDir) + MIDDLE_BIN)); } catch (Exception e) { } removeCustomEvent(this); } return false; } } public class AimFactor { double distanceIndex,wallIndexX,wallIndexY,accelerationIndex,velocityIndex,time,timeSinceAccel; int angle; public AimFactor(double ad,double awx,double awy,double aa,double av,double at,double ati,int aangle){ distanceIndex = ad; wallIndexX = awx; wallIndexY = awy; accelerationIndex = aa; velocityIndex = av; time = at; timeSinceAccel = ati; angle = aangle; } } }
If you run this you end up with it always firing at guessFactor -1, How can I fix this?
It is supposed to be running a patternMatchingStatitistical Targeting gun. Basically, it segments the data without using nested arrays
--Pkdeken 15:38, 29 April 2009 (UTC)
I'm testing. One thing that is wrong is the BIN_WIDTH calculation, it should be
public final static double BIN_WIDTH = MAX_ESC_ANGLE / (double)MIDDLE_BIN;
And the diff always be NaN (try printing it out). Another thing to mention is this is not patternMatchingStatitistical Targeting gun, but it is a Dynamic Clustering GuessFactor Targeting gun. I'll look into this later when I have time. » Nat | Talk » 16:01, 29 April 2009 (UTC)
Problem finding enemy position
I've tried to make a snippet to find the enemy position. For some reason the computer isn't calculating it right :/ after I couldn't figure it out I tried making the calculations by hand and it was exactly right - only one off which was probably due to me rounding when I calculated it. Any ideas why this won't work??? =S
int x, y;
double radHead = getRadarHeading();
double eDist = e.getDistance();
double quadrant = Math.ceil(radHead / 90);
switch((int)quadrant){
case 1:
x = 1;
y = 1;
break;
case 2:
x = 1;
y = -1;
break;
case 3:
x = -1;
y = -1;
break;
case 4:
x = -1;
y = 1;
break;
default:
x = 1;
y = 1;
break;
}
double angle = radHead - ((quadrant - 1) * 90);
double enx = (Math.cos((90 - angle))) * eDist * x;
double eny = (Math.sin((90 - angle))) * eDist * y;
double enemX = getX() + enx;
double enemY = getY() + eny;
I don't know :S I can't figure out why it wont work lol. Help plz :D Thanks --Exauge ◊ talk 22:18, 23 July 2010 (UTC)
Well, I see multiple issues to address...
- Math.cos and Math.sin take angles in radians, not degrees, so you need to use Math.toRadians on the angle before passing it. (I'd recommend just switching to radians entirely, but that's up to you.)
- You really don't need to special case the quadrants (though I readily confess my first attempts did the same). sin and cos inherently implement these multipliers if you just use sin(angle) and cos(angle).
- You should use sin for x and cos for y, at least if you're using sin/cos(angle) instead of (90 - (angle % 90)). Robocode's coordinate system is not the most common one used in mathematics, which might be a reason you'd see it differently elsewhere.
- Why use radar heading for the angle to the enemy? I would use e.getBearing() + robot.getHeading() (e.getBearing() is relative to your heading) to get the exact angle.
If you want to peek at code that implements this pretty minimally, take a look at Komarious/Code, particularly the "project" method. But it sounds like you want to do it yourself, so hopefully I've helped. =)
--Voidious 22:37, 23 July 2010 (UTC)
Thanks - you've helped me shrink my code a lot from those sloppy lines to this:
double absB = e.getBearing() + getHeading();
double eDist = e.getDistance();
double enx = Math.sin(absB) * eDist;
double eny = Math.cos(absB) * eDist;
enemX = getPosition().getX() + enx;
enemY = getPosition().getY() + eny;
I've figured out why it won't work though - the java trigonometric functions are different than they should be or something. For example in this test:http://img94.imageshack.us/img94/9633/faillf.png
The sin(108) should be about .927 and cos(108) should be about .376 however the java calculations are quite a bit off... They don't appear to be in degrees or radians :S --Exauge ◊ talk 01:46, 24 July 2010 (UTC)
They definitely expect an angle in radians. sin(108.18478489153478) is 0.980034448685092 on my calculator, cos is 0.19882776312806. In degrees, they would be about 0.95 and -0.31, respectively. Not sure where you're getting .927 and .376? Anyway, if you just wrap absB in a Math.toRadians() call before passing to sin/cos, you should get the behavior you expect. --Voidious 02:06, 24 July 2010 (UTC)
Thanks so much :) that did it. I'm gonna use that for the targeting for my first mega - I'll collect about 50 ticks of linear targeting predicted positions and average them and fire at it. Hopefully it'll work :)