Main Menu
Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - imbalisk

#1
AI Development / Re: Help With Functions
March 05, 2010, 12:08:44 PM
So lets see how the AI work to see your mistakes.
The computer will give every AI a timeslot, in which the AI functions are computed. Some functions will be called like every 1 secound or less. This means, this function is called every secound (0.5sec, 0.2 sec, dont know)

void AIMeleeProt (int player) {   
    int mainState = AIState(player, e_mainState);


    if (mainState == e_mainState_Init)              { ProtossInit(player);     }


    else if (mainState == e_mainState_OpenGnd0)     { ProtossOpenGnd0(player); }
    //else if (mainState == e_mainState_OpenGnd1)     { ProtossOpenGnd1(player); }
}

you may add a TriggerDebugOutput( ... ) in ths function to see when it's called.
The state of the AI can be set via the
void AISetMainState (int player, int mainState, int mainSubState) function, this function is called within AIMeleeInit to set the state of all AIs to 1 ( = e_mainState_Init ) so that when the AIMelee[race] (int player) function is called, [race]Init(player) is called.
That means: If the AI is Protoss, the Inintial state is 1, when the AIMeleeProt(int player) is called the first time, it will call ProtossInit(player)


ProtossInit(player) chooses an opening for the Protoss:


if (AIGetGroundStartLocs(PlayerStartLocation(player)) > 0) {
state = AIDiffEnum(player, e_mainState_OpenGnd0);
}
else {
        state = AIDiffEnum(player, e_mainState_OpenAir0);
    }
    AISetMainState(player, state, e_mainSubState_Unset);

Read it like that: If there are only island start positions, choose an air unit opening( like Void Rays), else set state to e_mainState_OpenGnd0.


So, in the nex secound, AIMeleeProt is called again, now the state is not longer e_mainState_Init, it is e_mainState_OpenGnd0 (cause we are not on an island map :) ), now the function ProtossOpenGnd0 is called, there is where most of the players put their Openings :).


You may also only want the AI only make your builds and behaviour, to make this, add

void AIMeleeProt (int player) {   
        one(player)


}

Yeah, thats enough, your AI do not longer work with states. That sux, but this will work.
Why is your AI not working?




//-----------------------------------------------------------------------------------
// AIMeleeProt
//-----------------------------------------------------------------------------------

void AIMeleeProt (int player) {
  int mainState = AIState(player, e_mainState);
  if (mainState == e_mainState_Init) { ProtossInit(player); }
  One(player);
  Twoplayer);
  Three(player);
}

You call all 3 functions after each other and dont make a decision which function you want to call. So when one( ) is called, it sets stock to 8probes. Now the AI tries to have 8 probes.
Then you call two() and clear the stock. The AI is not longer trying to make probes. It tries to makes an assimimator and an pylon, but only if it has 8 probes. But you cleared the stock, it will never try to make 8 probes.


You should take a deeper look into the ProtossOpenGnd0 function to see what it does, here is a version of my opening as P:


void ProtossOpenGnd0(int player) {
    AIClearStock(player);
    AISetGasPeonCountOverride(player, c_townMain, 6);


AISetFlag(player, e_flagsScouting, false);
    AISetFlag(player, e_flagsEarlyDefScout, false);


    if(AIGetTime() > 150 - AIGetUserInt (player, 100))
    {
AISetFlag(player, e_flagsScouting, true);
    }


     // Protoss opening v3.1 by imbalisk
    AISetStock( player, 1, c_PB_Nexus );
    AISetStock( player, 9, c_PU_Probe );
    AISetStock( player, 1, c_PB_Pylon );
    AISetStock( player, 11, c_PU_Probe );
    AISetStock( player, 1, c_PB_Gateway  );
    AISetStock( player, 13, c_PU_Probe );
    AISetStock( player, 2, c_PB_Gateway  );
    AISetStock( player, 15, c_PU_Probe );
    AISetStock( player, 2, c_PB_Pylon );
    AISetStock( player, 5, c_PU_Zealot );
    AISetStock( player, 4, c_PB_Pylon );
    AISetStock( player, 1, c_PB_Assimilator );
    AISetStock( player, 1, c_PB_CyberneticsCore );
    AISetStock( player, 1, c_PR_ZealotCharge);
   
    // around 100 resources in about 2 units
    AISetStock( player, 16, c_PU_Zealot );
    AISetStock( player, 6, c_PU_Stalker );
    ProtossTechUp(player, 1);
   
if (AIEnableVeryEasyStockOpen(player, c_PU_Probe)) {
return;
}


}

