/// <summary> /// Runs the commander away from opponents /// </summary> private static void DoCommander(BotMain bot, TerritoryStanding cmdrTerritory, Commander cmdr) { var directive = CommanderDirective(bot, cmdrTerritory.ID); if (directive.HasValue) { AILog.Log("SpecialUnits", "Directive directs us to move the commander from " + bot.TerrString(cmdrTerritory.ID) + " to " + bot.TerrString(directive.Value)); if (directive.Value != cmdrTerritory.ID) { bot.Orders.AddAttack(cmdrTerritory.ID, directive.Value, AttackTransferEnum.AttackTransfer, cmdrTerritory.NumArmies.NumArmies, false, commanders: true); } bot.AvoidTerritories.Add(cmdrTerritory.ID); //add this so we don't deploy there, we want the commander to stay alone return; } var powerDiff = bot.Map.Territories[cmdrTerritory.ID].ConnectedTo.Keys .Select(o => bot.Standing.Territories[o]) .Where(o => bot.IsOpponent(o.OwnerPlayerID) && o.NumArmies.Fogged == false) .Sum(o => o.NumArmies.AttackPower) - cmdrTerritory.NumArmies.DefensePower; var toDeploy = Math.Max(0, powerDiff); if (powerDiff > 0) { if (bot.UseRandomness) { toDeploy = SharedUtility.Round(toDeploy * RandomUtility.BellRandom(0.5, 1.5)); } if (toDeploy > bot.MakeOrders.IncomeTracker.RemainingUndeployed) { toDeploy = bot.MakeOrders.IncomeTracker.RemainingUndeployed; } if (toDeploy > 0 && bot.Orders.TryDeploy(cmdrTerritory.ID, toDeploy)) { AILog.Log("SpecialUnits", "Deployed " + toDeploy + " to defend commander"); } } //Consider this territory and all adjacent territories. Which is the furthest from any enemy? var terrDistances = bot.Map.Territories[cmdrTerritory.ID].ConnectedTo.Keys.ConcatOne(cmdrTerritory.ID) .Where(o => bot.Standing.Territories[o].OwnerPlayerID == bot.PlayerID || bot.Standing.Territories[o].NumArmies.DefensePower <= 4) //don't go somewhere that's defended heavily .ToDictionary(o => o, o => bot.DistanceFromEnemy(o)); AILog.Log("SpecialUnits", "Commander run options: " + terrDistances.Select(o => bot.TerrString(o.Key) + " dist=" + o.Value).JoinStrings(", ")); var sorted = terrDistances.OrderByDescending(o => o.Value).ToList(); sorted.RemoveWhere(o => o.Value < sorted[0].Value); var runTo = bot.UseRandomness ? sorted.Random().Key : sorted[0].Key; if (runTo == cmdrTerritory.ID) { return; //already there } AILog.Log("SpecialUnits", "Moving commander from " + bot.TerrString(cmdrTerritory.ID) + " to " + bot.TerrString(runTo)); bot.Orders.AddAttack(cmdrTerritory.ID, runTo, AttackTransferEnum.AttackTransfer, cmdrTerritory.NumArmies.NumArmies + toDeploy, false, commanders: true); }