AF wrote:As always write out the algorithm in pseudocode so we can all ellaborate on it untill it's sufficiently detailed to transfer into code.
I'm not sure how the whole AI loop works, so it's more like a list of checks than pseudocode.
1. First off, see if there is at least one builder (unit or factory).
2. If true, see if there is some metal and energy income.
3. If 2 is true, AI is still active. If 2 is false, check to see if there are at least enough spare resources to build a resource unit of some type. (This runs into a problem only if there are, say, energy-making structures that cost no energy or metal to make; you'd always be able to make more of them, but never gain any metal if metal extractors cost at least some metal to make and the AI is at 0 metal. But that seems like a really unrealistic mod design.) If it can't, the AI is dead. If it can, it should build said resource structure and start the check again.
4. If there is no builder, the AI is probably dead--but perhaps not! Maybe it (somehow) still has tons of energy production, plenty of defenses, and some attack units that it could potentially kill the player with. This is the tricky bit. The AI should immediately attack with available mobile units; if they're stuck they should be disregarded from the check. (Detecting stuck units is a separate problem.) If they're not stuck, it's a matter of waiting to see if the player dies before they do or not. The AI is still "active" during this time. If the units are destroyed it will have to run the check again based on more remote possibilities of success.
5. For instance, the AI might have no mobile units, but may have long-range assault structures capable of killing a player, and defenses and energy production sufficient to hold the player at bay for a long time. This is perhaps the trickiest situation--determining if its weaponry could actually kill off a remaining side or not. It's a little easier with a maphack--seeing if there are any enemy units that simply cannot be hit with any of its weapons. Without one, I guess it would only know for sure that it's failed if the game is still ongoing, yet no shootable enemy units can be detected. I.e., none of its weapons can reach any detected enemies (easy to calculate just considering range, but it would also have to be able to determine whether terrain is a permanent obstacle or not), or there are simply no detected enemy units. Since it has no mobile units, it will never be able to detect the enemy base and will never be able to shoot at it regardless of whether its weapons are physically capable or not. (Caveat: if a mod were created in which a side could completely cloak/stealth their base, but with some weakness like the invisibility goes away for a while if a unit is hit with a stray shot, then this would still be a normally "winnable" situation that this algorithm would not properly detect. However, I have a feeling that no existing AI would be able to play such a mod in the first place, so it's kind of a moot point.)
Some theoretically generated outcomes that are a bit weird: if the enemy has, say, a scout plane, it would be able to use it to spot for artillery (and then it comes down to range/line-of-fire checks). If this scout were destroyed, the AI might find it has no more mobile units and cannot detect any enemy units. So the AI would be active so long as the little scout plane were left alone, but shooting it down would cause the AI to self-D its entire base. Something of a butterfly effect. This behavior seems a little extreme, but it isn't really wrong.
One other approach would be to allow the AI to continue as long as it has any weapons remaining and sufficient energy to fire. However, a single solar and LLT hidden away in some remote recess of the map would keep such an AI active even though it comes down to the usual "send radar planes all over the entire goddamn map just to find a solar and LLT" problem, so I don't support that method. Even though the LLT could theoretically kill all the units a player sends at it, it could NEVER destroy the player's base.
The only time this algorithm really seems to make bad choices is in games involving more teams. Team A's few remaining defensive structures might be able to kill Team B's assault force, which B intended to use to kill A and then kill Team C. Meanwhile, Team C launches all its units at Team B's base. If Team A (an AI) self-D's, Team B is cleared to send all its units at Team C without having to worry about Team A's defenses as all. Perhaps in this situation, Team B triumphs by killing C before C kills B's base. However, if Team A did not self-D, A's defenses might cause enough damage to B's units to give C the upper hand. Either way, A won't legitimately win, but its self-D behavior can still affect the outcome of a game.
This is also an obvious effect regarding allied teams--an ally with defenses but no assault units is still valuable to your alliance. However, this doesn't present a big problem for the algorithm since it merely needs to be extended to account for the capabilities of the entire alliance rather than just its own team. As such, only the previous example seems to be a significant fault, and it's such a rare situation that I think the benefit of the algorithm considerably outweighs this fault.
Edit: note that even though this check is probably quite CPU intensive, it can get away with running VERY rarely--even once a minute would be sensible, and once every three minutes would even be tolerable. And throughout most of the game, the check would exit
very quickly as there would be an active builder found right away.
It'd also be nice if the AI announced that it was self-destructing, so it doesn't leave the player wondering, "what just killed that AI? Does that mean there are other enemies over there?"