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 - Astazha

#31
AI Development / Re: Improved combat AI
March 17, 2010, 03:34:42 PM
Thank you Doix.




256 is the maximum possible index for the UserInt() functions.  Accessing anything above that returns 0.
#32
AI Development / Re: Improved combat AI
March 17, 2010, 12:12:11 PM
Do you know where the player prop constants are used?  I'd like to directly read mineral/gas instead of using AIHasRes()
#33
AI Development / Re: Evolution of the Overmind
March 17, 2010, 11:57:40 AM
Successes:


  - 3/23/2010  Overmind is capable of using the Intel functions to send an Overlord to the enemy's main to monitor production.

  - 3/18/2010 Overmind AI beat Starcrack Protoss OpenGnd1 (19 zealots) in a 1v1


Using the following stock options:
       *11-Pool build order that develops into 1 queen, 2 extractors, 30 drones
       * stock of 40 zerglings
       * default scouting
       * default expansion routine

With the following determined by AI
        *Number of banelings to send with the wave based on known # of zealots
        *Size of wave to send based on known # of zealots
        *Time of attack determined by strength of army compared to known # of zealots

Battle Length - 15:33   


Lots of room for improvement still.  Zerg has dominated Protoss OpenGnd1 before but never fast enough to prevent unscouted expansions from making victory impossible.


Note: Additional victory in 19:15.  In general however, the outcome is unpredictable.  Most games are either lost or brought to a stalemate by scouting failures.

  - 3/17/2010 Overmind AI understands when to go for the kill after wiping out most of the enemy's troops.  Current model only acknowledges Zealots, Zerglings, and Banelings.


Problems:

  - Poor scouting algorithms leave some expansions undiscovered and unattackable.
  - Baneling tactical AI wastes them on armored units if that's what is closest.
  - Army response to enemy scouts has a large and somewhat random impact on the game outcome by creating multiple unplanned skirmishes.
#34
AI Development / Re: Evolution of the Overmind
March 17, 2010, 11:57:20 AM
Sub Projects:


DATA COLLECTION:


The first thing any decision-making framework needs is data.

Working Functions  http://pastebin.com/2tpX4U6V


OvermindReadLarva()
 
- Counts number of larva on the ground and provides an estimated rate of total larva production.
  - Does not account for Hatcheries not making larva when 3 or more are on the ground.

OvermindReadEconomy()  UPDATED 3/23/2010
  - Counts mineral and gas resources on ground at all towns. 
  - Counts # of extractors, and unused gas geysers. 
  - Depletion accounting is only per town, not at individual geyser level.
  - Adjusts for the bug in AIGetGasAmountLeft()
  - Calculates income for gas and minerals.

OvermindReadBank()
 
- Current Minerals, Gas, Supply, and Projected Supply (includes overlords in progress)
   - It's questionable whether it's really necessary to put these into globals via a function.

OvermindMemory array and PeonGas functions
 
- historical data storage
   - safe for use by all players
   - initially just provides  a way to set and get how many peons are harvesting gas at each town
       * Get only knows what was previously Set, it doesn't examine actual peon conditions.
       * Set is a direct replacement for AISetGasPeonCountOverride()
   - interface functions make access look like any other function and encapsulate specifics
   - can be extended to store all kinds of data.
   - OvermindMemory now includes an array slot for marking whether the initialize routines have been run for this player (separate from the standard mainstate variable.)

TODO:
 
- functions to determine unit costs and build times from XML data
          *Use http://www.sc2mapster.com/api-docs/functions/catalog-field-value-get/WISHLIST:
   - whether any waves are in combat and projected change in food usage from coming losses.
   - whether a base is under attack
   - a system of relative valuation of each base, considering resources & harvest rate, resources invested in buildings.

UNIT CHOICE



PRODUCTION MANAGEMENT





ECONOMIC MANAGEMENT



TODO
  - Have the AI successfully generate and execute a starting build order.


CEREBRAL INTELLIGENCE AGENCY

Working Functions:

UPDATED 3/24/2010
  - Fixed various bugs preventing proper acquisition of enemy main.
Various Functions: http://pastebin.com/XRwTK6U7
  -  Locates all resource locations on the map for scouting/expansion purposes.
  -  Location stored is not the town hall location but the location of one of the minerals there.
  -  Will support marking the town as enemy, friendly, or neutral.  All towns start marked neutral.
  -  As any unit spots a townhall building, the location is marked as occupied by friendly or enemy.

