DarkBlizz

Game On => Land of AI => STARCRAFT II: WINGS OF LIBERTY => AI Scripts => Topic started by: SuXue on March 13, 2010, 02:42:28 PM

Title: Fixing three issues of Starcrack v6.1.1
Post by: SuXue on March 13, 2010, 02:42:28 PM
I watched multiple games of AI fighting each other, spotted quite some issues, felt like programming, and wrote some codes  :)

0) This solves the dread "kiting" issue... With it the AI will defend itself much better, especially in early stages:


void AIWaveThinkDefault (int player, wave w, int type) {

      point pHome = AIGetTownLocation(player, c_townMain);
    int pDist;
    int pDistMax = 9999999;
    int i = 1;
    unit u;
   
    if (AIWaveUnitCount(w) < 1)
    {
        return;
    }
   
      while(i <= AIWaveUnitCount(w))
       {
         u = UnitGroupUnit(AIWaveGetUnits(w),i);
         pDist = FixedToInt(DistanceBetweenPoints(pHome, UnitGetPosition(u)));
     
      //* retreat idle groups when far away from base *
      if (AIWaveGetTimeInCombat(w) == 0)
      {
        pDistMax = 32;
      }
      else
      {
        pDistMax = 38;
      }
         if ((pDist >= pDistMax) && (type == c_waveMain))
         {
        if ( (AIWaveState(w) == c_waveStateIdle) || (AIWaveState(w) == c_waveStateDefend) )
        {
          AIWaveSetType(w, c_waveStateRetreat, AIWaveTargetGatherO(player, c_townMain));
            return;
           }
         }
      i = i + 1;
      }
   
    if (type == c_waveMain) {
        AIWaveMain(player, w);
    }
    else if (type == c_waveDefend) {
        AIWaveDefend(player, w);
    }
    else if (type == c_waveAttack) {
        AIWaveAttack(player, w);
    }
    else if (type == c_waveDivert1) {
        AIWaveDivert(player, w, e_divert1State);
    }
    else if (type == c_waveDivert2) {
        AIWaveDivert(player, w, e_divert2State);
    }
    else if (type == c_waveClearObs) {
        AIWaveClearObs(player, w);
    }
    else if (type == c_waveHome) {
        AIWaveHome(player, w);
    }
}


1) The AI is not building supplies quickly enough after the middle stage of the game... After this fix one will see the AI developing faster:


void AIManageSupply (int player)
{
    string supplyType;
    string p_race = PlayerRace(player);
   
    int supply_made = PlayerGetPropertyInt(player, c_playerPropSuppliesMade);
    int supply_gap = supply_made / 9;
    if (supply_gap < 5)
    {
      supply_gap = 5;
    }
   
    if(p_race == "Terr")
    {
        supplyType = c_TB_SupplyDepot_Alias;
    }
    else if(p_race == "Prot")
    {
        supplyType = c_PB_Pylon;
    }
    else if(p_race == "Zerg")
    {
        supplyType = c_ZU_Overlord_Alias;
    }
   
    if ( (PlayerGetPropertyInt( player, c_playerPropSuppliesUsed ) >= PlayerGetPropertyInt( player, c_playerPropSuppliesMade ) - supply_gap )
        && (AITechCount ( player, supplyType, c_techCountIncompleteOnly ) == 0 ))
    {
        AISetStockUnitNext( player, AITechCount( player, supplyType, c_techCountCompleteOnly ) + 1, supplyType, c_stockAlways);
    }
}


2) The Peon management code is bugged. After this fix the AI will build more workers and use them much more effectively:


void AIBalancePeons(int player)
{
    int a = 0;
    int gas = PlayerGetPropertyInt(player, c_playerPropVespene);
    int minerals = PlayerGetPropertyInt(player, c_playerPropMinerals);
    int totalTowns = AIGetTotalTowns(player);
    int nRefinery = 0;

    int gcount = 0;
    int totalPeons = 0;
    int needPeons = 0;
    int gasPeons = 0;
    string refine;
    string worker;
    string mbase;
    string p_race = PlayerRace(player);

    if(p_race == "Terr")
    {
        refine = "Refinery";
        worker = "SCV";
        mbase = c_TB_CommandCenter_Alias;
    }
    else if(p_race == "Prot")
  {
        refine = "Assimilator";
        worker = "Probe";
        mbase = c_PB_Nexus;
  }
  else if(p_race == "Zerg")
  {
        worker = "Drone";
        refine = "Extractor";
        mbase = c_ZB_Hatchery_Alias;
  }
 
  a = 0;
    while(a != 8 )
    {
    gasPeons = 0;
        if (AIGetTownState(player, a) == c_townStateEstablished)
        {
      nRefinery = AIGetBuildingCountInTown(player, a, refine, c_techCountCompleteOnly);
          if(AIGetCurPeonCount(player, a) > 12)
            {
                AISetStockEx (player, a, 2, refine, c_makeCollector, 0);
        if (gas > minerals + 1200)
              {
                gasPeons = 0;
              }
        else if (gas > minerals + 900)
              {
                gasPeons = 1;
              }
        else if (gas > minerals + 600)
              {
                gasPeons = 2;
              }
              else if (gas > minerals + 300)
              {
                gasPeons = 3;
              }
              else
              {
                gasPeons = 3 * nRefinery;
              }
            }
            else if(AIGetCurPeonCount(player, a) > 6)
            {
                AISetStockEx (player, a, 1, refine, c_makeCollector, 0);
                gasPeons = 3;
            }
            else
            {
                gasPeons = 0;
            }
        }
        AISetGasPeonCountOverride(player, a, gasPeons);
        a = a + 1;
    }

    //making zerg spam hatchs
    //AISetStockUnitNext(player, totalTowns, mbase ,c_stockIdle);
   
    // build peons
  totalPeons = AITechCount (player, worker, c_techCountCompleteOnly);
    if(p_race == "Zerg")
    {
            needPeons = totalTowns * 28;
    }
    else
    {
            needPeons = totalTowns * 33;
    }
    if (needPeons > 90)
    {
        needPeons = 90;
    }
    if (needPeons < totalPeons)
    {
        needPeons = totalPeons;
    }
    AISetStockUnitNext(player, needPeons, worker, c_stockAlways);
}
Title: Re: Fixing three issues of Starcrack v6.1.1
Post by: Ninja1017 on March 13, 2010, 03:01:39 PM
you should up the pre-made file for this
Title: Re: Fixing three issues of Starcrack v6.1.1
Post by: Myst on March 13, 2010, 03:05:25 PM
and used [ code ] [ /code ] tags  :P
Title: Re: Fixing three issues of Starcrack v6.1.1
Post by: GooseBoy on March 13, 2010, 07:38:10 PM
implement now, gogogo!
Title: Re: Fixing three issues of Starcrack v6.1.1
Post by: godspiral on March 13, 2010, 09:50:02 PM
The first 2 are interesting.  I hope they're good, but I can't tell just looking.

The gas one I disagree with.  First, it should only ever consider removing gas workers if there are fewer than 2 per patch on minerals (18 usually).  Even then, it should focus on spending gas unless it has one base and is struggling to replace dead mineral workers.  Also, 3 workers on gas saturates it on every map released so far.
Title: Re: Fixing three issues of Starcrack v6.1.1
Post by: SuXue on March 14, 2010, 02:36:45 AM
Quote from: godspiral on March 13, 2010, 09:50:02 PM
The first 2 are interesting.  I hope they're good, but I can't tell just looking.

The gas one I disagree with.  First, it should only ever consider removing gas workers if there are fewer than 2 per patch on minerals (18 usually).  Even then, it should focus on spending gas unless it has one base and is struggling to replace dead mineral workers.  Also, 3 workers on gas saturates it on every map released so far.

I have found the AI with 500+ gas and 100- minerals multiple times, especially during Terran opening stages... there is no way to spend these gas with such limited minerals
Title: Re: Fixing three issues of Starcrack v6.1.1
Post by: Xest on March 14, 2010, 04:53:16 AM
I fixed up your code (removed some redundant stuffs and organized it) to be read/pushed into the GIT.

void AIWaveThinkDefault (int player, wave w, int type)
{
    point pHome = AIGetTownLocation(player, c_townMain);
    int pDist;
    int pDistMax;
    int i = 1;
    unit u;

    if (AIWaveUnitCount(w) < 1)
    {
        return;
    }
    while(i <= AIWaveUnitCount(w))
    {
      u = UnitGroupUnit(AIWaveGetUnits(w),i);
      pDist = FixedToInt(DistanceBetweenPoints(pHome, UnitGetPosition(u)));
      //retreat idle groups when far away from base
      if (AIWaveGetTimeInCombat(w) == 0)
      {
        pDistMax = 32;
      }
      else
      {
        pDistMax = 38;
      }
      if ((pDist >= pDistMax) && (type == c_waveMain))
      {
        if ( (AIWaveState(w) == c_waveStateIdle) || (AIWaveState(w) == c_waveStateDefend) )
        {
          AIWaveSetType(w, c_waveStateRetreat, AIWaveTargetGatherO(player, c_townMain));
          return;
        }
      }
      i = i + 1;
    }
   
    if (type == c_waveMain) {
        AIWaveMain(player, w);
    }
    else if (type == c_waveDefend) {
        AIWaveDefend(player, w);
    }
    else if (type == c_waveAttack) {
        AIWaveAttack(player, w);
    }
    else if (type == c_waveDivert1) {
        AIWaveDivert(player, w, e_divert1State);
    }
    else if (type == c_waveDivert2) {
        AIWaveDivert(player, w, e_divert2State);
    }
    else if (type == c_waveClearObs) {
        AIWaveClearObs(player, w);
    }
    else if (type == c_waveHome) {
        AIWaveHome(player, w);
    }
}

