• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

AI - Decisions Model

Status
Not open for further replies.
Level 7
Joined
Oct 8, 2007
Messages
154
Hi !
I wonder if it is possible to make a decissions model for AI controlled player. I mean for example to make AI know what kind of item for hero shall it buy or what research to do at certain situation. Do you posses any ideas/examples of such models in W3 modding?

http://en.wikipedia.org/wiki/Decision_model

is it maybe possible to make a Perceptron which would help AI in for example choosing what development to do ?

http://en.wikipedia.org/wiki/Perceptron

My certain usage is footy frenzy so I want to make a kind of model which would make AI decide if it shall upgrade tier, buy items for hero or upgrade units. When you write AI how do you deal with such problems ?
 
Level 7
Joined
Mar 6, 2006
Messages
282
Edit: You would absolutely need JASS, in case you were planning on doing it in GUI.

You could probably script that exactly how YOU would play the game.

When footies starts, how do you select your hero?

- Base it off what your teammates picked
- Lean more towards the OP heroes

So then script that.

- Get your teammates heroes, and do a comparison. This means you'd need pre-defined variables for every hero, and judge for yourself what hero is compatible with what, and add them to a group.

- Once you have a pool of heroes that are compatible with your teammates, let random pick a hero, but give the OP heroes (pre-defined) a higher chance at being randomed, based on how OP you judge they are.

===============================
That would be how I would write hero selection; exactly how you would play the game, just take it step by step.

Picking items would almost be the same pattern of decision making. You'll need lists of every item in the game and how relevant they are with each hero. Then, leave it up to random to decide what item to buy, granting better items with a higher chance to be randomed.

Periodicly change the relevancy of items based on a formula that has the following variables:

Current Gold, Game Time, Hero Level, and Gold Per Minute (make a simple timer to get ur gold per minute)

So let's see what would happen. A periodic timer fires that asks the AI if it should buy an item. It runs through your list, recently updated by ur gold, level, time, and gold per minute.

You have 500 gold, but its 10 minutes into the game, and you're getting gold rather slowly. The item relevancy changes to drastically prefer an item to help you get gold quickly, like a Scroll of the Beast.


========

Is this the proper way to do this? No clue, but it's logical and seems like it would work. There really is no "one answer" on how to make AI, that's what separates good and bad AI, based on how clever they are. You could make your AI WAY less complicated, but it just wouldn't perform as well, it's up to you on how much effort you wanna put into it.
 
Safe the hero's role statics in a hashtable with a integer that rates it's nuke, tank, stickyness (hard to escape) assult, evading, atk speed advantages, ect and then makes it buy items that improves that. So if it is tank, it will buy items that gives HP, HP regen, amor and some attack damage. If it's attacks stuns, cleave, steals HP and stuff then you make it buy items that gives it attack speed and movement speed. However you can't trigger the AI to reason wich item is better. You need to put items in groups based on their role and make the AI decide by using it's raitings. I'm also making AI in GUI and it is easy if you write the ITE down on paper and starting at the basics. Then you improve that step by step :)
 
Level 7
Joined
Mar 6, 2006
Messages
282
I used to write a lot of AI in GUI too, but I would always hit snags. Now that I'm learning JASS, I realized how those snags would never have occurred and I'd like to try it again, so I just said that 'JASS is required' based on my experience.

Sure, you can do it in GUI, but it's like making a mountain out of a molehill (again, totally based on how smart the AI is).
 
Level 7
Joined
Oct 8, 2007
Messages
154
Safe the hero's role statics in a hashtable with a integer that rates it's nuke, tank, stickyness (hard to escape) assult, evading, atk speed advantages, ect and then makes it buy items that improves that. So if it is tank, it will buy items that gives HP, HP regen, amor and some attack damage. If it's attacks stuns, cleave, steals HP and stuff then you make it buy items that gives it attack speed and movement speed. However you can't trigger the AI to reason wich item is better. You need to put items in groups based on their role and make the AI decide by using it's raitings. I'm also making AI in GUI and it is easy if you write the ITE down on paper and starting at the basics. Then you improve that step by step :)


I think this idea is easy and might work cool.

But I guess I have idea how to improve it.

Lets group heroes by thieir main attribue (strengh, intelligence, agility) and put types of items into 3 different arrays, some items may be contained in both. And than make an algorithm which will be like