TODO
  - Means to remove town spots when destroyed.
  - Include info on player's expansions.
  - Deal with possibility of floating command centers.
  - Various access functions for quickly returning data about known town locations
  - Store additional basic data about the town. player, starting resources, main or expansion
  - Develop system of placing scouts and quickly retrieving them for analysis.
  - Intelligently assign the right scout for the job.  Overlord, Zergling, Roach.
  - Determine travel time to and from various locations for attack coordination.
  - Refine scout behavior for optimization of information/unit conservation.
  - Particularly in protected areas, Overlords should be generating creep on potential expansions once Tier2 is reached.


WISHLIST
   - Historical data including whether an enemy town was ever here, how long it's been neutral, last time attacked, time spotted, known # of workers, projected exhaustion time.
  - Track hot spots on the map where combat frequently occurs.
  - Track Pathing, particularly in high traffic areas.  Be able to locate regions that are out of the way of normal pathing.
  - Develop intel system to support coordinated attacks on multiple locations.




TACTICAL


For improving the AI of waves and individual units.

Working Functions:


SpawnLarva() http://pastebin.com/MTHgEYPV contributions by Kernel64
  - replace code in TactZergAI.galaxy
  - A Queen will spawn a larva at any hatch within range 25 of her
  - She will spawn larva until there are at least 16
  - Larva count based on count of larva units in range of the hatch so it isn't always 100% accurate but it's very close.



CHAT DEBUGGER - suggested by vjeux