Ignore the AISetStock for a moment, whats most important is the AIEnableVeryEasyStockOpen(player, c_PU_Probe), since this will call a function in MeleeNotHard.galaxy, the AIEnableVeryEasyStockOpen.
Look at this:


bool AIEnableVeryEasyStockOpen (int player, string peonType) {
    return AIEnableStockOpen(player, peonType, 350, false, e_mainState_Mid0);
}

and

static bool AIEnableStockOpen (int player, string peonType, int time, bool veryEasy, int nextState) {
    AIEnableStock(player);


    if (AIGetTime() < time) {
        return true;
    }
    AIGenericStock(player, nextState, e_mainSubState_GndA);
    return false;
}

AIEnableStock tells the AI: ok, you can start building things that are on your Stock (i.e. try to make pylons or probes), if the time (here: 350 sec, because AiEnableVeryEasyStockOpen calls this function with 350 as parameter!) is over, launch an attack, AND SET NEXT STATE to e_mainSubState_GndA.
Next time AIMeleeProt is called (it was called like 350 times and always executed ProtossOpenGnd0) it will execute ProtossMidGndA, cause the state was set to e_mainState_Mid0.
So, in order to make a working AI, either overwrite ProtossOpenGnd0 and overwrite ProtossMidGndA and so on, and also change the EnableStockOpen functions, or make an AI like the guy who wrote the protoss AI.
#2
Try the AIFindUnits just like in the QueenAI:
hatcheries = AIFindUnits(player,                              c_ZB_Hatchery_Alias,
                             UnitGetPosition(aiUnit),
                             15,
                             c_noMaxCount)

                             ;

like this:


unitgroup gateways;
gateways = AIFindUnits(player,                        c_PB_Gateway ,
                       UnitGetPosition(aiUnit),
                       15, // or more, thats the range
                       c_noMaxCount)

                       ;
forges = AIFindUnits(player,
                           c_PB_Forge,
                           15,
                           c_noMaxCount)
                           ;

and try to find out if the gates are producing something (dont boost non building structures) or researches sth (dont boost forge if it doesn't produce).
Still don't know how to do this :)
#3
Quote from: Kernel64 on March 04, 2010, 08:38:56 AM
Quote from: Yuna_Q on March 04, 2010, 08:16:15 AM
queen related functions at tactzergai.galaxy

Okay, I found the functions. But, Yuna_Q, I want to find the codes that call these functions.

You see, I want to use this as template for making ChronoBoost. The one discovered doesn't work.


Seems like you want to add ChronoBoost, try this:
In UnitData.xml you can find this:
<TacticalAIThink value="AIThinkQueen"/>
The function calls for the AIThink functions are hardcoded, if the AI has a queen or more, it searches for a TacticalAIThink value, if it finds one, it calls this the function AIThinkQueen.
As I mentioned in my LOOOOOOOOOOOOOOONG post in this other thread, you need to add a <TacticalAIThink value="AIThinkNexus"/> for the Nexus inside the UnitData.xml and create a AIThinkNexus function inside the TacticalThinkProtoss galaxy file that calls the ChronoBoost function.


In order to improve the AI of the queen, you can change transfusion function


order Transfusion (int player, unit aiUnit) {
    order ord;
    unitgroup group;
    aifilter filter;


    ord = AICreateOrder(player, c_AB_Transfusion, 0);
    if (!UnitOrderIsValid(aiUnit, ord)) {
        return null;
    }


    group = AIFindUnits(player, null, UnitGetPosition(aiUnit),
                        AIAbilityFixed(player, c_AB_Transfusion, c_fieldRange0) + 1,
                        c_noMaxCount)
    ;


    filter = AIFilter(player);
    AISetFilterAlliance(filter, c_playerGroupAlly);
    AISetFilterLifeLost(filter, AIEffectFixed(player, c_EF_Transfusion, c_fieldEffectChange0), c_noMax);
    group = AIGetFilterGroup(filter, group);


    return AIUnitGroupGetValidOrder(group, ord, aiUnit, c_forwards);
}


//--------------------------------------------------------------------------------------------------
order SpawnLarva (int player, unit aiUnit) {
    order ord;
    unitgroup hatcheries;
    int larvaCount;


    //  Only cast if idle.
    //
    if (UnitOrder(aiUnit, 0) != null) {
        return null;
    }


    ord = AICreateOrder(player, c_AB_SpawnMutantLarva, 0);
    if (!UnitOrderIsValid(aiUnit, ord)) {
        return null;
    }


    //  Don't cast if we already own at least 10 larva
    //
    larvaCount =
        TechTreeBehaviorCount(player, c_BF_MutantLarvaTimer, c_techCountQueuedOrBetter) * 4
      + TechTreeUnitCount(player, c_ZU_Larva, c_techCountQueuedOrBetter)
    ;
    if (larvaCount >= 10) {
        return null;
    }


    hatcheries = AIFindUnits(player,
                             c_ZB_Hatchery_Alias,
                             UnitGetPosition(aiUnit),
                             15,
                             c_noMaxCount)
                             ;
    return AIUnitGroupGetValidOrder(hatcheries, ord, aiUnit, c_backwards);
}

and code as the position for the search of the hatcheries the expansion point (overwrite UnitGetPosition(aiUnit) to the expansion point) when AI have more then 1 queen.
#4
Quote from: itsarabbit on March 03, 2010, 05:10:36 PM
I believe most of them don't use c++(or is that just an extremely similar language?), but if it's possible to implement it, it might prove useful :)
This is written in the galaxy language
#5
Hey guys.


