The system used in Musashi to respond to MirrorMovement bots.
There are a lot of possible approaches to that, but the one discused here is that: "if they wan't to follow me, be my guest...", my wife is trying to convince me to call it "Vem-Nenem", let's see (but u know the GirlPower)...
I have call it AntiMirrorSystem just because it can't fit in a Object Orientated Model any AntiMirrorTargeting by itself. The anti-mirror system concept that was used in Musashi's code relies in a tripod: Detecting, Moving & Aiming.
Detecting:
That is probably the most important and sensible part of the system, if it's not well planned and implemented u might loose points against the non-mirror bots instead of only gaining points against the mirrors.
In Musashi this was thinked aiming bots that mirror using the center of the field as reference (at least for the present). What i've done is quite simple:
Moving:
Here resides the soul of the "Vem-Nenem" or "if they wan't to follow me, be my guest..." philosophy.
That is: The mirror bots use your movement against you, so let's use our movement against them. Afterall, u can predict were u are going to, they can't.
The key for accomplish this, is instead of deciding "on-the-fly" where you are going to move next, pre-calculate your positions for the next n ticks and store them somewhere (an ArrayList for example).
Musashi's particular implementation: Since Musashi's movement is based only in inversions of direction, i pre-calculate my next inversions for the next (2*(distance_to_enemy/11)) ticks and store them in an ArrayList.
My problem here, was to garantee that a wall wouldn't be on my way, and then mess out my pre-calculated inversions. I had also, to fix somehow it's trajectory, otherelse the pre-calculated inversions would be useless by themselves.
I had opted for a KISS solution for this: Once the mirror movement is detected, Musashi starts orbiting the center of the field instead of the enemy, and goes to a wall-safe orbit (radius = (int)Math.min(500, Math.min(field.height, field.width) - 100) / 2).
This is a particular implementation, other bots would probably fit better other approach, the important here is to have a way to predict your own moving. Another approach would be, for example, start moving in a simple pattern. But if the MirrorBot? have a PM gun you can be vanished. Although that could be a simple and efficient approach if your gun is a PM (by moving in a predictable pattern, you can discard the pre-calculated moving, and you won't even need to link your gun to the moving... That is probably a good approach to a non-MegaBot.).
Aiming:
The easy part: Once you've had started moving in a pre-calculated way, it's only a matter of choosing the fire power, calculating the time that the bullet would take to reach him and "play the film" of your own stored moving applied and mirrored(?). Fire at will! It's like a simple PM without having to choose a sample and with almost 100% of chance in hitting it.
So, as i promissed to PEZ, here it is. Musashi's implementation is yet too crude, it can't reach OldManXP nor PrairieWolf (at least for the present). But bots like NaN that were actually beating Musashi (Musashi's scored ~39% against NaN, now it scores ~80%) now die like flies. I hope that this help other bots with the same problem, and also hope that it serves as an incentive on improving the MirrorBots? themselves(yes, i know that is like a bayonet poking their belly, but it's still a stimulus :). As ABC would say: "O mundo gira, a lusitana roda".
These are the general lines of the idea. You probably will find a better way to doing this, or a better way to fitting it into your bot. If I can give any recomendation, there it goes: do it KISS. Afterall, we aren't talking about beating DT nor Shadow...
To detect if I'm mirrored I just check if my enemy is within a certain distance of the mirrorPoint. This might make me mistakenly think I'm mirrored at times, but only very momentarily. From my tests this is very accurate on plain center-mirrorers. Of course I also fail on OldManXP which uses velocity a bit to smart. -- PEZ
I have started with that approach too, but taking an average had proved to be much more accurate. I can even detect and beat OldManXP if i adjust the mirrorSlack value to 50. The problem is that i start detecting other non-mirrors too... I strongly recommend u that averaging approach, it can last a little more to detect (depending on the wideness of the averaging), but is a lot more accurate. -- Axe
I like the idea with cicling the center when in anti-mirror mode. Bloody brilliant! -- PEZ
KISSes! (obviously straight ones, on the cheeks). Glad u liked! -- Axe
Do you do anything to take into account the lag of the enemy's movement compared to yours? (ie. the enemy has to see what your doing, and then copy it, meaning it will be at least 1 tick behind, possibly more) Could you not use a PM technique to detect, and basically compare your pattern to your enemy's pattern, and if they are the same, just mirrored, you have a mirror-bot regardless of the mirror-line (you would need to check horizontal, vertical and diagonal mirror-lines separately). The easy way to counter this system is simply to move the mirror-line, a random mirror line (changed every round) would work quite well... -- Tango
It's a very interesting idea. If you use old school heading-change and velocity the ideal mirror pattern will look exactly the same as the original. -- PEZ
Expect heading change would be *-1, surely? -- Tango
Would it? -- PEZ
About the lag, u r right, very good observation. Indeed i use something to compensate it: the mirrorSlack (see the definition above), witch is precisely the lag.
About using vel & heading change in detection: As i said, there are countless ways on doing it, that is one, no doubts (probably it wouldn't get OldManXP either, but it should work for PrairieWolf). I use vector operations because is what i use in my PM gun (i don't use directly vel & heading for PM, but vector operations on the stored positions). Another reason that I found for using that kind of detection, is based on my particular solution of moving in a wall-safe orbit (see above), it seems more natural to me.
The important thing is to find a way on doing the detection and moving that seems natural to you and fit well in your bot. Regardless of the path that you trail, less is better. So, if you feel more comfortable in not using vectors, the best is not to use it. -- Axe
I also thought many times about how to make a working AntiMirrorSystem and the most effective way to find out if an enemy is mirroring me seems to me a mirror counter: Everytime you scan your opponent check if it mirrors you like:
boolean mirroring=Point2D.Double.distance(getX(),getY(),getBattleFieldWidth()-e_x,getBattleFieldHeight()-e_y)<16.If it does, add 1 to your mirror-counter if not reset it to 0.Then you just have to check each tick if this mirror counter is higher then a certain value and you can decide if you should use your normal behavior ( movement and gun ) or an AntiMirrorBehavior? that slaughters the mirror bot with a hit rate of 100% :D --deathcon
Deathcon, that is precisely how I implemented my mirror detection in Unnamed (although you have to widen the distance to about 30 for it to be effective). I also have an "anti-mirror counter" to detect if the enemy has stopped mirroring. This gives a buffer at both ends. -- nano
Damn it.I thought i was the first one that had this idea. :((( --deathcon