[For Scripting ZvP, PvZ] AI Strats (includes Triggering)

Started by Kernel64, March 08, 2010, 04:12:02 PM

Previous topic - Next topic

Kernel64

So it's like making a chess engine of the sort. Making an AI that can generate it's own list of to-do's and choose between lists of what it can do at certain degree of effectiveness, is something.

I suggest a far simpler approach. An ai that doesn't problem solve, but still solve problems. It will become predictable overtime, in terms of how it responds, when, how much, etc. Eventually people will be able to trick it to doing something by triggering it to do just the thing, and smash it down, depending on how well the AI can shift between blocks of commands, and how fast it checks and rechecks if it should take another block.

This involves creating a database of the sort. These said blocks, or list of commands. These commands may be small, like, Train 6 lings more, tech to hydra, add more drones, add two more ovies.

It won't be as intuitive as what you mentioned, but it can serve, just as you said, to provide some level of responsiveness. It's not as close to an actual thinking engine, but more like a scenario randomizer that allows players to at least develop some skills until they face an actual human opponent.

I sure hope that idea of yours is doable. But if we can make an AI (or most accurately script) that does respond even if not at that level of precision you described, then I believe it would still be worth it.

Your insight is worth noting, and I think those capable should get a crack at it.

hd

I think the both of you are over complicating the AI and this process. I'm not trying to be a nay-sayer but this is getting some what out of hand. :\

Astazha

I'm just looking out at the horizon.  In the short term I have more modest goals, like making the AI expand and scout intelligently, and attack based on a probability of success instead of when a some total unit count is reached.

Kernel64

Yeah, I know hd. Actually, what you said before always keeps me a bit grounded. For the sake of modesty, that is. And it's a good thing you said those words.

But yeah, as Astazha says, I love to think of the what ifs. But hey, if

"If (AITechCount( player, c_zu_Spawningpool, 3) != 1) works, maybe, just maybe, if we consider number of gateways and pylons as a single unit, we could do something like

HyperCounterUnit(data_struct_Gatewatys);

???

Kernel64

Here are some development notes that might be useful to anyone interested. The idea is to make a process for ai command execution and adding/modifying the OrderList -- the main list that the AI will process line by line.

Quote
Ultimate Goal:
        AI can decide the best course of action. But to do that, it must be able
        to filter through a collection of data.
       
        - it can get the numbers of what is. True, but it considers everything
        equal. How does it evaluate so that it will decide to make 4 drones in
        the beginning of a game?
            a) it is the most immediate thing it can buy.
            b) it is told to do so.
            c) it can see it will be needing the resource rate to make it happen.
           
        Option C is probably something very hard to pull of. There's just too
        much equation involved when you can simply feed it with information
        you know -- option B.
       
        Option A means that other decision factors must come into play whenever
        resources are high. Even so, a smart human will still spawn drones if
        it forsees a long match -- that it is going to need to gather resource
        to match the opponent's resource when the time comes what is in the bank
        has been depleted.
       
        note: AI can choose to go ECON, and choose DRONES if a function exists
        where the resource rate of its opponent is measured. It can then:
            a) WANT TO MATCH THAT RESOURCING RATE,
            b) BEAT IT by a degree,
           
        How I think:
            I chose to make all larva into drones because:
                a) there was no immediate threat, or
                b) the immediate threat is no longer a threat because
                    i) I have military to:
                        1.) Match it, or
                        2.) Hold it for enough time where the second
                            batch of larva and the production of units
                            is already possible.
            I did not think of:
                a) What if the opponent used that time to spawn units, and
                thereby pose a greater threat so that at the next turn,
                even if I produced all larva, I wouldn't be able to match it?
               
        AI Proposal:
            1) Check if opponent is producing ECON,
                a) yes:
                    i) Produce your own if you can
                    ii) Produce military and attack
                   
            note on ii: This would be very strong if the ratio after producing
                units is, Mine > Opponent
           
            therefore, we choose ECON only if we have equal military, we have
            no plans of attacking, we want econ.
           
            We WANT econ if:
                a) Enemy is going econ
                b) Military status quo is at a neutral level
                c) We do not wish to increase our rating Military wise
                d) We have free resource and larva,
               
            Two types of Econ building:
                a) Greed - we want more, because we can.
                b) Need - we have to, because we do not have.
               
            NEED
                - econ becomes the highest of priorities, even if we can
                do anything else;
                - we do not do this if military is not neutral, or minimal
               
                Military Status Quo reads enemy data of alive and in progress.
                Response to these must be immediate.
               
            GREED
                - everything else in the current status quo of demands have
                been met,
                - we have surplus larva, and minerals,
               
