/// <summary> /// Calculates the potential value of the field that the current military unit can go to in the next frame, while the unit's weapon are ready to fire. /// The unit's Max Shooting Distance (MSD) will be the optimal place to be, because all enemy units with a shorter MSD then can't harm your unit, unless they move fastest. /// </summary> /// <param name="distanceToEnemy"></param> /// <param name="enemyUnit"></param> /// <param name="forceToOwnMSD"></param> /// <param name="forceStepToOwnMSD"></param> /// <returns>double potentialValue</returns> public double PFMaxShootingDistanceAttraction(double distanceToEnemy, Unit enemyUnit, double forceToOwnMSD, double forceStepToOwnMSD) { int ownUnitMSD = SCUnit.getType().groundWeapon().maxRange(); // / TileSize;// int enemyUnitMSD = enemyUnit.getType().groundWeapon().maxRange(); int MSDDifference = ownUnitMSD - enemyUnitMSD; double potenTialValueMSD = 0; //Weight potenTialValueMSD is used to alter the relative strength of the current tile, which the unit stands on or the possible tiles the unit can go to. if (distanceToEnemy > ownUnitMSD) //GET CLOSER TO ENEMY { return(forceToOwnMSD - forceStepToOwnMSD * (distanceToEnemy - ownUnitMSD)); } if (MSDDifference > 0) { if (distanceToEnemy <= ownUnitMSD && distanceToEnemy > enemyUnitMSD) { return(forceToOwnMSD + distanceToEnemy); } } else if (distanceToEnemy <= ownUnitMSD) //TOO CLOSE TO ENEMY { return(forceToOwnMSD); } return(potenTialValueMSD); }
/// <summary> /// Checks if the current unit's health level is ok. /// </summary> /// <returns>True if the current unit's health level is ok (health and shield level together is over the specified minHealthLevel).</returns> public Boolean IsHealthLevelOk(int minHealthLevel) { if (SCUnit.getHitPoints() + SCUnit.getShields() >= minHealthLevel) { return(true); } return(false); }
public void ExecuteBestActionForUnitAgent(List <UnitAgent> squad) { if (SCUnit.isVisible() && GoalUnitToAttack != null) //Always remember to check if the unit is visible, before Moving it. { SubGoalPosition = CalculateNewSubGoalPosition(squad, GoalUnitToAttack); if (SCUnit.getGroundWeaponCooldown() != 0) { SCUnit.rightClick(SubGoalPosition); } else { SCUnit.attack(SubGoalPosition); } } }
/// <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 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); }