void AIManageSupply (int player)
{
    string supplyType;
    string p_race = PlayerRace(player);
   
    int supply_made = PlayerGetPropertyInt(player, c_playerPropSuppliesMade);
    int supply_gap = supply_made / 9;
    if (supply_gap < 5)
    {
      supply_gap = 5;
    }
   
    if(p_race == "Terr")
    {
        supplyType = c_TB_SupplyDepot_Alias;
    }
    else if(p_race == "Prot")
    {
        supplyType = c_PB_Pylon;
    }
    else if(p_race == "Zerg")
    {
        supplyType = c_ZU_Overlord_Alias;
    }
   
    if ( (PlayerGetPropertyInt( player, c_playerPropSuppliesUsed ) >= supply_made - supply_gap )
        && (AITechCount ( player, supplyType, c_techCountIncompleteOnly ) == 0 ))
    {
        AISetStockUnitNext( player, AITechCount( player, supplyType, c_techCountCompleteOnly ) + 1, supplyType, c_stockAlways);
    }
}

void AIBalancePeons(int player)
{
  int a = 0;
  int gas = PlayerGetPropertyInt(player, c_playerPropVespene);
  int minerals = PlayerGetPropertyInt(player, c_playerPropMinerals);
  int totalTowns = AIGetTotalTowns(player);
  int nRefinery = 0;
  int needPeons = 0;
  int gasPeons;
  string refine;
  string worker;
  string mbase;
  string p_race = PlayerRace(player);
  if(p_race == "Terr")
  {
    refine = "Refinery";
    worker = "SCV";
    mbase = c_TB_CommandCenter_Alias;
  }
  else if(p_race == "Prot")
  {
    refine = "Assimilator";
    worker = "Probe";
    mbase = c_PB_Nexus;
  }
  else if(p_race == "Zerg")
  {
    worker = "Drone";
    refine = "Extractor";
    mbase = c_ZB_Hatchery_Alias;
  }
  while(a != 8 )//Starcraft supports up to 16 players (0 to 15)
  {
    gasPeons = 0;
    if (AIGetTownState(player, a) == c_townStateEstablished)
    {
      nRefinery = AIGetBuildingCountInTown(player, a, refine, c_techCountCompleteOnly);
      if(AIGetCurPeonCount(player, a) > 12)
      {
        AISetStockEx (player, a, 2, refine, c_makeCollector, 0);
        if (gas > minerals + 1200)
        {
          gasPeons = 0;
        }
        else if (gas > minerals + 900)
        {
          gasPeons = 1;
        }
        else if (gas > minerals + 600)
        {
          gasPeons = 2;
        }
        else if (gas > minerals + 300)
        {
          gasPeons = 3;
        }
        else
        {
          gasPeons = 3 * nRefinery;
        }
      }
      else if(AIGetCurPeonCount(player, a) > 6)
      {
        AISetStockEx (player, a, 1, refine, c_makeCollector, 0);
        gasPeons = 3;
      }
      else
      {
        gasPeons = 0;
      }
    }
    AISetGasPeonCountOverride(player, a, gasPeons);
    a = a + 1;
  }

  //making zerg spam hatchs
  //AISetStockUnitNext(player, totalTowns, mbase ,c_stockIdle);
   
  // build peons
  if(p_race == "Zerg")
  {
    needPeons = totalTowns * 28;
  }
  else
  {
    needPeons = totalTowns * 33;
  }
  if (needPeons > 90)
  {
    needPeons = 90;
  }
  if (needPeons < totalPeons)
  {
    needPeons = AITechCount (player, worker, c_techCountCompleteOnly); //Should you just ignore AISetStockUnitNext() ?
  }
  AISetStockUnitNext(player, needPeons, worker, c_stockAlways);
}
Title: Re: Fixing three issues of Starcrack v6.1.1
Post by: turdburgler on March 14, 2010, 05:27:34 AM
The gas stuff is a terrible idea. We used to do it like that. But the AI reaches saturation so fast and the additional workers off the gas don't make a difference past saturation. Then for expos, they already do this in a much simpler way.
Title: Re: Fixing three issues of Starcrack v6.1.1
Post by: godspiral on March 14, 2010, 09:03:09 AM
Quote from: SuXue on March 14, 2010, 02:36:45 AM

I have found the AI with 500+ gas and 100- minerals multiple times, especially during Terran opening stages... there is no way to spend these gas with such limited minerals

but wasn't the AI mining and training marines?  The appropriate play is to build factories/starports/techlabs.

Its possible in some rare circumstances to want to take workers off gas and put them on minerals, but the decision is not based on how much minerals/gas stockpiles you have.  Its is mostly based on income rate of minerals, and need for more minerals.  typically, After your mineral workers have been killed and you need to make a bunch more.