HOW TO DETERMINE THE STATUS QUO

    a) By feeding a list of what needs to be there at a certain phase
    b) By reading presently existing and changing data and responding:
   
    ECONOMIC STATUS QUO (B)
        1) We are greater, lesser, or equal to the enemy's economy
       
        How it works:
            1) READ ENEMY ECON STATUS
            2) CHECK IF WE NEED MILITARY
                a) No
                -Check if we are higher or lower or equal...
                    i) Lower
                        -check how many we can morph
                        -check how many we need
                        ()we can morph LESS THAN WE NEED TO:
                            -add them to queue
                        ()we can morph MORE THAN WE NEED TO:
                            -queue needed only
                        ()we can morph EXACTLY AS NEEDED:
                            -queue them
                   
                    ii) Higher (or Equal)
                        >> CHECK IF THERE IS A TECH NEEDED/WANTED...
                        yes:
                            *check if we have spare money after spending
                            on tech...
                                yes:
                                    -check how much we can spend on drones,
                                    -check how many larva are free
                                    -make accordingly (add to queue)
                        no:
                            {proceed to PRODUCTION check}
                           
                        >> CHECK IF THERE IS A PRODUCTION NEEDED/WANTED...
                        yes:
                            *check if we have spare money after spending
                            on Production
                                yes:
                                    -check how much we can spend on drones,
                                    -check how many larva are free
                                    -make accordingly
                        no:
                            *check if our money is good for expand
                                yes:
                                    -add expand 1 to queue
                   
                b) Yes
                    >> SATISFY MILITARY STATUS QUO
               

TECH-ING
    I want to tech because:
        a) I need to respond to a threat
            This is common. Human players choose a tech path based on what they want to produce
            in military. Upgrades are not considered tech.
           
        b) I can
        c) having this tech will allow me to counter threat better
        d) this tech is a prerequisite
       
    I tech even without a threat and way before a threat can be read because:
        a) I can
            -Everything else is satisfied
            -There is free resource
       
        b) It is a prerequisite to what I want/need now in Production queue
            -This is a call from other Directives. Directives such as Military
            and production can add a tech to the queue. But only if they
            absolutely need them.
           
    Why choose a baneling nest over roach warren and vice-versa?
        a) Enemy race factor
        b) Enemy forces factor
       
        I choose baneling nest if I'm looking to make banelings; R.Warren if
        roaches. Simple.
       
Issue: If the AI only builds tech if Threat data is already there, it will be
        too late when the threat arrives?
       
        Solution:
            We gather TECH data from the enemy and respond accordingly.
       
        How do you choose between two tech types available given enemy tech
        data without feeding the AI what's the best course?
       
            We can't. We have to have a list that the AI will use to evaluate
            what tech to respond with against a specific tech.
           
        We NEED Baneling nest tech if we see three gateways, and no Cybernetics
        core. (vs Toss)
        We NEED Roach Warren tech if we see two gateways, and no Cybernetics core..

Experience:

        (Vs. Toss with Early Immortal attack)
       
        When I saw gateway and cybernetics core, I was double minded between
        facing a stalker army/air/or immortals.
       
        When there was 3 zealots, I made lings. Harrassed, lost the lings, did
        not replenish, as they were not within range of attacking.
       
        I had to choose between mass lings/Muta/Muta:
            -Chose to expand early since I am capable of dealing with
            stalkers with lings, and there were no stalkers yet. (tech is ignored)
            -Chose to add gas/lair when RoboBay was in progess, and no
            stalkers were there. (lair was chosen as tech vs robobay. 2 gas was required by Lair)
           

    Therefore, we must have a list that the AI can use to counter tech choices of the enemy.
        ex.
            Tech to counter: Robotics Facility
            Tech Threat Count: 2
            Tech Counter: Lair, Spire

When do we Queue in a tech?

        a) When we need it for a Queen
        b) When we need it for a military response
        c) When it is a prereq to a desired tech
       