This will be a library of chat commands that will cause the AI to display data.  This will be useful for debugging AI behavior during a game (while spectating, I assume it doesn't work during replays) without being continuously buried in data scroll.

TODO:
  - Income
  - KnownForces
  - KnownTowns
  - Create chat trigger options to turn on continuous debugging for a feature.  1st word will be the feature, 2nd word (if any) will be On or Off.


Example:
"Income" will display income data once.
"Income On" will make income data display continuously
"Income Off" will stop the continuous scroll of income data.
#35
AI Development / Evolution of the Overmind
March 17, 2010, 11:57:01 AM
I'm working towards developing an AI that I'm going to call Overmind that will be a Zerg-only AI component.  The initial goals are:


- Intelligent scouting
- Moment of attack determined by decision-making rather than arbitrary times or army sizes.
- Greatest benefit economic decision-making rather than rigid build orders and stock levels.
- A strategic Overmind routine that controls the big picture.
- Adjustable personality variables for setting aggression levels, etc.
- AI doesn't cheat, including:
      *No harvest bonus.
      *No map vision
      *No use of enemy player numbers in place of "player" to access hidden information about the enemy.

I am presently building it within the latest (6.1.1) version of Starcrack as a complete replacement to the existing Zerg AI.  To the extent that it is possible, I wish to contain it within the Zerg files so that it will be easier to merge it with different AI versions.  This will be a 1v1 AI to begin with.


Milestone #1 will be to beat the Starcrack Protoss in a 1v1 without using a stock build order designed to do that.


It will be some time before this is released.  Your thoughts and code snippets are welcome.
#36
I'm beginning to lean towards doing things manually to get real control.  I'm just starting to look into it, but it seems like you could give a move order and then check in on that unit every script cycle to see if there are enemies in range.  If so, pick one and attack it.  If idle, begin moving again.
#37
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.
#38
Something the above doesn't consider is what the units are weak against.  It would be valuable to look for units that are countered by the fewest number of thing in the enemy group as well.


For starters I'd like to focus on responding with builds to what is seen.  Keep it simple to begin with and grow from there.  I'm still interested in discussing more complex possibilities though.
#39
AICounterUnit() adds that value to the unit every time it runs, so you need to either put it in a function that only runs once, like the InitCounters() function or put it in a block of code that uses a static variable to make sure it only runs once.  Then you'll have the exact ratios you added.


An advantage of this approach is that you can run AICounterUnit() later with -1.00 and it will take the value out (if it was +1.00 to start with) and then put a different unit in.


I don't think that building a framework around that function is a good idea.  There are a lot of ways to counter a particular unit.  To counter Zealots, for example, we don't want to just build banelings.  It would be some combination of Zerglings and Banelings, or Zerglings and Roaches.  Maybe Roaches and Banelings.  The counter might be Mutas later in the game.


Besides, the question we'll be more likely to need to answer is what to do about a combination of Zealots and Stalkers given some approximate ratio that the enemy is using them in.  Does the enemy have detection that would prevent roach micro from stretching those units?  Will the battle take place near photon cannons?  Is AIGameTime() large enough that we should be worried about the sudden appearance of Void Rays?  Dark Templars?  Do we have a Greater Spire up?


Here's what I'm imagining:
1) We use the known units function to be aware of what we know the opponent has.
2) We record historical data making note of what units have been seen in the game at any time, how many there were of each at maximum, and at what time that maximum occurred.
3) We record another set of historical data making note of the last time a particular unit was actually spotted and how many there were then.  If this proves too difficult then we can at least make note of when the known unit count goes to 0.
4) Another data set is generated by our assumptions.  This will be tricky but it will give us the option to make educated guesses based on what has been seen and how long it has been.  For example:  After scouting the opponent's race as Protoss an Overlord scout was sent to replace the Drone scout, which we command to bug out after the 1st Zealot appears.  The Overlord has orders to leave when the Cybernetics Core is built, and when that occurred the Protoss player had only 1 Gateway up.  A Stargate started building as the Overlord was leaving.  We expect the player to produce a Void Ray in X minutes, and to have +1 Void ray every y minutes after that.  The threat is weighted by a probability.  If we had less information we might be uncertain whether the fast teching Protoss was going for Collossi, a DT drop with Warp Gates and Warp Prisms, Void Rays, or some other strat.
5) Based on the above we calculate for a given time (say, 3 minutes from now.) or maybe for multiple times what units we expect to face.
6) The cost in time and resources of producing a unit (and teching to it) is tallied.  Tech costs are counted once, unit costs are multiplied by the number of units needed for a counter.  Units that we already have are deducted from the cost at some point, but maybe not here.  Existing unit upgrades should be taken into account here.
7) This is getting complicated, isn't it?
8 ) Now we calculate the cost of countering each type of unit that the enemy has.  Each of our units is assigned a score for the number of enemy units it is being asked to counter multiplied by the cost of the enemy unit and by a factor that represent how dangerous those units are.  This is divided by the cost of making the counter. 
9) The 3 highest scoring units for each enemy unit are considered.  At this point units that have an unacceptable time cost are removed from the list entirely.
10) We begin by taking the #1 choice for every enemy unit and talling the cost of producing the total number required to counter everything that it is #1 for.  The total cost of countering everything with the #1 counters will be our start point.  This is where the cost of our existing army can be deducted, and the tech costs appropriately reduced.
11) From here the object is to reduce this list of #1 counters (which might be 7 types of our units) down to a list of 2 or 3 things that can counter the whole group most effectively. 
11a) Any unit that has already been reached in the tech tree stays.
11b) Now we make a list of units that are countering the smallest amount of stuff (either # of unit types or value of unit types).  We go to each enemy unit type that our candidate for elimination is countering and see what the 2nd and 3rd choices are.  If one of these is existing (already on the list to counter other stuff) then we substitute so that fewer tech costs are incurred and then recalculate to make sure that this is actually a cost improvement.
11c) Repeat step 11b until no more cost effective consolidations can be made.
11d) Now look at available tech for those units and see how much cost effective it is to pay for upgrades.  Tech that takes longer than the available time should not be considered.  Probably no more than the next level of any tech should be considered.
12) We now have a list of counter units, how many we need, what the cost will be, and a projection of how long they will take to make.  At this point the AI can run a check to see what percentage of that force could actually be produced, given our current income and resources. 
13) Numbers over 100% will represent a solid course of action.  Numbers in the 80-90% range will represent a skin of the teeth defense.  Below that, especially a lot below, should signify that things are desperate.  The Overmind level of AI may wish to get creative instead of trying to counter the entire enemy force.  It might be time to shift to a "Hidden Island" all-in tactic or something similar.


This is complicated as hell.  It will require a lot of arrays.  It will require a lot of data about counters.  It will be fallible in the sense that our counter-units may not be fighting what we wanted them to fight when the battle actually happens.  Overall though, I think it's a reasonable cost/benefit analysis.