I've been playing SC1 since 2004 and I'm also interested in coding, so lets see if I can help the coders with some cool scripts to improve the AI :)


In Starcraft 1 I choose my build order or general gameplan based on the situation: is it a 1v1 or a 3v3? Or even a FFA?
When its a 1v1, what race I am playing against?
Wouldn't it be cool if the AI make the same decisions like a REAL (clever) player?
Here is the script:


First of all, we want to know how many players are in the game. I've tried AIGetNumEnemies (player); but it didn't work (returned a constant 13 no matter how much players are in). Here is the code of a working AI that analyze the game situation:



static void ProtossInit (int player) {
        ...   
   int numberOfPlayers = 0;
   string s = null;
   int i = 1;
   int enemyID;
   
   // Counting the players   
   while(i<=8){ // Asuming that blizzard has a maximum of 8 players
      s = PlayerRace(i); // getting a "Terr", "Zerg", "Prot" if this ID is used
      if(s != null) {  // otherwise a null if there is no player
          numberOfPlayers = numberOfPlayers + 1;
      }
      i = i + 1;
   }
   if(numberOfPlayers == 2) {
          // Lets find out our opponents playerID. It can't be our ID:
      if(player == 1) { // is my ID == 1?
         enemyID = 2;
      }
      else { // ok, my ID is 2
         enemyID = 1;
      }
      TriggerDebugOutput(1, StringToText("1v1 Mode vs " + PlayerRace(enemyID) ), true);
                 // add a state setting code here
                 // example: state = e_mainState_OpenGnd0; if you want to execute the ProtossOpenGnd0
   }
   else {
      TriggerDebugOutput(1, StringToText("FFA Mode vs " +               IntToString(numberOfPlayers-1)), true);

                // add a state setting code here
                // example: state = e_mainState_OpenGnd1; whatever
   }

Lets say AI is protoss and this script tells him that are 2 players in the game (1v1 baby) and PlayerRace(enemyID) == "Terr".
We can choose an opening that is good against Terran, lets say a Stalker into Immortal build.
If it's a FFA we could ajust our build so that if the AI is attacking, we make some defense, cause nobody likes an attack from player 3 when we attack player 2. Well thats what happens in FFA :)


Hope that helps a little bit, pls give me credit if you use that in your own AI.
- imbalisk
edit:
thx @ sYkO for providing this nice 1v1 obsmaps
#7
Quote from: Kernel64 on March 03, 2010, 01:21:49 AM
Also, have you looked at Chrono Boost?

I'm guessing these are run much like how the race0.galaxy are.

edit:

Other Units have their Think. Have you tried using this with your code? <-- this is crazy. Your code is about the Think. Sorry.
Chrono Boost cant be found in all of this files, it was added short before Beta came out, I think thats the reason its not implemented yet.
But because you can use it in the game, it has to be there, there is just no AI script triggering it.
Look at AbilData.xml:
<CAbilEffectTarget id="TimeWarp">
        <EditorCategories value="AbilityorEffectType:Units,Race:Terran"/>
        <Cost>
            <Vital index="Energy" value="25"/>
        </Cost>
        <TargetFilters value="-;Neutral,Enemy,Missile,Stasis,Dead,Hidden,Invulnerable"/>
        <Range value="500"/>
        <Arc value="360"/>
        <CmdButtonArray index="Execute" DefaultButtonFace="TimeWarp"/>
        <UninterruptibleArray index="Approach" value="1"/>
        <UninterruptibleArray index="Prep" value="1"/>
        <UninterruptibleArray index="Cast" value="1"/>
        <UninterruptibleArray index="Channel" value="1"/>
        <UninterruptibleArray index="Finish" value="1"/>
        <Effect index="0" value="TimeWarpSet"/>
        <AINotifyEffect value="TimeWarpProduction"/>
    </CAbilEffectTarget>

Chrono Boost takes 25 Energy, maybe it is called TimeWarp in the AI and called ChronoBoost in the game?
I think a way to activate it is to add a AIThinkNexus function into the game:
In the UnitData.xml this can be found:
<TacticalAIThink value="AIThinkHighTemplar"/>
I think this is a reference to the AI data stored in TactProt.galaxy file.
In order to make the Nexus cast this new spell we have to implement a function like AIThinkGateway
void AIThinkGateway (int player, unit aiUnit, unitgroup scanGroup) {
DebugVarInt("GGaTTee", 0);
    order ord;
   
    if (AIEvalTacticalData(aiUnit, null)) {
        return;
    }


    if (AITechCount(player, c_PR_WarpGateResearch, c_techCountCompleteOnly) == 0) {
        return;
    }


    AISetWantsToUpgrade(aiUnit);


    ord = AICreateOrder(player, c_AB_UpgradeToWarpGate, 0);
    if (!UnitOrderIsValid(aiUnit, ord)) {
        return;
    }
   
    AICast(aiUnit, ord, c_noMarker, c_castHold);
}

with calls on the ChronoBoost / TimeWarp function on the nexus itself (for testing, later on gates or forges to speed up research... dunno :) )