//==================================================================================================       
TECH MANAGER
        >>Check demand list which is queued by MILITARY, ECON, PRODUCTION, and self
        *do we have an item?
            yes:
                add this to the queue, and remove from our demand list
            no:
                (proceed)
        (since we have nothing demanded from other managers, let's see if we can slip in a tech)   
        (we always want to get to Hive. So we want prereqs done so we can get to hive)
        >>Check if we have Hive tech...
            no:
                >>Check if we have Lair tech...
                    no:
                        Check if we have Spawning Pool...
                            no:
                                add Spawning Pool to our demand list..
                                (proceed)
                            yes:
                                add Lair Tech to our demand list..
                                (proceed)
                    yes:
                        Check if we have Infestation Pit
                            no:
                                add Infestation Pit to our demand list...
                                (proceed)
                            yes:
                                add Hive tech to our demand list...
                                (proceed)
            yes:
                (proceed)
        (Let's see if we can slip in an Evo Chamber)
        >>Parse the Main Order List, and count the total cost...
        >>Get our current money and deduct the total cost of Order List items...
            *do we have spare money?
                yes:
                    >> Check if we can buy 1 evo chamber...
                        yes:
                            add evo chamber to our demand list.
                        no:
                            (proceed)
                no:
                    (proceed)
       
        (let's see if we can morph previos techs that was not called by Military, Prod, and Econ)
        >>Check if we have Hive tech...
            yes:
                >>Check what tech we don't have...
                    no Spire:
                        >>Check if we have spare money for this...
                            yes:
                                add to demand list.
                            no:
                                (proceed)
                   
                    no Hydra Den
                        >>Check if we have spare money for this...
                            yes:
                                add to demand list...
                            no:
                                (proceed)
                   
                    no GreaterSpire:
                        >>Check if we have spire...
                            yes:
                                >>Check if we have money for this...
                                    yes:
                                        add to demand list..
                                    no:
                                        (proceed)
                            no:
                                (proceed)
                   
                    no Nydus Network:
                        >>Check if we have money for this...
                            yes:
                                add to demand list...
                            no:
                                (proceed)
                   
                    (etc...)
            no (hive):
                >> Check if we have lair...
                    (do same yes and no here)
   
       
Note:    Our Military, Econ, and Production managers must always add what they need to the demand list,
        otherwise, the Tech Manager will choose a tech based on what it wants: TO GO HIVE and FULFILL
        EVERY MISSING TECH.
       
        the order of Fulfilling missing tech is from Hive down to Hatchery tech.
       
//======================================================================================================

Checking if we need Military...

    This function evaluates the Military Status Quo, and responds respectively.
   
MILITARY MANAGER

    what this does atm:
        1. Checks current enemy military force, and responds by adding unit orders to the OrderList.
        2. Updates the order list when we have what we want to produce in there.
        3. Demands tech if tech for Best Counter does not exists, also with secondary counter.
       
        -------------------------------------------------------------------------------
        ex.
            We see: Marauders, 10 units.
            Our Feed says:
                Best Counter Unit: Mutalisk
                Best Count: 40 percent
                Secondary Counter Unit: Hydralisk
                Best COunt: 100 percent
           
            We check if we have these units. If no:   
                We check if we can produce, if no:
                    We Demand Spire, because of Mutalisk
                    We check if we can produce secondary:
                        no:
                            We Demand Hydra Den because of Hydra
               
                our Tech Demand List becomes:
                    0 - Spire
                    1 - HydraDen
                    Tech List will process Tech demands like this:
                        Spire will be checked if it can be morphed, if not:
                            Pool will be checked, if not exists:
                                Lair is put first into the TechList.
                                Then Pool is put first into the techlist.
                            Tech list becomes:
                                0 - Pool
                                1 - Lair
                                2 - Spire
                                3 - HydraDen
        -------------------------------------------------------------------------------

    >> Gather current Enemy Military Data
        - list every enemy military unit by type and count, All in queue + progress + done. Most powerful
            comes first.
        - parse the list each line and: (repeat until the list is done)
            >>Get info on the best counter to this unit..
            >>Check if we have that unit include: ready, in queue, and in production...
           
            NO: Check if we can produce that unit..
                no:
                    >>Demand required tech, add to TechDemand list..
                    >>get info on the second best counter to that unit..
                    >>Check if we can produce that unit..
                        no:
                            >>Demand tech, add to TechDemand List..
                            >>Is this unit a Ground based unit?
                                yes:
                                    determine how many we can produce
                                    queue to our templist the default response unit to Ground Threats.
                                no:
                                    determine how many we can produce
                                    queue to out templist the default response unit to AIR threats.
                        yes:
                            determine how many we can produce
                            Queue that unit to our templist...
                yes:
                    determine how many we can produce..
                    Queue that unit to our templist...
           
            YES: Check if what we have in total is in the appropriate count...
                no:
                    add more..
                yes:   
                    (proceed)
        (continue parsing the list until done...)
           
    (we now have a templist)
    (we need to check the main OrderList, if we have these items listed)
    >> (Check OrderList if we have it there, update if necessary, add if not there)
        - Parse Orderlist by line
            - Parse ours each line until list is done..
                *Do we have it there?
                    yes:
                        *Is the count updated?
                            no:
                                change count to current count..
                            yes:
                                (proceed)
                                remove this line from templist
               
                    no:
                        add this line to the OrderList
                        remove this line from the templist
            (Continue until we've checked the entire templist)
        (continue until we've checked the entire OrderList)

Astazha

I'm trying to get to approximately the same place with my Overmind project, just going to take it in small pieces.


Quotea) it is the most immediate thing it can buy.
            b) it is told to do so.
            c) it can see it will be needing the resource rate to make it happen.
I'm shooting mostly for C, with perhaps a tiny bit of B.  It's important to me to have an AI that makes decisions for itself.

I think the resource rate is very doable, and I'm working on that angle now.  We can initially just feed it an order or have it select from them based on map size and personality, but the problem just appears later in game if we don't think about it.

It requires 6 (about 5.5 actually) drones to produce an income that will finance Zerglings as fast as a Hatchery makes larva.

It requires 14 drones to do that if the Hatchery has a queen.  (These values are calculated, not from testing, so the AI can reach these conclusions without help.)

We want some amount of surplus for development unless (and this should be the unusual case) it is tactically worthwhile to spend everything on military at that time, but that cannot be sustained unless we're on the winning side of the exchanges.  Exactly how much surplus could be one of our personality variables.
So you can start with this kind of thing - if you told the AI you wanted to have double the required income it would conclude that an 11-Pool is the thing to do, which would be reasonable initially.  Once it evaluated that it could improve it's production capacity by building a queen, it would conclude that it wanted twice the economy of 14 Drones, which isn't possible with one town.  At this point, it must make do with one town until conditions are ripe for expansion.  Only 24 Drones would be useful so it would stop there, or perhaps even stop for a bit at the point of diminishing returns, 16, to press the military angle based on scout information about the enemy unit count and the recognition that 6 or 12 or whatever Zerglings isn't going to cut it anymore.


Once the military is happier it runs up to the max of 24.  Somewhere in there it starts to wish for Banelings to deal with this Zealot infestation and goes for gas.  At that point the AI needs another Hatch for increased production capacity and it needs an Expansion to make it's economy any better.  It will make a security evaluation and either Expand, Hidden Expand, or just build a 2nd Hatch at home to boost military production and reach a security level that will permit truly expanding.

I don't know that 2x will serve us throughout, but it can always be modified by other routines based on game conditions - most likely this would be data about enemy force sizes.

I think at the strategic level it's worth guessing what the enemy's economy is, but most of the time it will be exactly that.  Our scouts aren't going to get to see their mineral line once the game gets going, so we'll have to make assumptions based on the number of known expansions, etc.

I ran some testing today on economic rates.  These numbers are pretty close:


Quote1st 2 Drones on a mineral pile:  2/3 of one mineral per second (each)
3rd Drone on a mineral pile: 1/3 of one mineral per second
1st 2 Drones on gas: 2/3 of one gas per second (each)
3rd Drone on gas: 1/2 of one gas per second

Hatcheries produce 1/15 larva per second, and a queen hatch pair produces an additional 1/10 larva per second.  The Overmind thread has a link to a function that calculates larva & larval rates, and I'm working on the economic functions right now, to include marginal rates, % of possible economic capacity, payoff times, etc.

I'm also managing gas between certain min and max thresholds so that peons aren't wasted for gas when we're dying for minerals.  Right now it's half-ass, but I'll be wanting to make that sing us a tune before long.

I'm initially making nothing but Zealots and Banelings available to the AI, and asking to defeat Starcrack's full Protoss with that.  This will drive the framework and decision making infrastructure without bogging it down in the endless list of unit possibilities.  Use of subroutines to keep the decision making modular will allow us to increase the sophistication of a particular aspect without upending the whole framework.

Astazha

So for example the Military subroutines (Cerebral?) will produce the output:  I want Zerglings and Banelings in this ratio, with no more than X Banelings but as many Zerglings as I can get.


The Overmind will then balance that with everything else.  It doesn't matter if the initial way to reach the decision about unit composition is really poor or even random, because you can make it sophisticated later and the Overmind doesn't know the difference, it's just getting better input.

Kernel64

Progress:

Have made a simply prototype of an engine that uses the orderlist which can be stacked on to or queued into with commands.

The AI's personality is currently based on randomization, and my plan is to use the modular blocks to add a list into the Order List. This Order list is a simple collection of arrays which are translated into AITrain/AIBuild/Expo.

It would be interesting to see if it's possible to parse from a text file. This way, we can maybe make an AI editor which people can use to define their custom personalities, order blocks, etc. and share them. We can then make a simple form that reads from other files and bunch them together. This way we'll have more scripts to play with.

The idea of the engine is that, it uses blocks to have a guideline for proactive behavior. Reactive modifies how those orders are executed, and sometimes skipped altogether, proceeding to the next block, when called for.

I'll post it up when a more stable one is available. Then anyone can use it for further development.

Astazha

Would love to see that.  I'm going AITrain for sure instead of the stock functions - that's one of my next big goals.  My intent is not really to create a queue but to have the AI decide every time what it should be building right now.  Unless conditions change, it should be heading for the same goal during every calculation cycle anyway, and if things have changed then changing directions is appropriate..


The reading from a text file thing: we can parse XML... the only thing is I'm not sure if you can reach XML that is outside of the MPQ.  Even if you couldn't though, a utility could be generated that would edit the AI variables without someone having to really get into code.


Another idea, and one that I'll be doing for testing at least:


I want to build the Overmind AI so that I can co-exist with another Zerg AI.  The idea is to have


1) A constant determining how many of the AI are allowed
2) a static global variables tracking how many are present already
3) code in the ZergInit that looks to see if an Overmind AI slot is available, if not this player gets the default.
4) a player indexed array will store which AI a player is using, and all of the appropriate functions will have to have if statements to shift between them.  This will mean that it will take a significant amount of surgery to install Overmind into a new AI version in this manner.


