Talk:Maximum Escape Angle/Precise
Calculating
There was some discussion of this recently and I just read some more on User talk:Rednaxela/SaphireEdge, so I thought I'd post how it's done in Dookious and Diamond. Of course, trust your own findings on how valuable this is, but I have personally found precise MEA to be a good thing, both in TC and the rumble. All of these steps use Precise Prediction, just like in Wave Surfing.
- Simulate the enemy turning perpendicular to the wave's absolute bearing and accelerating to full speed. This is what
Math.asin(8.0 / bulletSpeed)
approximates, but that of course ignores current speed and heading. Predict until the wave passes the enemy and calculate the resulting MEA. If the enemy didn't hit a wall, just use this, otherwise continue to the remaining steps. - Simulate the enemy moving perpendicular to the wave's abs bearing, but with Wall Smoothing. I use a wall stick of 80 and ignore wall hits (ie, use the wall to calculate how he will move, but let him move through walls).
- Repeat step 2 a second and third time, but instead of moving perpendicular, have the enemy move directly towards the point at which they ended the previous simulation. If the enemy will end at that spot, he can further increase his MEA by just heading straight toward that spot to begin with.
- The precise MEA returned is the maximum MEA from any of the above calculations.
This is all in Dookious/utils/Wave.java and Diamond/utils/DiaWave.java. In Diamond, I don't use this for GFs, but I use (precise MEA / traditional MEA) as the wall distance attribute, since I think wall distance is meant to tell you how much the wall is impacting the enemy's movement.
--Voidious 17:24, 18 September 2009 (UTC)
public LinkedList<Point2D> precisePrediction(Point2D me, Point2D them, double heading, double velocity, double bSpeed, int moveDir) {
LinkedList<Point2D> tmp = new LinkedList<Point2D>();
//Not entirely sure this time is set right, but if not, its very close. :)
int time = 0;
tmp.add(them);
do {
double absAngle = Tools.absoluteBearing(them, me);
double absAngle2 = Tools.absoluteBearing(me, them);
double latVelocity = velocity * Math.sin(heading - absAngle2);
int direction = Tools.sign(latVelocity);
//Best angle is perpendicular to the owner.
double targetAngle = absAngle - Math.PI / 2.0 * direction;
while(!battlefield.contains(Tools.project(them, targetAngle, 120))) {
targetAngle += 0.1*direction;
}
double turn = Utils.normalRelativeAngle(targetAngle - heading);
if(Math.abs(turn) > Math.PI / 2.0) {
turn = Utils.normalRelativeAngle(turn + Math.PI);
direction = -direction;
}
MovSim2Stat stat = MovSim2.step(them, velocity, direction*moveDir, heading, turn);
them = new Point2D.Double(stat.x,stat.y);
heading = stat.h;
velocity = stat.v;
++time;
tmp.add(them);
} while(bSpeed * time < me.distance(them));
return tmp;
}
To be fair Voidious implementing this can be quite a trick when you don't have a working Precise Predictor. I fixed that on mine, I used a stick of 120 in this image, but having read your comment here, I think I might try and lower it before I try it in actual use in my gun. — Chase-san 10:04, 7 July 2010 (UTC)
- I also notice that the travel lines can get strange if the enemy is pointing in a non-optimal direction. — Chase-san 10:10, 7 July 2010 (UTC)
Smashing it down to bins
Although this page is called 'Precise', when converting it into (VCS) bins it is not as accurate as it first seems. Just take the very simple example of reversing. It that case the enemy can travel less far than just asin(8.0 / bulletspeed)
. But how do you handle that? Do you make every bin a bit smaller, do you 'overlay' a few bins as they cover the same area, or do you do nothing about it.
When the enemy approaches a wall, the situation becomes even more complicated. The overall angle becomes smaller, but how to handle the size of the bin. Just make every bin a bit smaller is one option. An other option is to make the first few bins (close to the HOTangle) the normal size, but when the enemy is turning towards you, the size of the next bins should become smaller, e.g. dynamic binsize. These situations are quickly becoming to complicated, although adapting to a separate constant binsize for either continuing/reversing seems acceptable. Note that the binsize (max escape angle) could vary for every wave!
In the latest gun version of GresSuffurd I use another approach, simulated precise MEA, but as expected it is not ideal either. I just use the standard theoretical MEA, calculate the real MEA, and ignore all unreacheable bins. I then just hope that my wall-proximity segmentation can handle the situation. The advantage of this solution is that the binsize is always the same, and that bullets that would never hit are traded in for bullets with a chance to hit. Ofcourse there probably are better solutions, so fire away! --GrubbmGait 14:04, 4 April 2011 (UTC)
Yes, I just scale the bin size smaller in Dookious (and Diamond is similar, but no bins). You're right the MEA / bin size varies per wave, but why is that bad? GF 0.5, to me, means he went half as far as he could have in the current direction - slowed to half speed or paused a couple times. GF -1 means he immediately reversed direction and never stopped. I think that's the right way to learn, especially against random movements. Without precise MEA, GF 0.5 and -1 do not fit those descriptions. To me, GF without precise MEA seems like halfway between a raw bearing offset and the true idea of a "GuessFactor". (Well, ok, maybe 85% of the way... :P)
I believe Gaff also just caps the firing angle with whatever precise MEA he's calculated, which seems reasonable. Kind of like WaveSurfingChallengeBotB. I've been doing that with my perceptual gun experiments, but I really only gain a few hundredths of a percent in hit-% once I add the cap. I'm not sure how much that measurement translates to "real" guns. I could actually test a lot of this stuff very quickly with WaveSim... =)
--Voidious 14:53, 4 April 2011 (UTC)