This is my 1st brush at the matter, so I am of course open to suggestions.  In the meantime I think "this build counters that build" will be far easier to make and so will be much more effective in the short term.  We can just create favorite unit combinations and pick one of them based on what has been seen.


Also note that initially it isn't necessary to do all of these steps.  We can created a watered down version and grow it from there.  For example, the historical data is unnecessary to start with, we can just work with what we know in the present.  Predictive capabilities can be added later.  I do think that it will be important to quantify what we don't know - this is how I believe we will imitate a player's instincts.  When a player hasn't seen an enemy for 10 minutes, or when it's moving into late game and he hasn't scouted the Island expansions, he knows there is a problem.  He also has an approximate idea of how the opponent's economy is doing, based on how many bases he has and how many of them are old enough to be exhausted.  These are places where recording times can give us additional information.  Hell, the computer when scouting an expansion could count the workers and total the mineral piles.  Simple math to get info from that, but you have to write down when you took that data for it to truly help.
#40
Quote from: Aeg1s on March 16, 2010, 09:40:57 AM


AIKnownUnitCount(player, 4, c_PB_Gateway); will return the number of units player knows that player 4 has; if you haven't enabled the cheating vision it will only return what it can/has seen.


It's possible that I used it wrong... I tried that and it didn't work.  Now that I'm talking about this I think I was running the player index from 0 to 3 back then instead of 2-5.  That would be way easier...


@Kernel64 no it doesn't make anything.  AICounterUnit just sets up relationships, and AICounterUnits reports numbers.


It may be useless if AIKnownUnitCount() works as Aeg1s just described, but here's the code for the new InitCounter()


Edit:  Aeg1s is right, AIKnownUnitCount() works fine if you have the right index.  I'll leave the code below in case someone wants to copy paste it and set up counters or something.  I'm a little skeptical about using this as it just returns one unit and sometimes the answer is combined arms.  Better than nothing for reactive code I suppose, but I'd rather read what they have and go from there than just feed a simple 1:1 counter into the production queue.


Note: The index for a player is the player# +1.  Player 2 is index 3, etc.  This Galaxy stuff seems to like 1 base indexes.  I'm not sure why player 1 isn't index 1, but whatever.