At the most basic level you would just replace the OpenGnd0 etc. level of code, but if you really wanted to see the full difference then the unit-behavior functions in TacticalZerg and the army behavior in MeleeAI etc. would have to have if statements as well.  This would allow you to see the difference that is made by things like the improved Queen routine we wrote.


It may not be worth the hassle for release, but for testing ZvZ this would be invaluable.  If you did release it like that, then the number of allowable AI's of each type could be one of the XML variables.  Or it could be random selection.  A 2v2 would be more interesting if a mix of completely different AI's was possible - though that would be a nightmare to maintain.

Kernel64

Attached are the files.

Attached all these since I have no recollection of what exactly and which ones I've tampered. I'm sure though that one of these contained that thing where the engine jumps to the next state.

Zerg will remain within Opengrnd.

All the functions are inside the Zerg0.

It's not clean, but you should see what's happening.

I'm using the said OrderList (currently just arrays) as a list, where queuing or stacking happens.

Stacking on top is important to this process, since sometimes, I want the AI to prioritize a Train/Build/Expo, and I see that in the future, military will use this often.

You'll see in the Zerg0 how this happens, and how it shows that even if a current order in the list isn't finished, another one can be placed on top of it. etc.

Anyway, tell me what you think could be improved.

Kernel64

System has been tested.

So far, reaction is faster, and more immediate. I may be able to provide the first version soon.

Kernel64

#41
Updated the opening post with the entire codes I'm working on right now.

It's all zerg atm, but everything can be copy-pasted for the other races. It needs to be fed with commands on what to do, when, etc., but the system is working.