I still don't get it :) ...
The highlighted comment was created in this revision.
Hi mates. I would appreciate a little help with displacement vectors, my brain starts to rotate in circles and i guess i do it horribly wrong.
What i do so far is:
1) collect all target positions (scan)
2) build a map with every displacement vector from 1-60 (if possible) for every scan (60 is enough for me with 3.0 bullets 11*60=660 and 0.1 bullets 19.7*60=1182) which is within my combat distance
so far so good (bad?) ...
3) i want to shoot :) ... because i guess it is a good idea
4) i calculate a appropriate bullet power for the current distance to the target
from now on i guess i do something wrong...
5) what i have now is a huge bunch of displacement vectors and don't know which one to choose... (more important - which one is the right for my bullet power)
6) so i calculate the bullet ticks it would take to reach the target at his current position... (thats nice but i wouldn't hit the target with this)
7) now i limit the displacement vectors to min/max tick (minTick= travel time of my bullet if the target is approaching me at full speed, maxTick the opposite) (this should be more precise but for the first try it should be enough)
8) next is to take all displacement vectors from the map which are from minTick to maxTick
9) now i eliminate all vectors which point out of the field
10) for all remaining vectors i make a max visit check - max visit is calculated by indices so vectors with almost the same angel and distance will be counted as the same (i guess this is not good)
11) take the most visited and calculate an angle for this one.
12) shoot next turn with this angle
Well, this works so far and i got an acceptable hit rate out of it. But it looks so horrible wrong that i could cry out in pain.
The main questions now are: Do i have to rely on waves and make the vectors scalable or did i oversee something that could make my approach also scalable. What is a good way to select the right displacement vector for the current enemy state? Is it comparable to GuessFactors and i should map additional informations to the displacement vectors?
I guess i don't full get it how the collected vectors will be used. If i look at the picture from the displacement vector side i see a bunch of vectors as well and lets say they are all for the same bullet speed - how do you decide which one is the right?. Because i collect every single displacement vector, the target looks like an hedgehog if i paint all vectors.
I guess i just need to talk a little about it to get it right, and i would appreciate any heads up in the right direction.
Take care
Well, what I do, is the displacement vector is always scaled by time, so every displacement vector is just a per tick average of the enemy's movement. Bullet power is forgotten, like with GFs. So if the bot moved forward 30 and left 50, relative to their initial heading, and this was over 10 ticks, the displacement vector recorded would be (3, -5). To select which displacement vectors to use, I do it the same as for GuessFactors or anything else, by recording other attribute data for inputs and doing a KNN search. In fact, all of my gun code is exactly the same except for the method that translates their movement over the time of the wave to a GuessFactor or Displacement Vector, and back into a firing angle relative to the absolute bearing to the enemy.
To project the displacement vectors into firing angles, I go tick by tick, adding the dx and dy of the displacement vector to their current position (you can do the trig once and cache it, since the angle isn't changing) and advancing my wave by bullet velocity until the bullet would pass their position. It's true you might want bullet power to also be one of the attribute inputs. I do this in Diamond's main gun (though it's GF). But it's not hugely important.
So, I'd say yes, use waves. You could use any timer, but waves mean the timer is bullet flight time, which is a reasonable choice. If you want to go to a lot of trouble not to suffer the loss of fidelity in dividing and re-inflating all the vectors by bullet time, it would probably be simpler to just do real Play It Forward from the raw movement logs.
Does any of that make sense / help? You could also check out Diamond's wave class or BrokenSword for a really basic version of how I use them. (Though I store them as polar coordinates in BrokenSword, for code size. ;))
Oh, I missed that part of your confusion is how the vectors get used. You don't select "which one" to fire at - each of them produces a firing angle, and then you do a kernel density calculation on all the firing angles to decide where to shoot. At least that's what I do, for both GFs and displacement vectors. This can be a really simple calculation, like:
- Look at 59 evenly spaced angles from GF -1 to 1 (Math.asin(8 / bullet speed) yada yada).
- For each one, count how many of your firing angles are within half a bot width (roughly (18 / distance)).
- Fire at the angle with the highest count.
I do something a little fancier, with some smoothing and weighting the count by the scan distance calculation, but you get the idea.
My thought was, if i'm using waves i have to rely on the radar at the right position if the wave hits the target. But i would like to just collect the scan and build all known displacement vectors for this scan. That would give me a little more robustness against missed targets/scans. While reading your posts i got a glimpse of an idea what i could do better, but i have to think a little more about it. I guess i will play a little with the timer and look where it goes.
If you use the bullet flight time as timer would that mean if the target gets closer to you, you have no displacement vectors and have to collect it new for the now changed bullet time? Or do you scale the vectors on the new bullet time as well? I'm always concerned my gun could not learn fast enough if i take to much different states into account.
I have to admit that i don't get the point, of having displacement vectors and still do the tick by tick stuff. I thought you have it once calculated and then you can use it at the right time - at least this is what i do right now (not to speak in a crummy way :)), i guess i have to change my thinking there.
For the density stuff - i guess i do it somehow right now (point 10) there i take all remaining vectors and make a highest count check. I might have a look at the more 'fancier' :) densities. Thanks for pointing me at this.
I try to avoid to look at Diamond, because it is way to sophisticated for me :) and it gave me quite a headache the couple of times i had a look at it. I guess i take my chances with BrokenSword :).
Anyway thanks for taking the time to bring a little light at this stuff.
I see what you mean about collecting vectors between the current scan and all previous scans within a certain range. That makes sense and should get you more data. I do something different that gives me more gun data in Melee - I also fire waves from the position of all other bots alive on the field. The effect might be similar. This seems separate from whether you scale them by time when you collect and project them.
I was wrong about how I do the tick by tick projection stuff, but regardless, you want to account for the fact that the projected movement might change the bullet time you're using to project. I.e., you don't want to project the displacement vector 35 ticks if they'll end up 30 bullet ticks away from you at the projected location. I do it the same way many do for Linear or Circular Targeting: take their current distance / bullet speed and project the vector that much; get the bullet time for the new location and re-project; do this until the bullet time doesn't change, or I'm alternating between two bullet times.
Dunno when you last looked at Diamond, but the code has gotten a huge overhaul since the 1.6.x versions. I think it's a lot better now. But it might still be "sophisticated". =)
After looking at BrokenSword i'm now even more confused :). I saw you classify the vector by distance and velocity and collect 200 vectors for each index. This is quite similar to what i do right now, but i take lastHeading change and velocity. Then you fire a wave and register the displacement vector if the wave reaches the target and you have scanned it one tick before. so far i can follow :). Now it comes to calculate the fireAngle. You take for all targets the lastVectors (are you not concerned that you haven't seen the target for quite a while?) and then just scale the vectors to the current distance and bulletPower. If you just scale the vector to whatever tick you want, would that not be against the displacement vector idea? Because the target could be anywhere between the vectors start and end point, i guess. I would say the worst thing that could happen is, you calculate the vector for lets say 20 ticks and scale it down to 1 tick. Now the battle progresses and you use these vector, but the target travels 30 ticks. If you scale the 20 tick vector the target could be anywhere. Don't get me wrong maybe i missed something important :). I was a little unsure about my thoughts and started a little test match against my current arch enemies Tron and DoctorBob :) (meleefield). Tron moves very straight but jiggles in a very nice manner so he should be save against almost all simple guns but vulnerable against displacement vectors. Maybe you have a look by yourself :) but be prepared it is very devastating what he does with BrokenSword. DoctorBob is a nano bot and he just oscillates to close combat distance. Which is quite nasty with simple guns but every learning gun should kill him quite well.
The question is, how is the average displacement vector working? To me it looks like the classifyer attributes are very important to group the right vectors but the scaling generates a lot of noise and misinterpretations. My gun is a little better in hit rate against these both bots but still not competitive. I will give the timer tomorrow a try and play a little with the attributes i let you know how it worked out.
Take care