/// <summary>Returns whether it makes sense to perform an unplanned expansion step from our territory to the neutral territory. /// </summary> /// <remarks> /// Returns whether it makes sense to perform an unplanned expansion step from our territory to the neutral territory. The /// parameters considered therefore are the distance to the opponent and whether we can take that territory. /// </remarks> /// <param name="fromTerritory">an owned territory, not bordering the opponent</param> /// <param name="toTerritory">a neutral territory</param> /// <returns></returns> private static bool IsUnplannedExpansionStepSmart(BotMain state, BotTerritory fromTerritory, BotTerritory toTerritory) { var isSmart = true; if (fromTerritory.GetIdleArmies().AttackPower <= 1) { isSmart = false; } if (toTerritory.Armies.DefensePower > toTerritory.getOwnKills(fromTerritory.GetIdleArmies().AttackPower, toTerritory.Armies.DefensePower)) { isSmart = false; } var distanceCondition1 = fromTerritory.DistanceToOpponentBorder <= 4; var distanceCondition2 = toTerritory.GetOpponentNeighbors().Count == 0; if (distanceCondition1 && distanceCondition2) { isSmart = false; } return(isSmart); }
/// <summary>We only try to perform 1 attack to a high ranked territory where an attack is possible. /// </summary> /// <remarks> /// We only try to perform 1 attack to a high ranked territory where an attack is possible. For multiple attacks this /// function has to be called multiple times. /// </remarks> /// <param name="attackLowImportantTerritories"></param> /// <param name="attackMediumImportantTerritories"></param> /// <param name="attackHighImportantTerritories"></param> /// <returns></returns> public static Moves CalculateNoPlanTryoutAttackTask(BotMain state, bool attackLowImportantTerritories, bool attackMediumImportantTerritories, bool attackHighImportantTerritories) { var possibleAttackTerritories = GetPossibleTerritoriesToAttack(state, attackLowImportantTerritories, attackMediumImportantTerritories, attackHighImportantTerritories); var sortedPossibleAttackTerritories = state.TerritoryValueCalculator.SortAttackValue (possibleAttackTerritories); foreach (var territoryToAttack in sortedPossibleAttackTerritories) { var neededNewArmies = 0; var ownedNeighbors = territoryToAttack.GetOwnedNeighbors(); var sortedOwnedNeighbors = state.TerritoryValueCalculator.SortDefenseValue(ownedNeighbors); BotTerritory bestNeighbor = null; for (var i = sortedOwnedNeighbors.Count - 1; i >= 0; i--) { var smallAttackPresent = IsTerritoryAttackingOpponentTerritorySmall(ownedNeighbors[i], territoryToAttack); if (smallAttackPresent) { neededNewArmies = territoryToAttack.Armies.DefensePower; } else { neededNewArmies = territoryToAttack.Armies.DefensePower + 1; } if (ownedNeighbors[i].GetIdleArmies().NumArmies >= neededNewArmies) { bestNeighbor = ownedNeighbors[i]; break; } } if (bestNeighbor != null) { var outvar = new Moves(); if (bestNeighbor.GetIdleArmies().NumArmies > 2) { var atm = new BotOrderAttackTransfer(state.Me.ID, bestNeighbor, territoryToAttack, new Armies(3), "NoPlanTryoutAttackTask"); atm.Message = AttackMessage.TryoutAttack; outvar.AddOrder(atm); return(outvar); } else { var atm = new BotOrderAttackTransfer(state.Me.ID, bestNeighbor, territoryToAttack, new Armies(neededNewArmies), "NoPlanTryoutAttackTask"); atm.Message = AttackMessage.TryoutAttack; outvar.AddOrder(atm); return(outvar); } } } return(null); }
/// <summary>Calculates the amount of idle armies on the territory after the already made expansion decisions. /// </summary> /// <param name="territory"></param> /// <param name="expansionDecisions"></param> /// <returns></returns> private Armies GetOverflowIdleArmies(BotTerritory territory, Moves expansionDecisions) { var outvar = territory.GetIdleArmies(); foreach (var placeArmiesMove in expansionDecisions.Orders.OfType <BotOrderDeploy>()) { if (placeArmiesMove.Territory.ID == territory.ID) { outvar = outvar.Add(new Armies(placeArmiesMove.Armies)); } } foreach (var expansionMove in expansionDecisions.Orders.OfType <BotOrderAttackTransfer>()) { if (expansionMove.From.ID == territory.ID) { outvar = outvar.Subtract(expansionMove.Armies); } } return(outvar); }