Quote//--------------------------------------------------------------------------------------------------
//  InitCounters()
//
//  Blank template for setting up unit counters and ratios.
//  Current version contains every unit and building listed in Requirements.galaxy whether used or not.
//  Functionality with aliases not tested.
//--------------------------------------------------------------------------------------------------
static void InitCounters (int player) {
//
    // Entries for Protoss Units
    AICounterUnit(player, c_PU_Archon,                 1.00, c_PU_Archon);
    AICounterUnit(player, c_PU_Carrier,                 1.00, c_PU_Carrier);
    AICounterUnit(player, c_PU_Colossus,                 1.00, c_PU_Colossus);
    AICounterUnit(player, c_PU_DarkTemplar,             1.00, c_PU_DarkTemplar);
    AICounterUnit(player, c_PU_HighTemplar,             1.00, c_PU_HighTemplar);
    AICounterUnit(player, c_PU_Immortal,                 1.00, c_PU_Immortal);
    AICounterUnit(player, c_PU_Mothership,              1.00, c_PU_Mothership);
    AICounterUnit(player, c_PU_Disruptor,                 1.00, c_PU_Disruptor);
    AICounterUnit(player, c_PU_Observer,                 1.00, c_PU_Observer);
    AICounterUnit(player, c_PU_Phoenix,                 1.00, c_PU_Phoenix);
    AICounterUnit(player, c_PU_Probe,                 1.00, c_PU_Probe);
    AICounterUnit(player, c_PU_Stalker,                 1.00, c_PU_Stalker);
    AICounterUnit(player, c_PU_VoidRay,                 1.00, c_PU_VoidRay);
    AICounterUnit(player, c_PU_WarpPrism,                 1.00, c_PU_WarpPrism);
    AICounterUnit(player, c_PU_WarpPrismPhasing,        1.00, c_PU_WarpPrismPhasing);
    AICounterUnit(player, c_PU_Zealot,                 1.00, c_PU_Zealot);




    //Entries for Protoss Buildings
    AICounterUnit(player, c_PB_Assimilator,             1.00, c_PB_Assimilator);
    AICounterUnit(player, c_PB_CyberneticsCore,         1.00, c_PB_CyberneticsCore);
    AICounterUnit(player, c_PB_DarkShrine,              1.00, c_PB_DarkShrine);
    AICounterUnit(player, c_PB_Obelisk,                 1.00, c_PB_Obelisk);
    AICounterUnit(player, c_PB_FleetBeacon,             1.00, c_PB_FleetBeacon);
    AICounterUnit(player, c_PB_Forge,                 1.00, c_PB_Forge);
    AICounterUnit(player, c_PB_Gateway,                 1.00, c_PB_Gateway);
    AICounterUnit(player, c_PB_Nexus,                 1.00, c_PB_Nexus);
    AICounterUnit(player, c_PB_PhotonCannon,            1.00, c_PB_PhotonCannon);
    AICounterUnit(player, c_PB_Pylon,                 1.00, c_PB_Pylon);
    AICounterUnit(player, c_PB_RoboticsBay,             1.00, c_PB_RoboticsBay);
    AICounterUnit(player, c_PB_RoboticsFacility,        1.00, c_PB_RoboticsFacility);
    AICounterUnit(player, c_PB_Stargate,                 1.00, c_PB_Stargate);
    AICounterUnit(player, c_PB_WarpGate,                 1.00, c_PB_WarpGate);
    AICounterUnit(player, c_PB_TemplarArchives,         1.00, c_PB_TemplarArchives);
    AICounterUnit(player, c_PB_TwilightCouncil,         1.00, c_PB_TwilightCouncil);




    //Entries for Terran Units
    AICounterUnit(player, c_TU_AutoTurret,              1.00, c_TU_AutoTurret);
    AICounterUnit(player, c_TU_Banshee,                 1.00, c_TU_Banshee);
    AICounterUnit(player, c_TU_Battlecruiser,           1.00, c_TU_Battlecruiser);
    AICounterUnit(player, c_TU_BattlecruiserClass,      1.00, c_TU_BattlecruiserClass);
    AICounterUnit(player, c_TU_BattlecruiserDefensive,  1.00, c_TU_BattlecruiserDefensive);
    AICounterUnit(player, c_TU_BattlecruiserMissile,    1.00, c_TU_BattlecruiserMissile);
    AICounterUnit(player, c_TU_BattlecruiserYamato,     1.00, c_TU_BattlecruiserYamato);
    AICounterUnit(player, c_TU_D8Charge,                 1.00, c_TU_D8Charge);
    AICounterUnit(player, c_TU_Ghost,                 1.00, c_TU_Ghost);
    AICounterUnit(player, c_TU_Hellion,                 1.00, c_TU_Hellion);
    AICounterUnit(player, c_TU_Marauder,                 1.00, c_TU_Marauder);
    AICounterUnit(player, c_TU_Marine,                 1.00, c_TU_Marine);
    AICounterUnit(player, c_TU_Medivac,                 1.00, c_TU_Medivac);
    AICounterUnit(player, c_TU_Raven,                 1.00, c_TU_Raven);
    AICounterUnit(player, c_TU_Reaper,                 1.00, c_TU_Reaper);
    AICounterUnit(player, c_TU_SCV,                 1.00, c_TU_SCV);
    AICounterUnit(player, c_TU_SiegeTank,                 1.00, c_TU_SiegeTank);
    AICounterUnit(player, c_TU_SiegeTankSieged ,        1.00, c_TU_SiegeTankSieged );
    AICounterUnit(player, c_TU_SiegeTank_Alias,         1.00, c_TU_SiegeTank_Alias);
    AICounterUnit(player, c_TU_Thor,                 1.00, c_TU_Thor);
    AICounterUnit(player, c_TU_Viking,                 1.00, c_TU_Viking);
    AICounterUnit(player, c_TU_VikingAir,                 1.00, c_TU_VikingAir);
    AICounterUnit(player, c_TU_VikingGnd,                 1.00, c_TU_VikingGnd);
    AICounterUnit(player, c_TU_Viking_Alias,            1.00, c_TU_Viking_Alias);


    //Entries for Terran Buildings
    AICounterUnit(player, c_TB_Armory,                 1.00, c_TB_Armory );
    AICounterUnit(player, c_TB_Barracks,                 1.00, c_TB_Barracks);
    AICounterUnit(player, c_TB_BarracksReactor,         1.00, c_TB_BarracksReactor);
    AICounterUnit(player, c_TB_BarracksTechLab,         1.00, c_TB_BarracksTechLab);
    AICounterUnit(player, c_TB_Bunker,                 1.00, c_TB_Bunker);
    AICounterUnit(player, c_TB_CommandCenter,           1.00, c_TB_CommandCenter);
    AICounterUnit(player, c_TB_CommandCenter_Alias,     1.00, c_TB_CommandCenter_Alias);
    AICounterUnit(player, c_TB_EngineeringBay,          1.00, c_TB_EngineeringBay);
    AICounterUnit(player, c_TB_Factory,                 1.00, c_TB_Factory);
    AICounterUnit(player, c_TB_FactoryReactor,          1.00, c_TB_FactoryReactor);
    AICounterUnit(player, c_TB_FactoryTechLab,          1.00, c_TB_FactoryTechLab);
    AICounterUnit(player, c_TB_FusionCore,              1.00, c_TB_FusionCore);
    AICounterUnit(player, c_TB_GenericTechLab,          1.00, c_TB_GenericTechLab);
    AICounterUnit(player, c_TB_GhostAcademy,            1.00, c_TB_GhostAcademy);
    AICounterUnit(player, c_TB_MercCompound,            1.00, c_TB_MercCompound);
    AICounterUnit(player, c_TB_MissileTurret,           1.00, c_TB_MissileTurret);
    AICounterUnit(player, c_TB_NuclearReactor,          1.00, c_TB_NuclearReactor);
    AICounterUnit(player, c_TB_OrbitalCommand,          1.00, c_TB_OrbitalCommand);
    AICounterUnit(player, c_TB_PlanetaryFortress,         1.00, c_TB_PlanetaryFortress );
    AICounterUnit(player, c_TB_Refinery,                 1.00, c_TB_Refinery);
    AICounterUnit(player, c_TB_SensorTower,             1.00, c_TB_SensorTower);
    AICounterUnit(player, c_TB_Starport,                 1.00, c_TB_Starport);
    AICounterUnit(player, c_TB_StarportReactor,         1.00, c_TB_StarportReactor);
    AICounterUnit(player, c_TB_StarportTechLab,         1.00, c_TB_StarportTechLab);
    AICounterUnit(player, c_TB_SupplyDepot,               1.00, c_TB_SupplyDepot );
    AICounterUnit(player, c_TB_SupplyDepot_Alias,       1.00, c_TB_SupplyDepot_Alias);




    //Entries for Zerg Units
    AICounterUnit(player, c_ZU_Baneling,                 1.00, c_ZU_Baneling);
    AICounterUnit(player, c_ZU_BanelingEgg,             1.00, c_ZU_BanelingEgg);
    AICounterUnit(player, c_ZU_Broodling,                 1.00, c_ZU_Broodling);
    AICounterUnit(player, c_ZU_Changeling,              1.00, c_ZU_Changeling);
    AICounterUnit(player, c_ZU_ChangelingZealot,        1.00, c_ZU_ChangelingZealot);
    AICounterUnit(player, c_ZU_ChangelingZergling,      1.00, c_ZU_ChangelingZergling);
    AICounterUnit(player, c_ZU_ChangelingZerglingWings, 1.00, c_ZU_ChangelingZerglingWings);
    AICounterUnit(player, c_ZU_ChangelingMarineShield,  1.00, c_ZU_ChangelingMarineShield);
    AICounterUnit(player, c_ZU_ChangelingMarine,        1.00, c_ZU_ChangelingMarine);
    AICounterUnit(player, c_ZU_Cocoon,                 1.00, c_ZU_Cocoon);
    AICounterUnit(player, c_ZU_Corruptor,                 1.00, c_ZU_Corruptor);
    AICounterUnit(player, c_ZU_CreepTumor,              1.00, c_ZU_CreepTumor);
    AICounterUnit(player, c_ZU_Drone,                 1.00, c_ZU_Drone);
    AICounterUnit(player, c_ZU_Hydralisk,                 1.00, c_ZU_Hydralisk);
    AICounterUnit(player, c_ZU_Infestor,                 1.00, c_ZU_Infestor);
    AICounterUnit(player, c_ZU_InfestedTerran,          1.00, c_ZU_InfestedTerran);
    AICounterUnit(player, c_ZU_InfestedTerranEgg,       1.00, c_ZU_InfestedTerranEgg);
    AICounterUnit(player, c_ZU_Larva,                 1.00, c_ZU_Larva);
    AICounterUnit(player, c_ZU_Lurker,                 1.00, c_ZU_Lurker);
    AICounterUnit(player, c_ZU_LurkerEgg,                 1.00, c_ZU_LurkerEgg);
    AICounterUnit(player, c_ZU_Mantaling,                 1.00, c_ZU_Mantaling);
    AICounterUnit(player, c_ZU_Mutalisk,                 1.00, c_ZU_Mutalisk);
    AICounterUnit(player, c_ZU_Overlord,                 1.00, c_ZU_Overlord);
    AICounterUnit(player, c_ZU_Overlord_Alias,          1.00, c_ZU_Overlord_Alias);
    AICounterUnit(player, c_ZU_Overseer,                 1.00, c_ZU_Overseer);
    AICounterUnit(player, c_ZU_Queen,                 1.00, c_ZU_Queen);
    AICounterUnit(player, c_ZU_Roach,                 1.00, c_ZU_Roach);
    AICounterUnit(player, c_ZU_BroodLord,                 1.00, c_ZU_BroodLord);
    AICounterUnit(player, c_ZU_BroodLord,                 1.00, c_ZU_BroodLord);
    AICounterUnit(player, c_ZU_Ultralisk,                 1.00, c_ZU_Ultralisk);
    AICounterUnit(player, c_ZU_Zergling,                 1.00, c_ZU_Zergling);




    //Entries for Zerg buildings
    AICounterUnit(player, c_ZB_BanelingNest,            1.00, c_ZB_BanelingNest);
    AICounterUnit(player, c_ZB_CreepTumor,              1.00, c_ZB_CreepTumor);
    AICounterUnit(player, c_ZB_EvolutionChamber,        1.00, c_ZB_EvolutionChamber);
    AICounterUnit(player, c_ZB_Extractor,                 1.00, c_ZB_Extractor);
    AICounterUnit(player, c_ZB_GreaterSpire,            1.00, c_ZB_GreaterSpire);
    AICounterUnit(player, c_ZB_Hatchery,                 1.00, c_ZB_Hatchery);
    AICounterUnit(player, c_ZB_Hatchery_Alias,          1.00, c_ZB_Hatchery_Alias);
    AICounterUnit(player, c_ZB_Hive,                 1.00, c_ZB_Hive);
    AICounterUnit(player, c_ZB_HydraliskDen,            1.00, c_ZB_HydraliskDen);
    AICounterUnit(player, c_ZB_HydraliskDen_Alias,      1.00, c_ZB_HydraliskDen_Alias);
    AICounterUnit(player, c_ZB_InfestationPit,          1.00, c_ZB_InfestationPit);
    AICounterUnit(player, c_ZB_Lair,                 1.00, c_ZB_Lair);
    AICounterUnit(player, c_ZB_Lair_Alias,              1.00, c_ZB_Lair_Alias);
    AICounterUnit(player, c_ZB_LurkerDen,                 1.00, c_ZB_LurkerDen);
    AICounterUnit(player, c_ZB_NydusNetwork,            1.00, c_ZB_NydusNetwork);
    AICounterUnit(player, c_ZB_NydusWorm,                 1.00, c_ZB_NydusWorm);
    AICounterUnit(player, c_ZB_RoachWarren,             1.00, c_ZB_RoachWarren);
    AICounterUnit(player, c_ZB_SpawningPool,            1.00, c_ZB_SpawningPool);
    AICounterUnit(player, c_ZB_SpineCrawler,            1.00, c_ZB_SpineCrawler);
    AICounterUnit(player, c_ZB_SpineCrawlerUp,          1.00, c_ZB_SpineCrawlerUp);
    AICounterUnit(player, c_ZB_Spire,                 1.00, c_ZB_Spire);
    AICounterUnit(player, c_ZB_Spire_Alias,               1.00, c_ZB_Spire_Alias);
    AICounterUnit(player, c_ZB_SporeCrawler,            1.00, c_ZB_SporeCrawler);
    AICounterUnit(player, c_ZB_SporeCrawlerUp,          1.00, c_ZB_SporeCrawlerUp);
    AICounterUnit(player, c_ZB_UltraliskCavern,         1.00, c_ZB_UltraliskCavern);


}
#41
Ok, this is actually really straightforward.  I thought I was going to have to jump through some hoops, but it turns out to be extremely simple.