Code:
PSEUDOCODE:

if (hero_main_attribute==strengh)
then
{
call function BuyingItemDecissionModel
}

//===================================

BuyingItemDecissionModel takes 3 arguments (Current_Amount_of_Gold , PlayerNumber, ArrayOfItems) 
returns ThingToBuy
{
if (Gold==100)
    {
     Buy Item=Potion of Healing
    }
if (Gold>=100,Gold<=300)
   {
    Improve Units damage
   }
if (Gold>=1000,Gold<=2000)
    {
    Improove Tier
    }
if (Gold>3000)
    {
     Buy Item "Epic Sword of Ethernal Destruction" 
    }
// and so on...
}

The argument "Items array" of decisions model function will be different for every attribute so it might be StrenghtItemArray, IntelligenceItemArray, AgilityItemArray

What do you think will it work ?

Another problem is that I dont have much experience in making triggers or jass programming would you help me a little how to make those arrays with both "Hero's main attribute" and "Types of items" and make it work together on an example?
 
Level 7
Joined
Oct 8, 2007
Messages
154
I highly doubt that machine learning techniques can successfully used for wc3 AI, for different reasons. But if you have more concrete ideas id like to hear them.

So my idea is shown in previous post but I dunno how to make trigger or what I would maybe prefer JASS Code doing it


JoHnyW said:
PSEUDOCODE:

if (hero_main_attribute==strengh)
then
{
call function BuyingItemDecissionModel
}

//===================================

BuyingItemDecissionModel takes 3 arguments (Current_Amount_of_Gold , PlayerNumber, ArrayOfItems)
returns ThingToBuy
{
if (Gold==100)
{
Buy Item=Potion of Healing
}
if (Gold>=100,Gold<=300)
{
Improve Units damage
}
if (Gold>=1000,Gold<=2000)
{
Improove Tier
}
if (Gold>3000)
{
Buy Item "Epic Sword of Ethernal Destruction"
}
// and so on...
}
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,258
Realistic AI can be made using a Bayesian decision tree. The idea is that each action is given a value from a Bayesian decision tree and the one with highest figure of merit is executed.

The figure of merit is generally referred to as probability although it is completely logical and has nothing to do with chance although one could add chance to a figure of merit but this generally can result in sub-optimal decisions.

These trees are often slow to evaluate or have nodes that are hard to define. As such it is often a better solution to simplify into simple conditional statements. This however gives only very basic decision capabilities that will often not factor in enough sensor input to make a good decision and is the main reason why AI suffer compared to real human intelligence.

For item purchase it seems that such a tree would be the perfect solution. You could factor in measurements like current stats, gold and current opponents to make a much more accurate item decision choice than just buying random items or items you can afford. The slow evaluation of such decision trees is meaningless since it only runs once every few minutes.

To actually get to the shop to buy items needs to be made as part of the tactical AI component. As such you will probably be better using a simple state machine to make this decision as tactical AI can evaluate multiple times a second and state machines are fast.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,258
It is not feasible to use perceptron based AI for games like WC3. The AI is too complex (needs large perceptron network) and perceptrons are too slow (especially in JASS) for it to work well in real time. Some specialist hardware, such as from intel, does allow real time perceptron use but this is not widely available enough and certainly not supported by WC3.

Some games claim to use such learning techniques for their AI but I believe that is all marketing hype. Mostly they use Bayesian networks which can also be trained by adjusting threshold values. Unlike perceptrons, it is much easier to train a Bayesian network and they are much simpler to evaluate so can be used in real time.

Bayesian networks are not an easy thing to make. They work wonders but need a lot of development behind them.
 
Level 14
Joined
Dec 12, 2012
Messages
1,007
So my idea is shown in previous post but I dunno how to make trigger or what I would maybe prefer JASS Code doing it

That has nothing to do with Machine Learning, what you posted are just if statements. You should read the links I sent you.


It is not feasible to use perceptron based AI for games like WC3. The AI is too complex (needs large perceptron network) and perceptrons are too slow (especially in JASS) for it to work well in real time. Some specialist hardware, such as from intel, does allow real time perceptron use but this is not widely available enough and certainly not supported by WC3.

It is possible to apply Neural Networks to take over specific decisions a typical AI has to perform. Here is a link which evaluates this even for Warcraft 3 (you need an IEEE Acount):

