I want this to be a discussion thread to introduce and encourage methods of adaptivity.
My current algo used to be static and I decided it would be fun to make it adaptive, this was my approach:
I hardcoded sections of my algo and if an enemy unit had breached at (for example x value 5) then do the hardcoded element around that coordinate.
(I also hard coded the first few moves (I let my algo choose which side) because the starting moves are what defines my algo.)
How did you tackle making your algos adaptive?
Honestly, mine are mostly brute force. Simulate paths (not straight-up pathfinding, I include removing enemy firewalls via damage) and figure out which one would do the most damage or score the most. I do that with most decisions I make adaptive. It works great for offence, as long as you have a limited set of possible moves, but I haven’t gotten adaptive defense to work very well yet. My maze algo does switch sides based on this, though.
For attack, I simulate different attacks (including attacks possible only next turn) and choose the one with the best results (score and damage).
For defense, similarly I simulate several enemy attacks (for now only among the attacks I’ve seen the enemy use) on several game_map describing my possible defense strategy and choose the most resistant defense.
how would you go about stimulating enemy moves?
Simulating the results of an enemy attack is about the same as simulating your own attack.
I also do some ‘predictions’ about my enemy defenses (enemy tends to repair recently destroyed firewalls) but for now it’s is not very efficient.
For enemy attacks, as has been said in other threads, during the action phase of each turn, you can store the units the enemy spawned. You can then figure out what units spawned in the same places would do now or in a hypothetical board by pathfinding (possibly multiple times, if things would get destroyed) and calculating damage done. You’ll need to make a deep copy of the state in order to add and remove hypothetical units.
This all applies to your own attacks, too, of course.
For attack, I have a cached map that identifies the weakest locations (by damage dealt from destructors) and then chooses the path of least damage. The amount of damage dealt across the entire path determines what kind of attack I do. For example, if there is not a ton of damage for a path, I know a ping rush is a good strategy for that turn, etc.
I’m honestly much more interested in algo’s that build a defense from scratch dynamically. I think this is really interesting and have been working on it for quite a while now.
Some initial things I have done involve calculating every possible way the enemy can move and then determining chokepoints. I also take into account previous paths the enemy has used. I then use this to try and make a fully adaptive defense. This currently works very poorly since it is hard to generalize to match lots of different strategies, but I have high hopes for it since currently, my logic is quite basic. I have no problem sharing this because quite frankly, this defense strategy does not work, particularly against ping rushes.
That being said, I personally believe with some tinkering and developing other things I am not talking about this could become quite good. We’ll just have to see.
I am going to define a couple of terms for how I talk about them. When I say a “dynamic” algo, I mean it is changing in some way. This does not mean it necessarily adjusts to the enemy. A good example of this would be the door strategy, where it alternates a firewall spot like a door but in the same way every time. An “adaptive” algo is one that makes decisions based upon the current state of the game, and the opponent. When I say “fully adaptive” I mean there is no base to go off of. In other words, nowhere in your code do you say “build here first, and then if this happens then add extra defenses” or something. A fully adaptive algo does not have a common starting point, like a maze. It may create a maze, but nowhere in the code would you have a maze structure explicitly defined.
I believe there are tons of algos that are dynamic, and the top algos are all adaptive to some extent but primarily with attack. However, I believe all (please correct me if you see otherwise) the top algos have a very mild approach to adaptive defense. They have a set structure they are trying to achieve (or choose between several) and then make small changes depending on the enemy, etc. I don’t think anyone in the top is using a fully adaptive strategy, and I have extremely high hopes that sometime there will.
Except for first turn, every versions of Aelgoo are fully adaptative (except the firsts few one that where adaptative on attack and random on defense).
Very cool! I will definitely give it more of a look. Thanks for pointing it out.