RaphaelRoyerRivard / MicroMachine

Starcraft 2 Bot
MIT License
15 stars 0 forks source link

Create army composition analyser #137

Open RaphaelRoyerRivard opened 6 years ago

Unusual229 commented 5 years ago

Will start working on this soon, unless we have more important features or new bugs are found.

Unusual229 commented 5 years ago

Its being worked on. We currently can know the content of the enemy army and their dead units. This data is unused for now though.

Unusual229 commented 5 years ago

ArmyCompositionAnalyzer is called the CombatAnalyzer

It will handle the following : [CANCELLED] Invisible units if we end up doing the detection manually Counting units on both teams Counting dead units on both teams Try to determine the enemy upgrades and some detectable tech Manage what units we should produce based on the HealthDamageRatio and the enemy army composition.

Unusual229 commented 5 years ago

[CANCELED]

I plan on creating 4 methods: shouldProduceGroundAntiGround shouldProduceGroundAntiAir shouldProduceAirAntiGround shouldProduceAirAntiAir

Each of them will check if we are currently ahead or behind in a certain "matchup". For example, if we see a lot of zergling, the enemy will be winning on the ground, so shouldProduceGroundAntiGround will return true, and we will produce hellions. However, if we have enough ground units to deal with it (like a bunch of marines), we will produce hellions. This way, our production will be based on what the opponent has. When all 4 of the above methods return false, we will try to produce the unit with the highest damage/death ratio.

To determine whether we have enough or not, I will go by army value. I will consider gas as mineral * 2 so a banshee (150/100) is 350 in value. 2 zerglings = 1 marine = 50 minerals. 1 Banshee = 1.55 stalker = 350. I will, eventually, add some fraction of the value of upgrades to the unit, For example, a ling with speed will be worth 50 instead of 25, because it is much stronger.

Let me know if it makes sense to you.

Unusual229 commented 5 years ago

New idea:

If I can have a ratio of each unit VS each unit, I could know how to counter the enemy army, without having to hard code a list of counters. Ex: Marine -> Zergling : 0.9 Marauder -> Zergling : 0.8 Hellion -> Zergling : 3 Hellion (Hellbat) -> Zergling : 4 Marine -> Hydra : 1.2 Marauder -> Hydra : 1.5 Hellion -> Hydra : 0.6 Hellion (Hellbat) -> 0.9 ...

The current ratio of damage dealt/received should probably still exist, if we don't trade well in a particular game with X unit, we don't want to keep producing it even if it counters Y, might as well pick the unit with the second highest ratio against Y.

The current way we calculate the damage dealt for the the dealt/received ratio should be accurate enough. To calculate the damage received part of the ratio, we will need to :

When taking damage (X), check all units around (including ours which can do splash) if any of these unit can deal X damage to our unit, if its enemy we need to check with upgrades as well (will allow us to flag them and improve the combat simulation accuracy). If there is a single match, then modify the ratio, if there are multiple results modify all ratios proportionally (if we don't change any ratio, our unit might head up with unusually high ratios), if there is no match check if a combo of these units damage could explain it (takes 15, 5 from ling and 10 from roach). If there is such a match, then modify ratios proportionally, if there are multiple possibility either split, ignore or take the worst ratios (most likely to be this combo, than any other). If the match contains a friendly unit's splash damage, modify another ratio (for the unit that dealt the damage). If there is no match, but there is an invisible unit, try to match any of the unit type that can be invisible, if it doesn't match and there are many invisible unit, try to match a combo of them. Same rules as above if there is a match. If we still don't have a match, ignore it.

The above logic will not work with units being healed on our side (it will also not flag enemy armor upgrades), if we want to consider healing (medivac, SCV and reaper, for Terrans). The exact way the healing works will have to be investigated. It could be either tracked perfectly (we know, for example, the Medivac heals for 1 every 3 frames, so if we are on such a frame and we are a medivac's target, we consider it in our calculation) or could be guessed (we are close to a medivac, so if this unit attack doesn't match, does it match if I consider the healing I might have gotten? if yes, then its probably it). Reaper's healing isn't really important to consider, since we run away until we are fully healed.

If we want to keep track of the friendly fire, we will want to add the friendly fire ratio next to the dealt/received ratio. This way, we can know whether a unit type is more dangerous for us or not.

We should keep the dealt/received ratio between games (per opponent race) AND have a per game ratio (as it currently is).

These new ratios will allow us to know which unit to produce to counter XY units the enemy is making, it will also allow us to match our units to defend or unblock expansion optimally (probably other cases, such as attacking an expand protected by XY), will allow us to detect quite a few enemy upgrades and it will give us more informations on how our units trade. It will let us know if, for example, our vikings trade poorly vs mutalisk, or if our hellions are bad vs zerglings, so we can improve on them.

One draw back, is that it will be complex to put together and will require to be "trained" and "retrained" to have trustable ratios.

Unusual229 commented 5 years ago

[Design] There should be a function that receives a Unit (damage receiver), a list of Units (potential damage dealers) and a bool (which of the two we are). When a match fails, the bool should be checked, if we are the attacker, we try to match again with -1 damage (and so on), if we aren't the attacker, we try to match with + attack (based on the unit type and bonuses). This will allow us to reuse this function to be able to determine if the opponent has armor upgrades. Note that it should be really efficient when we attack (since the list of potential damage dealer should just 1 unit) and less efficient when we are attacked (since the list of potential damage dealer can be larger, but is based on types so 1 zergling or 10000 zerglings should be just as efficient).

Unusual229 commented 5 years ago

Should detect enemy hallucination (if enemy is protoss and is matching for 2x the damage, then is fake).