IEEE: Evolving Neural Controllers Using GA for Warcraft 3-Real Time Strategy Game

If its possible to do so in Jass is of course another question. But NNs have already been applied in several games... Backgammon's worlds best AI is a MLP which even "invented" new moves which are today used by professional backgammon players (free publication):

TD-Gammon, a Self-Teaching Backgammon Program, Achieves Master-Level Play
 
Level 14
Joined
Jun 27, 2008
Messages
1,325
There are other machine learning techniques than perceptrons, for example Bayesclassifier, gaus mixture models, support vector machines, linear discriminant analysis etc.
Im not saying that i think these models are suitable for wc3 ai, i just said im interested in the idea (well knowing that this will never be used in a wc3 map).

Also perceptrons arent thaat slot, what is really costly is the training with backpropagation (also there are newer techniques for training deep networks). But once they are trained the value retrieval is quite fast (some evaluations of sigmoidal or gaussian functions).

€: nice paper, looking_for_help :D
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,258
It is possible to apply Neural Networks to take over specific decisions a typical AI has to perform. Here is a link which evaluates this even in Warcraft 3 (you need an IEEE Acount):
Yes but these are usually have a very limited percept pool and frequency. Generally other approaches could be used to get the same results with drastically improved performance.

If its possible to do so in Jass is of course another question. But NNs have already been applied in several games... Backgammons worlds best AI is a MLP (free publication):
At what game? The paper is unclear but makes references to "board state" so I am guessing chess? If so, chess is hardly an AI challenge since the number of states and rules involved are small compared to most modern PC games. You also do not have the time constraints that RTS games have.

Chess -> 60 decisions total (about) Time limit is in the minutes.
SC2/WC3 -> >100 decisions a minute, more = better. AI with >1000 would be immune to many common strategies. Baneling bust? Split marines and micro one at a time. Enemy army attacking base? Surround individual units with your units so they cannot run.

But once they are trained the value retrieval is quite fast (some evaluations of sigmoidal or gaussian functions).
Except how often do you do that? How many inputs? How large is its internal state? How do you train the thing to start with?
 
Level 14
Joined
Dec 12, 2012
Messages
1,007
Generally other approaches could be used to get the same results with drastically improved performance.

That certainly is true. I also think the the thread opener should start with something more simple as those techniques are quite difficult and he seems to be new to AI programming.

At what game? The paper is unclear but makes references to "board state" so I am guessing chess?

For example Warcraft 3, see the first paper. There are other ones like for SC1 or some old first-person shooter I can't remember now.

Chess -> 60 decisions total (about) Time limit is in the minutes.
SC2/WC3 -> >100 decisions a minute, more = better. AI with >1000 would be immune to many common strategies. Baneling bust? Split marines and micro one at a time. Enemy army attacking base? Surround individual units with your units so they cannot run.

It is not meant that the net performs the whole AI of the game but only one very specific task, like choosing the right army mix or the right items (like described in the paper). You then could build up the AI with several modules of (different) nets, where everyone has a different task to solve.
 
