June 2nd, 2017, 17:27
(This post was last modified: June 2nd, 2017, 18:07 by Nelphine.)
Posts: 5,010
Threads: 17
Joined: Aug 2016
The building of a doomstack should be: whatever your current most powerful intercontinental stack is should be reinforced by the most powerful intercontinental units available modified for distance BUT it should not ever lose units EVEN IF there are more powerful units available.
A second doomstack should only be built if all cities and nodes and towers have reached adequate garrison amounts.
If a doomstack takes enough damage so that another intercontinental stack is more powerful, then the original would become simply units, subject to garrison rules; and the more powerful stack would become the new doomstsck and stop helping with garrisons
Posts: 10,492
Threads: 395
Joined: Aug 2015
The AI builds one doomstack. However it does so from idle units.
If the first stack is busy = heading towards an enemy to attack it - it's invisible for the doomstack procedure. they are not idle units so they are skipped entirely. So it then finds the next 9 best units and gathers those instead. In other words, as long as the doomstack(s) have a target to attack, new stacks will be made automatically as a side effect. As soon as any of them becomes idle, the process stops until the stack has something to attack again.
Effectively there are three cases :
One : the first doomstack dies. In this case, having a second one ready earlier (depending on distances it can take even 10+ turns to make one) is good - starting to build it while the first stack is on the way is good.
Two : the first doomstack wins and keeps going. In this case, it's a successful stack - having another copy allows the AI to take over/destroy enemies twice as fast. Again, this is good.
Three : The first doomstack has nothing to attack. It stays idle, so no other doomstack is being made : "THE" doomstack, as the algorithm sees it, is already assembled. If a new, better unit(s) are made, they might replace the weakest ones in the doomstack but aside from that, the stack does nothing (except maybe going towards the main action continent)
There is nothing wrong with this. However, a stack is 9 units. Assuming the AI has 4-5 cities capable of producing halberdier+ units, and those are near each other so it only takes 3 turns to gather them all, on Hard difficulty, it's very possible for the AI to use almost all the units produced in these stacks. (we are talking about turn ~30-100 mostly) At the very least enough of them that most cities won't have 9 defenders, and of course there won't be any leftovers to send to defending nodes either.
Also, as the more expensive unit is pulled, it leaves the cities with halberdiers (60), while all the javelineers are sent for attacking (75) even though it is the opposite for garrison preferences. (this can probably be "fixed" by either increasing the priority to produce javelineers more often, or by overriding their cost for the doomstack procedure specifically)
However, a similar problem will probably surface with draconians - even though Magicians should be the garrison instead of the offense, they cost more, so they will be used in the doomstack.
Finally, if the AI only has the "best" unit produced in one city, for example Dragon Turtles (but Griffons, Pegasai etc also), and loses its doomstack, it'll want a new one and...boom, the 9 best units are the 9 turtles so the city is left completely undefended.
June 2nd, 2017, 18:02
(This post was last modified: June 2nd, 2017, 18:04 by Seravy.)
Posts: 10,492
Threads: 395
Joined: Aug 2015
...anyway, this is the current algorithm :
0. Do the steps below once for each plane :
1. Go through every owned unit - skip land units and units below cost 55. Skip units that have any order except "move to" or "idle". Skip units in the wizard's capital. Skip units on the other plane. Note that "attack" is not the same as "move to" and is skipped, otherwise it would override attacks which would be bad.
2. Put all units found into a list of 9, highest cost first. Discard any unit after the 9th most expensive.
3. If there are less than 9 units, abort.
4. Count the highest number of units out of these 9 on the same tile.
5. If that number is less than 6, skip forward to 8
6. Check if the shared location is a node or city. If yes, skip to 8.
7. Check if any of the remaining units not at the location of those 6 (or more) are within 8 tiles. If not, abort, we have a "ready" doomstack of 6 units and it would take too long to fetch the last 3 units. In this case the stack will most likely head towards the main action continent.
8. Calculate the two average positions of the 9 units - one going through the edge of the map, and one not going through.
9. Calculate the total distance of the units from the two calculated points. Pick the one with less distance.
10. Find the closest empty map tile to the selected position. (no nodes, cities, other units of any player - but units already on the list of 9 are ok)
11. Send all units towards that map tile.
Done, and next turn repeat this entire procedure (after resetting all units to idle status and going through all other procedures suck as finding attack targets).
Posts: 5,010
Threads: 17
Joined: Aug 2016
I understand what you're saying. But you're not building doomstacks. By definition, a doomstack is more important than garrisons. Also by deginition, garrisons are important. You cannot do both at the same time.
That's why a doomstack is a single stack. If its full, yes it would be helpful to build more, but the idea is to build one so strong you don't need more than one. Then you build defenses as normal. Then you build offensive stacks (which might be as strong as the doomstsck, but which are differentiated by priority compared to defense.)
If the AI can't build stacks that are strong enough to destroy things without significant casualties, then its not building doomstacks. If its not building doomstacks, then it MUST prioritize at least minimal garrisons (sonethng like at least four units in all city garrisons will be ignored for building these stacks.)
Otherwise, it will leave the AI too weak. Yes, its a lot of work. Yes it might contradict what you've already written. But leaving the AI open to losing cities because I have one griffin flying around, is NOT worth doing.
Posts: 5,010
Threads: 17
Joined: Aug 2016
Do you want me to write an algorithm for what I want? I could only guess at the commands based on what you've already posted.
June 2nd, 2017, 18:48
(This post was last modified: June 2nd, 2017, 18:50 by Seravy.)
Posts: 10,492
Threads: 395
Joined: Aug 2015
Feel free to change step 1 any way you think can improve the results.
The other steps are unrelated to the problem and are only in charge of getting the selected 9 units to move to the same place.
The list has to be consistent - meaning the same 9 units have to be picked every turn, unless a new, stronger unit was made or one of the units died. So you can't use "random" or any condition that changes over time on a unit (unless it's a one way change from being invalid to being valid and never the opposite) - but you can assume the units naturally stay in the same order in the memory, so if there are 50 javelineers, the AI always picks the 9 oldest, so as long as the conditions on selecting the units remains consistent, the rest works out automatically.
Quote:If the AI can't build stacks that are strong enough to destroy things without significant casualties, then its not building doomstacks.
The AI will never be able to do that. A human player is smart enough to kill parts of the stack no matter what. Often significant parts. The AI will never build "human" doomstacks - those work because the human player knows exactly what the enemy can do and which units they can kill, and specifically only uses units they cannot kill. The AI builds AI doomstacks. Which just means "the best offensive stack the AI can make". There is no algorithm that tells the AI what is effective against which player or which target. Even if they build a stack from 9 sky drakes, if it attacks 9 javelineers and I know high prayer and blazing march, half those drakes will die.
So unless you change your definition of "doomstack" you're trying to make an algorithm that is impossible.
(also, in the first half of the game, the "doomstack" really only means a lot of common summoned creatures or good normal units. Any decent garrison can kill that. No one has rares at that part of the game.)
Posts: 10,492
Threads: 395
Joined: Aug 2015
PS : The only one easy and universal solution I can think of is to add this to "1." : Non-hero normal units part of a city or node garrison are invalid. (fortunately cities and nodes are marked on the AI's map at this point already)
Then the AI can still prioritize garrisons and the garrison rules of normal units work as intended, but their more important units are free. And this might even fit into the remaining space without having to find a larger free area than the current...quite huge one. Don't remember but I think less than 100 bytes are left.
Posts: 5,010
Threads: 17
Joined: Aug 2016
Can the AI in step 2 use strategic strength instead of cost? (Not sure we should, just curious if we can.)
Also, can the AI look at stack strength (similar to how it decides what units to buff when casting a unit buff, I think) during this?
June 3rd, 2017, 02:24
(This post was last modified: June 3rd, 2017, 03:07 by Seravy.)
Posts: 10,492
Threads: 395
Joined: Aug 2015
Probably yes but we should not. Strategic strength changes a lot (every time a buff or level is gained or lost), so the AI would replace the units in the stack way too often, slowing down the process too much.
Also, "cost" - the one used for this - has a good side effect - it's the same for certain units, allowing the AI to mix them in stacks, for example Shadow Demons and Chaos Spawn are both 210, Doom Bat and Efreet are 360, etc.
Posts: 10,492
Threads: 395
Joined: Aug 2015
By the way, something semi-related.
Shadow Demons. They plane shift, so as soon as the doomstack procedure pulls them from the garrison, they leave the plane (or, might even do that while in the garrison). But on the other side, unless at least 9 of them exist, no doomstack is formed because the wizard has no other units.
Also, this means they are limited to only the "other" plane, so the player will not meet shadow demon stacks from wizards on their plane, but might meet them from the other plane - most likely from wizards they can't even reach yet themselves.
The problem I see here is, the value of dumping these units into the other plane is questionable. If they manage to conquer a neutral city (or consistently conquer a wizard's entire territory without getting killed, thanks to regeneration), worth it, as the AI can start spreading on the other plane. In all other cases however, it's wasting the wizard's best units and the opportunity to have an early flying regenerating doomstack, one of the best such stack possible from uncommon creatures.
...so, the question is, do we like this or do we want to make the AI not use plane shifting on the shadow demons?
|