Just WRT your hitting walls problem, you do have WallSmoothing implemented, don't you? -- Skilgannon
Nope, haven't implemented WallSmoothing, nor any other form of WallAvoidance (i.e. limiting goal guess factors via PrecisePrediction that accounts for walls). I do have a form of WallSmoothing planned for the new movement method I'm working on. At some point I may add PrecisePrediction and/or WallSmoothing to my goto style wavesufing, but for the moment I see more potential in a new movement that I've just started coding. -- Rednaxela
If you're doing a style of goto wavesurfing, it's fairly simple to 'warp' any points you are aiming at inside the field, so you don't hit the walls. But good luck for getting your wavesurfing working, and if my 'reachable' method will come useful for you goto-surfing (it's what both DrussGT and Stormrider use), feel free to use it. -- Skilgannon
Thanks, I'll keep that in mind. First though I'm going to to experiment with a hybrid/combination of AntiGravity Movement and True Surfing that I have some high hopes for. Hopefully this idea won't flop... :)
Hmm, after looking at more stuff on the wiki, I see a few have tried a combination of AntiGravityMovement and WaveSurfing before... however from what I see, everyone who's tried that combination before has failed to some extend or another. I wonder if this will be worth trying or not. -- Rednaxela
Well... after some work I got my AntiGravityMovement working, and wavesurfing (using "True Surfing" which moves to local minima on the movement profile instead of the global minima). It seems to surf as intended, however: 1) This surfing style doesn't seem as effective, and 2) I'm not having much success making a "Gravity Source" to do effective wallsmoothing. In particular it seems to get stuck in the corners where it's close to two walls at once. If anyone has any tips they're welcome of course. In the meantime I'll probably leave this code and go back to working the goto wavesurfing -- Rednaxela
Okay! I finally got a working TrueSurfing implementation made from scratch (well, with a little code reuse from my old CircularTargeting code to do the precise prediction)! And damn... this thing is creating a really flat movement profile according to my builtin profile monitor (Well, a compliment to Voidious though: I've yet to see a flatter profile than Dookious's profile). I'm quite proud of my predictor code, which is a little sluggish, but fully accounts for everything except for robot-robot collisions (yes, it does include accurate turning speed limits). I haven't implemented WallSmoothing yet, so it's performance is still not so great though. Actually, against Shadow anyways, it wins a couple matches out of 35, but in a majority of the cases where it loses, it's either a close match where it just can't win (my lack of energy management could be alot of the issue) or getting stuck in a corner. It's encouraging that matches against Shadow end up fairly close when I don't get stuck in a corner, even if I very rarely win in those "close" situations. Thanks alot to everyone who's given tips! Next stop? WallSmoothing!
Hmm, One thing I haven't seen much on, is what to do after the enemy has fired a first shot, but my movement profile is flat so far. In the "GoTo? Surfing" I'd select a random guessfactor to go for, but as TrueSurfing doesn't use "goal guessfactors" in the same way, I suppose any sort of randomized perpendicular movement that doesn't run into walls would do the job fine? One other thought I've had is, do people usually save their own movement profile between rounds? Currently I don't, but I ponder if it might help, at least to avoid the points it visits early in the round from being as predictable. -- Rednaxela
Interesting... I just added some energy management code which roughly means: 1) Don't fire more powerful bullets than needed to kill it, and 2) Avoid firing bullets that would use more than 10% of our energy left. The effect of this, was a drastic drop in score against Shadow but a drastic increase in scorn against Duelist. I wonder what the right balance is or if there is an effective way method to manage energy against both bots... -- Rednaxela
My suggestion: don't test against Shadow unless you are a) just about to beat him anyways and b) are worried about your PremierLeague score. Not beating Shadow is nothing to worry about, nothing beats the strongest version of Shadow anyways =). RaikoMicro is one of my favourite testbots =) -- Skilgannon
But even so, this has shown me that the optimal level of energy conservation depends on the particular enemy, and thus ideally I'd have some way to adjust this. Some thought/observations about this I've had, is that:
IMO, the optimal bullet-power algorithm works like this: if the distance is less than 150 or the hitrate is more than 33%, fire 3 power bullets. Otherwise fire 2 or 1.9 power bullets. Don't fire a bullet that would do more damage than the enemy has life, and would gain if one of their bullets in the air hit you. If you are low on energy fire smaller bullets, eg. energy/10 or energy/16, and never fire a bullet if it would disable you. Remember that the minimum bullet power you can fire is 0.1 =). Some parts of this I still need to add to DrussGT. -- Skilgannon
That sounds like overall a good algorithm, however I'm not sure if accounts for the underlying mechanic allowed me to get dramatically better results against Shadow without energy management. I'm not sure of the exact hit rate I was getting there, but I highly doubt it was over 33% -- Rednaxela
---
I seem to be having alot of issues with getting movement right. For quick tests, I've tried plugging in various WallSmoothing code snippits that I've seen on the wiki, but they often seem to get my bot stuck even more, and if they don't they still cause a large drop in my score even though the movement may look fine to my eye. Anyone have some general tips for movement development? Would it be worthwhile to work in the context of MovementChallenge2K7 in order to develop movement while being sure the gun isn't getting in the way?
Yeah, working against something solid is a good way to go. Do you have any graphical debugging? It can help a lot for working out the finer details of the trig. -- Skilgannon
Currently, I use alot of debugging graphics in my targeting (i.e. a pretty display of the opponent's movement profile and as well as showing which gun is the active one of my virtualguns array), and also display a pretty graph of my own movement profile, however don't currently have any debugging graphics for my movement itself. Also, I just read more about WaveSurfing and found that apparently WaveSurfing is actually generally more about avoiding where you've been hit before. My implementation just was about avoiding anywhere I've been before. I think my movement therefore counted more as a "Flattener Surfing" of sorts (Haha, explains why I saw such a darn flat curve before). I'm thinking of making it bias against place where it's been hit before, anyone have any tips from experience about how heavily/lightly the flattener should be weighted compared to where I've been hit before?-- Rednaxela
In general, you shouldn't need any 'flattening'. Pure hit-dodging is good enough. I only recently (last week) added flattening to DrussGT, and it only gave me a 5 point boost. You have to be careful about flattening against simple targeting bots, because if you do hit-surfing you should be able to 'learn' their gun and dodge it perfectly, but if you add 'flattening' you will only make their hitrate drop to that of a random-targeting gun. DrussGT only enables its flattener if the enemy hitrate is above 10%, and even then it only gets weighted 50/50 with the hit-surfing buffers. I know Dookious, Phoenix and Shadow all employ similar methods. -- Skilgannon
(edit conflict) First, you should consider what your tank's goal is: winning battles (premier league) or winning them absurdly (roborumble). A flat movement works best against strong guns, but it will not be as good as it could be against weak guns. As I have neither, I am not speaking from experience. -- Martin
Interesting... before starting code to match onHitByBullet? events to known waves, I noticed I haven't constructed my EnemyWaves correctly, and they lagged two turns behind the real bullets and were not firing from the exact correct location (I found details about this offset around the wiki). So after fixing this, I thought "heck, it'll be interesting" so I did another test with my TrueSurfing-Flattener vs. Shadow to see the effect this had. The end result, was that whenever I wasn't stuck in a corner, I was actually getting an extremely similar hitrate against Shadow than Shadow was getting against me. It's rather fun watching Gwynfor and Shadow both missing eachother a lot, but Shadow being down to 0.0 energy while I still had 16.0 or so (sad thing is, it made a comeback and I didn't have it dead again till at 5.3 energy). I'd call that test encouraging that my WaveSurfing-Flattener is pretty good besides the lack of WallSmoothing and that my targeting isn't 100% useless... :-) Anyways, back to matching onHitByBullet? to EnemyWaves now, so I can do WaveSurfing-Dodging properly against people who don't target as well as the top bots '(edit: Okay, well, it seems getting that great hitrate ratios only happens every so often. It seems however, that sometimes Shadow gets a series of consecutive hits on me, but other times I'm just dodging perfectly. I'm not certain, but I think this likely means that sometimes Shadow is able to sometimes find some predictability in my flattening but other times it's just clueless. Still, the fact that it's able to fool Shadow fairly often isn't a bad thing. Anyways, back to concentrating on making movement that's good for thrashing non-top bots.)' -- Rednaxela
While working on getting WaveSurfing-Dodging coded more, I casually did a codesize check for the heck of it. Sure, for a MegaBot, codesize is meaningless, and I do have some "historic" classes of unused movement/targeting methods around, but even so... 14412 codesize. This one is getting big ;-) -- Rednaxela
Well, code rot has been kind of ill-managed here as I've developed Gwynfor. Now I need to decide, if I want to remake Gwynfor largely from scratch, do a lengthy refactoring, or hackishly finish off WaveSurfing before moving on. It's a pity because I put a lot into it. Hopefully lessons learned will make the next attempt smoother. If I remake from scratch, or move on after finishing off WaveSurfing, I wonder what I'll call my new bot, if it will still go by the name Gwynfor, use a variation like GwynforII?, or if I'll choose a new name entirely. Decisions, decisions... Curse you code rot... -- Rednaxela
Okay, in the rewrite, one issue I'm pondering, is how to set up robust event handling. In Gwynfor's first incarnation, I didn't really deal with many events besides onStatus, onScannedRobot and onPaint, however in order to do really nice surfing I'll have to deal with the different bullet events and such things. The issue is, I'm pondering a robust way to handle events in a way that keeps the state of the robot while it's processing a tick completely atomic (i.e. all events are buffered until the next time around the main loop). In Gwynfor's first form, It wasn't hard to make my "EnemyRobot?" data storage class buffer scannedRobotEvent? objects, and also make my "BattleState?" data store the next pending statusEvent, and such things. I'm just wondering what have other people tended to do to address this type of issue? I haven't seen much on the wiki about handling this. I'm thinking of storing a list of all events that occurred on a tick, and letting various data storage classes rummage through the list themselves, but I'm not sure if this is a great way to deal with it. -- Rednaxela