Level 14
Joined
Jun 27, 2008
Messages
1,325
looking_for_help;2455911 It is not meant that the net performs the [I said:
whole[/I] AI of the game but only one very specific task, like choosing the right army mix or the right items (like described in the paper). You then could build up the AI with several modules of (different) nets, where everyone has a different task to solve.
this
 
Level 7
Joined
Oct 8, 2007
Messages
154
I was shocked :eekani: when I saw publication on IEEE Xplore about Neural Controllers Using GA for Warcraft 3 but unfortunately I'm not a member :(


for now I made a simple decission list for AI if it's hero Primary Attribute is Intelligence and made some corrections to ai script created by editor. It'd be cool if you suggest me idea how to improve both of this. The problem with buying decissions trigger is that is quite primitive, and I'm not sure if part about improving towers will work ? Troubble with AI script is that bot doesnt attack other player unless its provoked (but when it is it attacks very fiercefully :) ). One more thing I still have problem with is revieving heroes.

  • ai for intelligence type hero
    • Events
      • Unit - A unit comes within 15000.00 of Archvault 0036 <gen>
    • Conditions
      • ((Triggering unit) is A Hero) Equal to True
      • ((Owner of (Triggering unit)) controller) Equal to Computer
      • (Intelligence of (Triggering unit) (Exclude bonuses)) Greater than (Agility of (Triggering unit) (Exclude bonuses))
      • (Intelligence of (Triggering unit) (Exclude bonuses)) Greater than (Strength of (Triggering unit) (Exclude bonuses))
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Player 7 (Green) Current gold) Greater than 0
        • Then - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Player 7 (Green) Current gold) Greater than or equal to 0
              • (Player 7 (Green) Current gold) Less than 150
            • Then - Actions
              • Hero - Create Potion of Mana and give it to (Triggering unit)
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Player 7 (Green) Current gold) Greater than or equal to 150
                  • (Player 7 (Green) Current gold) Less than 250
                • Then - Actions
                  • Hero - Create Sobi Mask and give it to (Triggering unit)
                  • Player - Add -150 to Player 7 (Green) Current gold
                • Else - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (Player 7 (Green) Current gold) Greater than or equal to 250
                      • (Player 7 (Green) Current gold) Less than 300
                    • Then - Actions
                      • Unit - Order (Matching unit) to train/upgrade to a Guard Tower
                    • Else - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • (Player 7 (Green) Current gold) Greater than or equal to 300
                          • (Player 7 (Green) Current gold) Less than 365
                        • Then - Actions
                          • Unit - Order (Matching unit) to train/upgrade to a Cannon Tower
                        • Else - Actions
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • (Player 7 (Green) Current gold) Greater than or equal to 365
                              • (Player 7 (Green) Current gold) Less than 500
                            • Then - Actions
                              • Hero - Create Runed Bracers and give it to (Triggering unit)
                              • Player - Add -365 to Player 7 (Green) Current gold
                            • Else - Actions
                              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                • If - Conditions
                                  • (Player 7 (Green) Current gold) Greater than or equal to 500
                                  • (Player 7 (Green) Current gold) Less than 1050
                                • Then - Actions
                                  • Unit - Create 1 Troll High Priest for Player 7 (Green) at (Center of training camp green <gen>) facing Default building facing degrees
                                  • Player - Add -365 to Player 7 (Green) Current gold
                                • Else - Actions
                                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                    • If - Conditions
                                      • (Player 7 (Green) Current gold) Greater than or equal to 1050
                                    • Then - Actions
                                      • Unit - Order Barracks 0001 <gen> to train/upgrade to a Tree of Life
                                      • Player - Add -1050 to Player 7 (Green) Current gold
                                    • Else - Actions
                                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                        • If - Conditions
                                          • (Player 7 (Green) Current gold) Greater than or equal to 7500
                                        • Then - Actions
                                          • Hero - Create Ring of J33Bus and give it to (Triggering unit)
                                          • Player - Add -7500 to Player 7 (Green) Current gold
                                        • Else - Actions
        • Else - Actions

I'm not really sure if this will work althrough I'm not really sure what does mean "Matching Unit" I guess it's unit which matches the trigger so which can be upgraded to "guard tower" so footman etc. cant only sentry towers can

  • Else - Actions
    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      • If - Conditions
        • (Player 7 (Green) Current gold) Greater than or equal to 250
        • (Player 7 (Green) Current gold) Less than 300
      • Then - Actions
        • Unit - Order (Matching unit) to train/upgrade to a Guard Tower
      • Else - Actions
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • (Player 7 (Green) Current gold) Greater than or equal to 300
            • (Player 7 (Green) Current gold) Less than 365
          • Then - Actions
            • Unit - Order (Matching unit) to train/upgrade to a Cannon Tower
I hope it will do :D


And here's my AI script

JASS:
//***************************************************************************
// globals
//***************************************************************************

globals
    integer                 attackWave                 = 1
    integer                 nextDelay                  = 0
    integer                 awGold                     = 0
    integer                 awWood                     = 0
endglobals

//***************************************************************************
// functions
//***************************************************************************

//===========================================================================
function CheckLastCommand takes boolean pop returns integer
    local integer cmd = GetLastCommand()
    if (pop) then
        call PopLastCommand(  )
    endif
    return cmd
endfunction

//===========================================================================
function CheckLastCommandData takes boolean pop returns integer
    local integer data = GetLastData()
    if (pop) then
        call PopLastCommand(  )
    endif
    return data
endfunction

//===========================================================================
function TotalFoodProduced takes nothing returns integer
    return GetPlayerState(ai_player,PLAYER_STATE_RESOURCE_FOOD_CAP)
