private Moves CalculateDefendTerritoryMoves(BotTerritory territoryToDefend, int maxDeployment, bool useBackgroundArmies, int step, BotTerritory.DeploymentType lowerConservativeLevel, BotTerritory.DeploymentType upperConservativeLevel) { var outvar = new Moves(); var maxAttackingArmies = 0; var currentDeployment = 0; foreach (var opponentNeighbor in territoryToDefend.GetOpponentNeighbors()) { currentDeployment += opponentNeighbor.GetTotalDeployment(lowerConservativeLevel); var opponentArmies = opponentNeighbor.GetArmiesAfterDeployment(lowerConservativeLevel).AttackPower; var upperOpponentArmies = opponentNeighbor.GetArmiesAfterDeployment(upperConservativeLevel).AttackPower; var deploymentDifference = upperOpponentArmies - opponentArmies; for (var i = 0; i < step; i++) { if (deploymentDifference > 0) { deploymentDifference--; opponentArmies++; currentDeployment++; } } var idleArmies = opponentArmies - 1; maxAttackingArmies += idleArmies; } // Adjust stuff so opponent can't deploy eyerything to every territory var maxOpponentDeployment = territoryToDefend.GetOpponentNeighbors().Select(o => o.OwnerPlayerID).Distinct().Max(o => BotState.GetGuessedOpponentIncome(o, BotState.VisibleMap)); var deploymentDifference_1 = maxOpponentDeployment - currentDeployment; maxAttackingArmies -= deploymentDifference_1; var opponentKills = SharedUtility.Round(maxAttackingArmies * BotState.Settings.OffenseKillRate); var ownArmies = territoryToDefend.GetArmiesAfterDeploymentAndIncomingMoves().DefensePower; var missingArmies = Math.Max(0, opponentKills - ownArmies + 1); // First try to pull in more armies if (missingArmies > 0 && useBackgroundArmies) { var neighborsWithIdleArmies = GetNeighborsWithIdleArmies(territoryToDefend); foreach (var neighbor in neighborsWithIdleArmies) { var armiesToTransfer = Math.Min(missingArmies, neighbor.GetIdleArmies().NumArmies); if (armiesToTransfer > 0) { outvar.AddOrder(new BotOrderAttackTransfer(BotState.Me.ID, neighbor, territoryToDefend, new Armies(armiesToTransfer), "DefendTerritoryTask")); missingArmies -= armiesToTransfer; } } } // Then try to deploy if (missingArmies <= maxDeployment && missingArmies > 0) { outvar.AddOrder(new BotOrderDeploy(BotState.Me.ID, territoryToDefend, missingArmies)); } else if (missingArmies > maxDeployment) { return(null); } return(outvar); }
/// <summary>Calculates the expansion territory value for a territory.</summary> /// <remarks>Calculates the expansion territory value for a territory.</remarks> /// <param name="territory">the territory which can be part of an arbitrary map</param> /// <param name="mapToWriteIn">the map in which the calculated territory value is to be inserted /// </param> private void CalculateExpansionTerritoryValue(BotTerritory territory, BotMap mapToWriteIn) { var currentValue = 0; var neighborsWithinBonus = territory.GetNeighborsWithinSameBonus(); // Add 1000 for each unknown neighbor within the same Bonus foreach (var neighbor in neighborsWithinBonus) { if (neighbor.OwnerPlayerID == TerritoryStanding.NeutralPlayerID && neighbor.GetOwnedNeighbors().Count == 0) { currentValue += 1000; } } // Add 100 for each neighbor within the same Bonus foreach (var neighbor_1 in neighborsWithinBonus) { if (neighbor_1.OwnerPlayerID == TerritoryStanding.NeutralPlayerID) { currentValue += 100; } } // Add 10 for each opponent neighbor currentValue += 10 * territory.GetOpponentNeighbors().Count; // Add 1 for each neutral neighbor in another Bonus foreach (var neighbor_2 in territory.Neighbors) { if (neighbor_2.OwnerPlayerID == TerritoryStanding.NeutralPlayerID && !neighborsWithinBonus.Contains(neighbor_2)) { currentValue += 1; } } mapToWriteIn.Territories[territory.ID].ExpansionTerritoryValue = currentValue; }
/// <summary>Returns the needed moves to defend the territory.</summary> /// <remarks> /// Returns the needed moves to defend the territory. If not possible then returns null. If no defense needed returns /// empty moves. First tries to fulfill the needed armies with background armies. /// </remarks> /// <param name="territoryToDefend"></param> /// <param name="maxDeployment"></param> /// <returns></returns> public Moves CalculateDefendTerritoryTask(BotTerritory territoryToDefend, int maxDeployment, bool useBackgroundArmies, BotTerritory.DeploymentType lowerConservativeLevel, BotTerritory.DeploymentType upperConservativeLevel) { var outvar = new Moves(); var oppNeighbors = territoryToDefend.GetOpponentNeighbors(); if (oppNeighbors.Count == 0) { return(null); } var maxOpponentDeployment = oppNeighbors.Select(o => o.OwnerPlayerID).Distinct().Max(o => BotState.GetGuessedOpponentIncome(o, BotState.VisibleMap)); for (var i = 0; i < maxOpponentDeployment; i++) { var defendMoves = CalculateDefendTerritoryMoves(territoryToDefend, maxDeployment, useBackgroundArmies, i, lowerConservativeLevel, upperConservativeLevel); if (defendMoves != null) { outvar = defendMoves; } else { return(outvar); } } return(null); }
private bool CanAnyOpponentAttackTerritory(BotTerritory ourTerritory) { var oppNeighbors = ourTerritory.GetOpponentNeighbors(); if (oppNeighbors.Count == 0) { return(false); } foreach (var group in oppNeighbors.GroupBy(o => o.OwnerPlayerID)) { var opponentIncome = BotState.GetGuessedOpponentIncome(group.Key, BotState.VisibleMap); var ourArmies = ourTerritory.Armies; var opponentAttackingArmies = opponentIncome; foreach (var opponentNeighbor in group) { opponentAttackingArmies += opponentNeighbor.Armies.AttackPower - BotState.MustStandGuardOneOrZero; } if (Math.Round(opponentAttackingArmies * BotState.Settings.OffensiveKillRate) >= Math.Round(ourArmies.DefensePower * BotState.Settings.DefensiveKillRate)) { return(true); } } return(false); }
private bool CanOpponentAttackTerritory(PlayerIDType opponentID, BotTerritory ourTerritory) { if (ourTerritory.GetOpponentNeighbors().Count == 0) { return(false); } var opponentIncome = BotState.GetGuessedOpponentIncome(opponentID, BotState.VisibleMap); var ourArmies = ourTerritory.Armies; var opponentAttackingArmies = opponentIncome; foreach (var opponentNeighbor in ourTerritory.GetOpponentNeighbors()) { opponentAttackingArmies += opponentNeighbor.Armies.AttackPower - BotState.MustStandGuardOneOrZero; } return(Math.Round(opponentAttackingArmies * BotState.Settings.OffensiveKillRate) >= Math.Round(ourArmies.DefensePower * BotState.Settings.DefensiveKillRate)); }
private static BotTerritory GetBestSeriouslyAttackedNeighbor(BotTerritory ourTerritory) { BotTerritory outvar = null; var bestNeighborAttackValue = -1; foreach (var opponentNeighbor in ourTerritory.GetOpponentNeighbors()) { if (IsTerritorySeriouslyAttacked(opponentNeighbor) && opponentNeighbor.AttackTerritoryValue > bestNeighborAttackValue) { bestNeighborAttackValue = opponentNeighbor.AttackTerritoryValue; outvar = opponentNeighbor; } } return(outvar); }
/// <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); }
/// <remarks>Calculates the attack territory values.</remarks> /// <param name="territory">allowed are neutral and opponent territories</param> public void CalculateAttackTerritoryValue(BotTerritory territory, BotMap mapToWriteIn ) { var currentValue = 0; // Add 100.000 * armies reward to the value if it's a spot in an // opponent Bonus if (territory.Bonuses.Any(o => o.IsOwnedByAnyOpponent())) { currentValue += LOWEST_HIGH_PRIORITY_VALUE * territory.Bonuses.Sum(o => o.Amount); } // Add 1000 to the value for each bordering own Bonus currentValue += territory.AttackTerritoryValue + LOWEST_MEDIUM_PRIORITY_VALUE * territory.GetAmountOfBordersToOwnBonus(); // Add 1000 to the value for each bordering opponent Bonus currentValue += LOWEST_MEDIUM_PRIORITY_VALUE * territory.GetAmountOfBordersToOpponentBonus(); foreach (var bonus in territory.Bonuses) { // Add 1000 * armies reward for the opponent having all but one neutral spot in the Bonus var neutralArmiesInBonus = bonus.NeutralArmies.DefensePower; var amountOfOwnedTerritories = bonus.GetOwnedTerritories().Count; if (amountOfOwnedTerritories == 0 && neutralArmiesInBonus <= 2 && neutralArmiesInBonus > 0) { currentValue += bonus.Amount * LOWEST_MEDIUM_PRIORITY_VALUE; } } // Add up to 30 to the armies reward for being close to an opponent // Bonus if (territory.DistanceToOpponentBonus == 1) { currentValue += 30; } else if (territory.DistanceToOpponentBonus == 2) { currentValue += 20; } else if (territory.DistanceToOpponentBonus == 3) { currentValue += 10; } // Add up to 30 to the armies reward for being close to an own bonus if (territory.DistanceToOwnBonus == 1) { currentValue += 30; } else if (territory.DistanceToOwnBonus == 2) { currentValue += 20; } else if (territory.DistanceToOwnBonus == 3) { currentValue += 10; } // Add 1 to the value for each opponent bordering territory currentValue += 1 * territory.GetOpponentNeighbors().Count; foreach (var vmBonus in territory.Bonuses) { // Add 10 - the amount of neutrals in the Bonus currentValue += Math.Max(0, 10 - vmBonus.NeutralArmies.DefensePower); // Add stuff if the opponent seems to currently expand in that Bonus if (BotState.NumberOfTurns > 0 && vmBonus.GetOwnedTerritories ().Count == 0 && vmBonus.Amount > 0 && !vmBonus.IsOwnedByAnyOpponent()) { var opponentIsExpanding = false; foreach (var opponentTerritory in vmBonus.GetVisibleOpponentTerritories()) { var lwmTerritory = BotMain.LastVisibleMap.Territories[opponentTerritory.ID]; if (lwmTerritory.IsVisible && lwmTerritory.OwnerPlayerID == TerritoryStanding.NeutralPlayerID) { opponentIsExpanding = true; } } if (opponentIsExpanding) { if (vmBonus.NeutralArmies.DefensePower <= 2) { currentValue += vmBonus.Amount * 30; } else if (vmBonus.NeutralArmies.DefensePower <= 4) { currentValue += vmBonus.Amount * 10; } else { currentValue += vmBonus.Amount * 5; } } } } currentValue *= ATTACK_ADJUSTMENT_FACTOR; mapToWriteIn.Territories[territory.ID].AttackTerritoryValue = currentValue; }