IEnumerable <int> FindAirDefenses() { airDefenses = AirDefense.Find(); //After finding air Defenses, Sort them. if (airDefenses.Length > 1) { //Now that we found all Air Defenses, order them in the array with closest AD to Target first. Array.Sort(airDefenses, delegate(AirDefense ad1, AirDefense ad2) { return(HumanLikeAlgorithms.DistanceFromPoint(ad1, mainTarget.DeployGrunts) .CompareTo(HumanLikeAlgorithms.DistanceFromPoint(ad2, mainTarget.DeployGrunts))); }); } else { Log.Error($"{Tag} Somehow no air defenses were found in Attack Phase. - Surrender."); surrender = true; yield break; } }
public override double ShouldAccept() { if (!PassesBasicAcceptRequirements()) { return(0); } //TODO - Check which kind of army we have trained. Calculate an Air Offense Score, and Ground Offense Score. //TODO - Find all Base Defenses, and calculate an AIR and Ground Defensive Score. //TODO - From Collector/Storage fill levels, determine if loot is in Collectors, or Storages... (Will help to decide which alg to use.) //Verify that the Attacking Army contains at least 6 Dragons. deployElements = Deploy.GetTroops(); var dragons = deployElements.FirstOrDefault(u => u.Id == DeployId.Dragon); if (dragons == null || dragons?.Count < 6) { Log.Error($"{Tag} Army not correct! - Dark Dragon Deploy Requires at least 6 Dragons to function Properly. (You have {dragons?.Count ?? 0} dragons)"); return(0); } //Verify that there are enough spells to take out at least ONE air defense. var lightningSpells = deployElements.FirstOrDefault(u => u.ElementType == DeployElementType.Spell && u.Id == DeployId.Lightning); List <DeployElement> earthquakeSpells = deployElements.Where(u => u.ElementType == DeployElementType.Spell && u.Id == DeployId.Earthquake).ToList(); var lightningCount = lightningSpells?.Count ?? 0; var earthquakeCount = 0; //Get a count of all earthquake spells... donated, or brewed... foreach (var spell in earthquakeSpells.Where(s => s.Count > 0)) { earthquakeCount += spell.Count; } if (lightningCount < 2 || lightningCount < 3 && earthquakeCount < 1) { //We dont have the Spells to take out the Closest Air Defense... Surrender before we drop any Dragons! Log.Error($"{Tag} We don't have enough spells to take out at least 1 air defense... Lightning Spells:{lightningCount}, Earthquake Spells:{earthquakeCount}"); return(0); } if (deployElements.Count >= 11) { //Possibly Too Many Deployment Elements! Bot Doesnt Scroll - Change Army Composition to have less than 12 unit types! Log.Warning($"{Tag} Warning! Full Army! - The Bot does not scroll through choices when deploying units... If your army has more than 11 unit types, The bot will not see them all, and cannot deploy everything!)"); } //Write out all the unit pretty names we found... Log.Debug($"{Tag} Deployable Troops: {ToUnitString(deployElements)}"); Log.Info($"{Tag} Base meets minimum Requirements... Checking DE Storage/Air Defense Locations..."); //Grab the Locations of the DE Storage darkElixirStorage = HumanLikeAlgorithms.TargetDarkElixirStorage(); if (!darkElixirStorage.ValidTarget) { Log.Warning($"{Tag} No Dark Elixir Storage Found - Skipping"); return(0); } //Get the locaiton of all Air Defenses var airDefensesTest = AirDefense.Find(); if (airDefensesTest.Length == 0) { Log.Warning($"{Tag} Could not find ANY air defenses - Skipping"); return(0); } Log.Info($"{Tag} Found {airDefensesTest.Length} Air Defense Buildings.. Continuing Attack.."); if (airDefensesTest.Length > 1) { //Now that we found all Air Defenses, order them in the array with closest AD to Target first. Array.Sort(airDefensesTest, delegate(AirDefense ad1, AirDefense ad2) { return(HumanLikeAlgorithms.DistanceFromPoint(ad1, darkElixirStorage.DeployGrunts) .CompareTo(HumanLikeAlgorithms.DistanceFromPoint(ad2, darkElixirStorage.DeployGrunts))); }); } //Create the Funnel Points deFunnelPoints = darkElixirStorage.GetFunnelingPoints(30); balloonFunnelPoints = darkElixirStorage.GetFunnelingPoints(20); #if DEBUG //During Debug, Create an Image of the base including what we found. CreateDebugImages(); #endif //We are Good to attack! return(1); }