endfunction

//===========================================================================
function ExpansionNeeded takes nothing returns boolean
    return take_exp
endfunction

//===========================================================================
function BuildExpansion takes integer hallID, integer mineID returns nothing
    if (HallsCompleted(hallID)) then
        call SetBuildExpa( TownCount(hallID) + 1, mineID )
    endif
endfunction

//===========================================================================
function CurrentAttackWave takes nothing returns integer
    return attackWave
endfunction

//===========================================================================
function ResetAttackUnits takes nothing returns nothing
    set awGold = 0
    set awWood = 0
    call InitAssaultGroup(  )
endfunction

//===========================================================================
function AddAttackUnit takes integer minQty, integer maxQty, integer unitID returns nothing
    // Track attacking gold workers
    if (unitID == 'uaco') then
        set awGold = awGold + minQty
    endif

    // Track attacking wood workers
    if (unitID == 'nbee') then
        set awWood = awWood + minQty
    endif

    call SetAssaultGroup( minQty, maxQty, unitID )
endfunction

//***************************************************************************
// basic options
//***************************************************************************

//===========================================================================
function InitOptions takes nothing returns nothing
    call SetMeleeAI(  )
    call SetDefendPlayer( false )
    call SetRandomPaths( true )
    call SetTargetHeroes( true )
    call SetPeonsRepair( false )
    call SetHeroesFlee( true )
    call SetHeroesBuyItems( true )
    call SetUnitsFlee( false )
    call SetGroupsFlee( false )
    call SetWatchMegaTargets( true )
    call SetIgnoreInjured( false )
    call SetHeroesTakeItems( true )
    call SetSlowChopping( false )
    call SetCaptainChanges( false )
    call SetSmartArtillery( true )
endfunction

//***************************************************************************
// conditions
//***************************************************************************

//===========================================================================
// updating values
//===========================================================================
function UpdateConditions takes nothing returns nothing
endfunction

//***************************************************************************
//*
//*  Heroes
//*
//***************************************************************************

//===========================================================================
// Stores hero ID and skills
//===========================================================================
function SetHero takes integer order, integer heroid returns nothing
    if (order == 1) then
        set hero_id = heroid
        if (heroid == 'H00Q') then
            set skills1[ 1] = 'AEev'
            set skills1[ 2] = 'AOcr'
            set skills1[ 3] = 'ANr2'
            set skills1[ 4] = 'AEev'
            set skills1[ 5] = 'AOcr'
            set skills1[ 6] = 'AOww'
            set skills1[ 7] = 'ANr2'
            set skills1[ 8] = 'AEev'
            set skills1[ 9] = 'AOcr'
            set skills1[10] = 'ANr2'
        endif
    endif
endfunction

//===========================================================================
// Selects hero IDs for three possible heroes
//===========================================================================
function SelectHeroes takes nothing returns nothing
    local integer roll = GetRandomInt(1,100)
    call SetHero( 1, 'H00Q' )
endfunction

//===========================================================================
// Returns the hero skill for the given hero and level
//===========================================================================
function ChooseHeroSkill takes nothing returns integer
    local integer curHero = GetHeroId()
    local integer level = GetHeroLevelAI()

    if (level > max_hero_level) then
        set max_hero_level = level
    endif

    if (curHero == hero_id) then
        return skills1[level]
    elseif (curHero == hero_id2) then
        return skills2[level]
    elseif (curHero == hero_id3) then
        return skills3[level]
    endif
    return 0
endfunction

//***************************************************************************
//*
//*  Building and Harvesting
//* I guess somewhere around here I should put a part with upgrading Tier...
//***************************************************************************

//===========================================================================
// Specifies building priorities for workers
//===========================================================================
function BuildPriorities takes nothing returns nothing
    local integer mine = TownWithMine()
    call SetBuildAll( BUILD_UNIT, 1, 'h004', -1 )
endfunction

//===========================================================================
// Specifies harvesting priorities for workers
//===========================================================================
function HarvestPriorities takes nothing returns nothing
    local integer mine = TownWithMine()
    local integer allGold = GetUnitCountDone('uaco')
    local integer allWood = GetUnitCountDone('nbee')
    local integer numWorkers
endfunction