However the difficulty is this:
ord = AICreateOrder(player, c_AB_UpgradeToWarpGate, 0);


c_AB_UpgradeToWarpGate is defined in RequirementsAI.galaxy:


const string c_AB_UpgradeToWarpGate         = "UpgradeToWarpGate";
There is no const string c_AB_TimeWarp or c_AB_ChronoBoost, I think it might work with just calling ord = AICreateOrder(player, "TimeWarp", 0); in the Nexus AI script.


However, the reason I write this down and dont test it is because I rage everytime I start SC2 and the AI just down spawn because there is a F***ing bug in my script.


I can't even get an output like "AI Gateway script is called" cause when i put a TriggerOutput function call within the AIThinkGateway function the programm just down't work as mentioned above.


Maybe someone take a look at this, implementing the use of new abilities, like ChronoBoost would make the AI much harder :)

#8
AI Discussion / Re: DISCUSS AI v 4.0
February 28, 2010, 06:27:46 PM
Quote from: jawknee530 on February 28, 2010, 06:17:05 PM
Is there any sort of schedule that is trying to be kept by the creator(s) or an ETA on the next AI. Me and my room mates are eagerly awaiting updates of games getting steadily more difficult.
With more feedback we can make changes more quick since we will know what to fix :D
#9
AI Discussion / Re: DISCUSS AI v 4.0
February 28, 2010, 04:11:21 PM
Quote from: GurU on February 28, 2010, 03:45:48 PM
First of all THANK YOU VERY MUCH FOR YOUR WORK !


And now some bitter words.

I played few games on Lost Temple 1/1/1/1 and noticed that :

- all my protoss oponents build 2x warp shrines what is nonsens !
- the expansion still have no protecting units. Only 1 or 2 canons
- AI make only 1 expansion
- AI make only one army and if this army get crushed he won't build another
- zerg dies instantly after 5 minutes :/ (killed by AI)
- I never played against Terran xD (after 3 or 4 games)
-as I lifted off command center and moved on the island AI wasn't able to charm me


That is all for now



OveR
You're right, currently we only have one Opening implemented, which is 2 gate Zealots as Protoss. More openings and midgame styles will be released at the next version.
We try to make a midgame army that is possible to attack islands, but henche, there is no "HumanBuildsOnIsland" scripted, so we have to figure out how to deal with that. But great point.
#10
AI Discussion / DISCUSS AI v 4.0
February 28, 2010, 03:29:00 PM

Note: This thread is for discussing the NON-CHEATING AI of our current version 4.0

Please give us some feedback to the AI:
Is it too hard?
Easy to beat?
What are the weaknesses, what do you want to be changed?
Currently we try to implement more builds to have more variations in the game :)