Fixing three issues of Starcrack v6.1.1

Started by SuXue, March 13, 2010, 02:42:28 PM

Previous topic - Next topic

SuXue

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);
}

Ninja1017

you should up the pre-made file for this

Myst

#2
and used [ code ] [ /code ] tags  :P

GooseBoy


godspiral

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.

SuXue

#5
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

Xest

#6
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);
}

turdburgler

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.

godspiral

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.