//===========================================================================
// Determines all building and harvesting assignments for workers
//===========================================================================
function WorkerAssignment takes nothing returns nothing
    loop
        call UpdateConditions(  )

        // Harvesting
        call ClearHarvestAI(  )
        call HarvestPriorities(  )

        // Building
        call InitBuildArray(  )
        call BuildPriorities(  )

        call Sleep( 2 )
    endloop
endfunction

//***************************************************************************

//***************************************************************************

//===========================================================================
// Returns true if the minimum forces for an attack exist
//===========================================================================
function HaveMinimumAttackers takes nothing returns boolean
    local integer count

    // Check for attack wave limit
    if (attackWave > 1) then
        return true
    endif

    // First Hero Only
    if (GetUnitCountDone(hero_id) < 1) then
        return false
    endif

    return true
endfunction

//===========================================================================
// Assigns units to attack based on the given attack group
//===========================================================================
function PrepareAttackGroup takes integer groupID returns nothing
    local integer all

    // Attack Group #1: All Units
    if (groupID == 1) then
        set all = GetUnitCountDone( hero_id )
        call AddAttackUnit( all, all, hero_id )
        set all = GetUnitCountDone( hero_id2 )
        call AddAttackUnit( all, all, hero_id2 )
        set all = GetUnitCountDone( hero_id3 )
        call AddAttackUnit( all, all, hero_id3 )
        set all = GetUnitCountDone( 'hdhw' )
        call AddAttackUnit( all, all, 'hdhw' )
        set all = GetUnitCountDone( 'hfoo' )
        call AddAttackUnit( all, all, 'hfoo' )
        set all = GetUnitCountDone( 'hgry' )
        call AddAttackUnit( all, all, 'hgry' )
        set all = GetUnitCountDone( 'hgyr' )
        call AddAttackUnit( all, all, 'hgyr' )
        set all = GetUnitCountDone( 'hkni' )
        call AddAttackUnit( all, all, 'hkni' )
        set all = GetUnitCountDone( 'hmpr' )
        call AddAttackUnit( all, all, 'hmpr' )
        set all = GetUnitCountDone( 'hmtm' )
        call AddAttackUnit( all, all, 'hmtm' )
        set all = GetUnitCountDone( 'hmtt' )
        call AddAttackUnit( all, all, 'hmtt' )
        set all = GetUnitCountDone( 'hrif' )
        call AddAttackUnit( all, all, 'hrif' )
        set all = GetUnitCountDone( 'hsor' )
        call AddAttackUnit( all, all, 'hsor' )
        set all = GetUnitCountDone( 'hspt' )
        call AddAttackUnit( all, all, 'hspt' )

        // Attack Group #2: footmen solo
    elseif (groupID == 2) then
        set all = GetUnitCountDone( 'hfoo' )
        call AddAttackUnit( all, all, 'hfoo' )

    endif
endfunction

//===========================================================================
// Prepares an attack group based on the current attack wave
//===========================================================================
function PrepareForces takes nothing returns nothing
    if (attackWave == 1) then
        call PrepareAttackGroup( 2 )
    endif
endfunction

//===========================================================================
// Sleep delays for each attack wave
//===========================================================================
function AttackWaveDelay takes integer inWave returns nothing
    if (inWave < nextDelay) then
        return
    endif

    set nextDelay = inWave + 1
endfunction

//===========================================================================
// Advances attack wave counter
//===========================================================================
function AttackWaveUpdate takes nothing returns nothing
    call AttackWaveDelay( attackWave )
    set attackWave = attackWave + 1
    if (attackWave > 1) then
        set attackWave = 1
        set nextDelay = attackWave + 1
    endif
endfunction

//===========================================================================
// Basic attack functionality
//===========================================================================
function AttackTarget takes unit target, boolean addAlliance returns nothing
    if (target == null) then
        return
    endif
    if (addAlliance) then
        call SetAllianceTarget( target )
    endif
    call FormGroup( 3, true )
    call AttackMoveKillA( target )
    if (not addAlliance) then
        call SetAllianceTarget( null )
    endif
endfunction