The two functions we are interested in are:
AICounterUnit()
AICounterUnits()


In Zerg.galaxy InitCounters() uses AICounterUnit() to set up relationships between enemy units and what they should be countered with.  For example:


AICounterUnit(player, c_PU_Zealot, 1.00, c_PU_Baneling);


This means that for every Zealot out there (that we've seen), we should build 1.00 Banelings.  It appears to be good at knowing the difference between a new unit and one that it has already seen, and it doesn't cheat.  We often don't get a real probe count on the initial scout, for example, because the default scout pathing doesn't get close enough to the mineral pile to actually see them all.


If you call AICounterUnits() like this:


howManyBanelingsShouldIBuild=AICounterUnits(player, 4, c_ZU_Baneling);


it will tell you how many Banelings should be built against player 3 (index 4).  As long as Zealots are the only thing Banelings counter, and the ratio is 1.00 then this is also the number of Zealots player 3 has.


It gets simpler.  We can't use any user-defined strings in these functions, but there is nothing preventing us from using the strings from other races.  Soooo...


We delete all the existing entries.  Then we make an entry for each unit and building, listing it as the counter to itself with a ratio of 1.00


Then when you call


countPBGateways=AICounterUnits(player, 4, c_PB_Gateway);


it will tell you how many Gateways player 3 has.  Wash Rinse Repeat for every unit in the game.  Once you get a read of what race you're dealing with you no longer have to check 2/3 of the units and we can begin to make match-specific decisions about the build order and general strategy.


I'll post actual code when I have something working, but if you want to mess with it now that's how it works.
#42
It does work on buildings... this is exciting.


::crawls into cave with computer::
#43
I have an idea that has survived initial testing.  I'm using the counterunit functions.  They don't cheat, and they have successfully told me how many zealots a player has when given the assumption that the player is protoss.  I think I can wrangle this to figure out everything we need once the scout has seen it.  We'll see... I haven't tried to make it work with buildings yet, which will be important.
#44
I like all of that.  I might add scouting - if we're trying to make a truly non-cheating AI, and I am, then information is it's own priority.


Without getting into map specific logic, I don't think we can do map control in the "control the center" sense apart from just guessing at what might be a good location to place troops.  You could go for center of map, or center of your towns and toward the enemy a bit, or a more aggressive posture center of their towns and towards you a bit.  On some maps those guesses might be disastrous though.  I think this might be worth exploring, just from the standpoint of reducing unit travel time. 


The first thing I think the AI can do better as far as map control is to expand, expand, expand.  Particularly a Zerg AI.  Defenses could range from:


1) Undefended.  The AI is placing a Hatchery just to know if the player is there or not and prevent player expansion, and to provoke a defense response if they show up to try to expand.
2) Light to Moderate defenses. - Some Spines, maybe Spores depending.
3) Mobile defenses.  Multiple expansions are best covered by units that are mobile - either centrally placed, Air units, or perhaps a defensive wave chillin' in a Nydus network with exits already built (back by the mineral line) and protected by defense structures.
4) Heavy defenses.  Expansions that have become the main source of income might warrant the presence of a wave in addition to some of the above.


On a separate note, Wave management will be important to stop the player from abusing the AI's defensive instincts.  A mildly threatening harass should not cause his main attack wave to abort the invasion.


Have you had any luck with information gathering functions?  I'm working on this right now to try to create the mathematical reductions you described.  AIWaveEvalRatio provides a ratio of (friendly life)/(enemy life) which is some indication of how things are going but is very rough.  A better indication of how the battle is going is to watch how that number changes, but even then it's a far cry from knowing whether the enemy has zealots or stalkers, and how many of each.


#45
AI Development / Re: AI Ability Usage xmls
March 16, 2010, 05:55:59 AM
I believe you asked in another thread if it was possible to read from the XML.


http://www.sc2mapster.com/api-docs/functions/catalog-field-value-get/