///// <summary> ///// Find and set the best leader candidate (most health/armor and not Tank, SCV or Medic). ///// ONLY WORKS FOR TERRAN. ///// </summary> ///// <returns></returns> //public static UnitAgent FindBestLeaderCandidate(ref List<UnitAgent> squad) //{ // int bestHealth = 0; // int currentHealth = -1; // UnitAgent bestUnitAgent = null; // if (squad != null && squad.Count > 0) // { // bestUnitAgent = squad[0]; // foreach (UnitAgent unitagent in squad) // { // if (IsAGoodLeaderCandidate(unitagent.MyUnit)) // { // currentHealth = unitagent.MyUnit.HitPoints + unitagent.MyUnit.Shields; // if (currentHealth > bestHealth) // { // bestHealth = currentHealth; // bestUnitAgent = unitagent; // } // } // } // bestUnitAgent.LeadingStatus = UnitAgent.LeadingStatusEnum.GroupLeader; // } // else // { // Console.WriteLine("Parameter squad null in FindBestLeaderCandidate in SCMath."); // // Logger.Logger.AddAndPrint("Parameter squad null in FindBestLeaderCandidate in MyMath."); // } // return bestUnitAgent; //} /// <summary> /// Find the enemy unit that has lost most hitpoints and shield in percentage /// in a user specified radius from the specified center position. /// </summary> /// <param name="position">center position</param> /// <param name="radius">the radius that should be scanned for injured or damaged enemy units.</param> /// <returns></returns> public static Unit GetEnemyUnitWithLowestHitpoints(Position position, int radius)//radius = 5 { Unit mostInjuredEnemyUnit = null; double lowestHealth = 1; if (SWIG.BWAPI.bwapi.Broodwar.enemy().getUnits() != null)//Game.PlayerEnemy.GetUnits() != null) { foreach (Unit enemyUnit in bwapi.Broodwar.enemy().getUnits()) { if (enemyUnit.isVisible() && enemyUnit.getPosition().getDistance(position) < radius * TileSize)//Only look at possible injured units in a radius of 5 tiles. { double currentEnemyUnitHealth = SCMath.UnitHitpointsLeftInPercentage(enemyUnit); if (currentEnemyUnitHealth < lowestHealth) { lowestHealth = currentEnemyUnitHealth; mostInjuredEnemyUnit = enemyUnit; } } } } else { //Logger.Logger.AddAndPrint("ERROR in GetEnemyUnitWithLowestHitpoints, the enemyUnits list is NULL"); //Util.Logger.Instance.Log("ERROR in GetEnemyUnitWithLowestHitpoints, the enemyUnits list is NULL");); } return(mostInjuredEnemyUnit); }
/// <summary> /// Calculates the magnitude of the specified field relative to the center of the map. /// </summary> /// <param name="field"></param> /// <param name="force"></param> /// <param name="forceStep"></param> /// <param name="rangePercentage"></param> /// <returns></returns> public double PFMapCenterAttraction(Position field, double force, double forceStep, int rangePercentage) { double distance = field.getDistance(SCMath.GetMapCenterPosition()); return(distance <= SCMath.GetPercentageOfMaxDistancePixels(rangePercentage) ? force//0 : force - forceStep * distance); }
/// <summary> /// Calculate the potential value of the field that the current military unit can go to in the next frame, while the unit's weapon has it's cooldown period. /// Weapon cooldown happens each time the weapon is reloading. /// Some weapons are very effective, but recharges very slowly. It may therefore be a good tactic to flee when the weapon is in cool down, and thereby avoid being hit. /// </summary> /// <param name="field"></param> /// <param name="enemy"></param> /// <param name="distanceToEnemy"></param> /// <param name="force"></param> /// <param name="forceStep"></param> /// <param name="range"></param> /// <returns></returns> public double PFWeaponCoolDownRepulsion(Position field, double distanceToEnemy, Unit enemy, double force, double forceStep, int range) { if (enemy.isVisible() && IsInEnemyUnitsRange(field, range)) { return(SCMath.CalculateRepulsiveMagnitude(force, forceStep, distanceToEnemy, true)); } return(0); }
/// <summary> /// Calculates the magnitude of the specified position on the map relative to the centroid of the squad /// (being close to the other units in the squad will give the best magnitude/attraction). /// </summary> /// <param name="squad"></param> /// <param name="possibleNextPosition"></param> /// <param name="force"></param> /// <param name="forceStep"></param> /// <param name="rangePercentage">How big the Range to the centroid of all the Units positions in the Squad/Group</param> /// <returns>The magnitude of squad attraction. 0 if a unit is inside the specified range and gives a negative linear drop-off the further away the unit is from the group.</returns> public double PFSquadAttraction(List <UnitAgent> squad, Position possibleNextPosition, double force, double forceStep, int rangePercentage) { if (squad != null && squad.Count > 0) { double distance = possibleNextPosition.getDistance(CombatControl.CalculateCentroidPosition(squad.Select(ua => ua.SCUnit))); return(distance <= SCMath.GetPercentageOfMaxDistancePixels(rangePercentage) ? force//0 : force - forceStep * distance); } log.Error("squad unit list is null or has zero elements in PFSquadAttraction"); return(0); }
public void FindAndSetOptimalGoalForUnitAgent(UnitAgent unitAgent) { if (unitAgent == null) { log.Error("unitAgent is null in method SetGoalPositionForUnitAgentToClosestEnemy"); throw new ArgumentNullException("unitAgent"); } Unit enemyUnitToAttack = SCMath.GetClosestEnemyUnit(unitAgent.SCUnit);//unitAgent.GetClosestEnemyUnit(); if (enemyUnitToAttack != null) { unitAgent.GoalUnitToAttack = enemyUnitToAttack; unitAgent.GoalPosition = enemyUnitToAttack.getPosition(); } }
/// <summary> /// Calculate the potential of the specified field/position. /// </summary> /// <param name="squad"></param> /// <param name="enemy"></param> /// <param name="field"></param> /// <returns></returns> public double CalculatePotentialField(List <UnitAgent> squad, Unit enemy, Position field) { double pVal = 0; //DO NOT UPDATE WITH EVOLUTIONARY ALGORITHM const double forceNeutralUnitsRepulsion = 200; // 0 - 1000 //REMEMBER TO SET TO A POSITIVE NUMBER. const double forceStepNeutralUnitsRepulsion = 1.2; // 0 - 10 int rangeNeutralUnitsRepulsion = 8; //0-512 // /////////////////////////////////////////// double distance = enemy.getDistance(field); if (SCUnit.getGroundWeaponCooldown() == 0) //If the weapon is ready to fire, PFMaxShootingDistanceAttraction is activated { pVal += PFMaxShootingDistanceAttraction(distance, enemy, OptimizedProperties.ForceMSD, OptimizedProperties.ForceStepMSD); //, MSDDiffDivValue); } else if (SCMath.GetRange(SCUnit) > 1) //Else If Weapon is ready to fire and AttackRange is bigger than 1, FLEE/RETREAT until weapon is ready to fire again. { pVal += PFWeaponCoolDownRepulsion(field, distance, enemy, OptimizedProperties.ForceWeaponCoolDownRepulsion, OptimizedProperties.ForceStepWeaponCoolDownRepulsion, OptimizedProperties.RangeWeaponCooldownRepulsion); } //Squad attraction if (squad.Count > 2) { pVal += PFSquadAttraction(squad, field, OptimizedProperties.ForceSquadAttraction, OptimizedProperties.ForceStepSquadAttraction, OptimizedProperties.RangePercentageSquadAttraction); } //Center of the map attraction (NEGATES the MSD) pVal += PFMapCenterAttraction(field, OptimizedProperties.ForceMapCenterAttraction, OptimizedProperties.ForceStepMapCenterAttraction, OptimizedProperties.RangePecentageMapCenterAttraction); //Map edge repulsion (NEGATES the MSD) pVal += SCMath.CalculateMapEdgeRepulsion(field, OptimizedProperties.ForceMapEdgeRepulsion, OptimizedProperties.ForceStepMapEdgeRepulsion, OptimizedProperties.RangeMapEdgeRepulsion); //Own Unit Repulsion pVal += PFOwnUnitsRepulsion(squad, field, OptimizedProperties.ForceOwnUnitsRepulsion, OptimizedProperties.ForceStepOwnUnitsRepulsion, OptimizedProperties.RangeOwnUnitsRepulsion); //Enemy Unit Repulsion pVal += PFEnemyUnitsRepulsion(field, OptimizedProperties.ForceEnemyUnitsRepulsion, OptimizedProperties.ForceStepEnemyUnitsRepulsion); //, rangeEnemyUnitsRepulsion); //Neutral Unit Repulsion pVal += PFNeutralUnitsRepulsion(field, forceNeutralUnitsRepulsion, forceStepNeutralUnitsRepulsion, rangeNeutralUnitsRepulsion); return(pVal); }
public double PFNeutralUnitsRepulsion(Position field, double force, double forceStep, int range) { double pfValue = 0; if (SWIG.BWAPI.bwapi.Broodwar.getStaticNeutralUnits() != null && SWIG.BWAPI.bwapi.Broodwar.getStaticNeutralUnits().Count > 0) { foreach (Unit neutralUnit in bwapi.Broodwar.getStaticNeutralUnits()) { pfValue = SCMath.CalculatePFNeutralUnitRepulsion(neutralUnit, field, force, forceStep, range); if (pfValue < 0) { return(pfValue); } } } return(0); }
/// <summary> /// Returns true if the specified position is inside one of the enemy units range + the extraRange. /// </summary> /// <param name="field"></param> /// <param name="extraRange"></param> /// <returns></returns> public Boolean IsInEnemyUnitsRange(Position field, int extraRange) { if (SWIG.BWAPI.bwapi.Broodwar.enemy().getUnits() != null && SWIG.BWAPI.bwapi.Broodwar.enemy().getUnits().Count > 0) { foreach (Unit enemyUnit in bwapi.Broodwar.enemy().getUnits()) { if (CanBeAttacked(SCUnit, enemyUnit)) { if (enemyUnit.getDistance(field) <= SCMath.GetRange(enemyUnit) + extraRange) { return(true); } } } // return Game.PlayerEnemy.GetUnits().Where(enemyUnit => CanBeAttacked(MyUnit, enemyUnit)).Any(enemyUnit => enemyUnit.getDistance(field) <= enemyUnit.getType().WeaponGround.AttackRangeMax); } return(false); }
public Position CalculateNewSubGoalPosition(List <UnitAgent> squad, Unit closestEnemyUnit) { int currentX = SCUnit.getPosition().xConst(); int currentY = SCUnit.getPosition().yConst(); List <Position> surroundingPositions = SCMath.GetPossibleSurroundingPositionsRotation(currentX, currentY, 48, 35); double currentPotentialFieldValue = -1000; double bestPotentialFieldValue = -1000; Position bestPosition = SCUnit.getPosition(); foreach (Position possibleNextPosition in surroundingPositions) { currentPotentialFieldValue = CalculatePotentialField(squad, closestEnemyUnit, possibleNextPosition); if (currentPotentialFieldValue > bestPotentialFieldValue) { bestPotentialFieldValue = currentPotentialFieldValue; bestPosition = possibleNextPosition; } } return(bestPosition); }
public double PFOwnUnitsRepulsion(List <UnitAgent> squad, Position field, double force, double forceStep, int range) { double pfValue = 0; if (SWIG.BWAPI.bwapi.Broodwar.self().getUnits() != null && SWIG.BWAPI.bwapi.Broodwar.self().getUnits().Count > 0) { foreach (UnitAgent myOtherUnit in squad) { pfValue = SCMath.CalculatePFOwnUnitRepulsion(SCUnit, field, myOtherUnit.SCUnit, force, forceStep, range); if (pfValue < 0) { return(pfValue); } } } else { log.Error("self unit list is null in PFOwnUnitsRepulsion"); } return(0); }
public double PFEnemyUnitsRepulsion(Position field, double force, double forceStep) { double pfValue = 0; //foreach (Unit myOtherUnit in unitsInMyArea) if (SWIG.BWAPI.bwapi.Broodwar.enemy().getUnits() != null && SWIG.BWAPI.bwapi.Broodwar.enemy().getUnits().Count > 0) { foreach (Unit enemyUnit in bwapi.Broodwar.enemy().getUnits()) { pfValue = SCMath.CalculatePFEnemyUnitRepulsion(SCUnit, field, enemyUnit, force, forceStep); if (pfValue < 0) { return(pfValue); } } } else { log.Error("Enemy unit list is null in PFEnemyUnitsRepulsion"); } return(0); }
/// <summary> /// Calculates the maximum distance from corner to corner in the current map (In tiles). /// </summary> /// <returns></returns> private static int CalculateMaxDistance() { _maxDistance = SCMath.PythagorasInt(bwapi.Broodwar.mapHeight(), bwapi.Broodwar.mapWidth());//Max Potential Field Value return(_maxDistance); }