//===========================================================================
// Initiates an attack based on target priorities
//===========================================================================
function LaunchAttack takes nothing returns nothing
    local unit target = null
    local boolean setAlly = true

    // I think offence is the best way of defending Threatend town :D
    if (TownThreatened()) then
        set target = GetMegaTarget()
        return
    endif

    // Target Priority #1
    if (target == null) then
        set target = GetMegaTarget()
    endif

    // Target Priority #2
    if (target == null) then
        set target = GetAllianceTarget()
        if (target != null) then
            set setAlly = false
        endif
    endif

    // Target Priority #3
    if (target == null) then
        set target = GetExpansionFoe()
        if (target != null) then
            set take_exp = false
        endif
    endif

    // Target Priority #4
    if (target == null) then
        set target = GetMegaTarget()
    endif

    // Target Priority #5
    if (target == null) then
        set target = GetEnemyExpansion()
    endif

    // Target Priority #6
    if (target == null) then
        set target = GetEnemyExpansion()
        if (target == null) then
            call StartGetEnemyBase(  )
            loop
                exitwhen (not WaitGetEnemyBase())
                call SuicideSleep( 1 )
            endloop
            set target = GetEnemyBase()
        endif
    endif

    // Target Priority #7 theres no creeps we attack enemy
    if (target == null) then
        set target = GetEnemyBase()
    endif

    // Target Priority #8
    if (target == null) then
         set target = GetEnemyBase()
    endif

    // Attack the target and increment attack wave
    if (target != null) then
        call AttackTarget( target, setAlly )
        call AttackWaveUpdate(  )
    else
        // if theres no other target attack enemy base
        set target = GetEnemyBase()
    endif
endfunction

//===========================================================================
// Determines all attacking assignments
//===========================================================================
function AttackAssignment takes nothing returns nothing
    call StaggerSleep( 0, 2 )
    if (attackWave == 1) then
        call AttackWaveDelay( 0 )
    endif
    loop
        loop
            call UpdateConditions(  )
            exitwhen (HaveMinimumAttackers() and not CaptainRetreating())
            call Sleep( 2 )
        endloop
        call RemoveInjuries(  )
        call ResetAttackUnits(  )
        call PrepareForces(  )
        call LaunchAttack(  )
    endloop
endfunction

//***************************************************************************
//*
//*  Main Entry Point
//*
//***************************************************************************

//===========================================================================
function main takes nothing returns nothing
    call InitAI(  )
    call SetPlayerName( ai_player, "ProjektSI Footy Frenzy2" )
    call InitOptions(  )
    call SelectHeroes(  )
    call CreateCaptains(  )
    call SetHeroLevels( function ChooseHeroSkill )

    call Sleep( 0.1 )
    call StartThread( function WorkerAssignment )
    call StartThread( function AttackAssignment )
    call PlayGame(  )
endfunction

Edit :


Hmmm when I place inteligence hero for player green at beggining of game things are worse than I thought ! At the beggining of game Tier of computer is changed to Tree of Life, he doesnt buy hero because he doesnt have required money, but maybe if hero wouldnt be placed but bought in game all things would work what do ya think ?
 
Last edited:

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,258
The item decision tree is nonsense.

You should break his gold into 2 pools.
1. Upgrades and units
2. Items and consumables

All gold earned is divided into these 2 sections. These sections are then spent separately when applicable. The weight of spending gold increases as the total gold in all sections increases. This means he will only shop when he has some gold to burn.

Upgrade gold is spent purely on upgrades. Which upgrade it is spent on has its own decision logic. Upgrades come before unit since upgrades are permanent while units generally are not, however this will probably be reflected in your weighting.

Item gold is spent purely on items. Like upgrades, this has its own decision logic. The hero should probably save 1-2 slots for consumables early game and replenish them priority on each shop visit. It should then focus at populating inventory with basic items to improve overall hero utilization. The items chosen are based on prime attribute and roll. Once all inventory is full it starts to save up for expensive items as "upgrades". After some time it dumps the consumable items (when they no longer are of much use) and starts investing in more items to replace them. Once the hero is fully equipped with "best" gear (highest weighted gear), it then transfers all item money into units and upgrades.

Units and upgrades could be split if units are important early game. This insures the AI will always invest in units and save for upgrades at the same time. You can adjust the income split depending on hero, randomness or anything really. A support hero might want to focus on upgrades and units more than his items so invest heavily in that. A DPS/assassin hero might want to focus items more than upgrades so invest more heavily there.

Yes breaking a single resource pool into separate reserved pools is a real AI strategy used by many RTS games. Most famous of which is Supreme Commander 2 which has pretty high end AI for such an under-played and under-ratted game.
 
Status
Not open for further replies.
Top