public static Moves CalculateGuessedOpponentTakeOverMoves(BotMain state, List <BotTerritory> territories, PlayerIDType opponentID, bool doesOpponentDeploy, BotTerritory.DeploymentType conservativeLevel) { var opponentIncome = state.Settings.MinimumArmyBonus; if (conservativeLevel == BotTerritory.DeploymentType.Conservative) { opponentIncome = state.GetGuessedOpponentIncome(opponentID, state.VisibleMap); } var ownedTerritories = territories.Where(o => o.OwnerPlayerID == state.Me.ID).ToList(); var opponentAttacks = CalculateMinimumOpponentMoves(state, opponentID, ownedTerritories, conservativeLevel); if (opponentAttacks.GetTotalDeployment() > opponentIncome) { return(null); } if (doesOpponentDeploy) { var remainingOpponentIncome = opponentIncome - opponentAttacks.GetTotalDeployment(); while (remainingOpponentIncome > 0 && opponentAttacks.Orders.OfType <BotOrderAttackTransfer>().Any()) { foreach (var atm in opponentAttacks.Orders.OfType <BotOrderAttackTransfer>()) { atm.Armies = atm.Armies.Add(new Armies(1)); remainingOpponentIncome--; if (remainingOpponentIncome == 0) { break; } } } } return(opponentAttacks); }
/// <summary>Returns null if not possible to defend all territories and not the acceptNotAllDefense flag is set. /// </summary> public Moves CalculateDefendTerritoriesTask(List <BotTerritory> territoriesToDefend, int maxDeployment, bool acceptNotAllDefense, BotTerritory.DeploymentType lowerConservativeLevel, BotTerritory.DeploymentType upperConservativeLevel) { var outvar = new Moves(); var sortedDefenceTerritories = BotState.TerritoryValueCalculator.SortDefenseValue(territoriesToDefend); foreach (var territory in sortedDefenceTerritories) { var stillAvailableArmies = maxDeployment - outvar.GetTotalDeployment(); var defendTerritoryMoves = BotState.DefendTerritoryTask.CalculateDefendTerritoryTask(territory, stillAvailableArmies, true, lowerConservativeLevel, upperConservativeLevel); if (defendTerritoryMoves != null) { outvar.MergeMoves(defendTerritoryMoves); } else if (!acceptNotAllDefense) { return(null); } } return(outvar); }
public static Moves CalculatePreventTerritoriesTask(BotMain state, List <BotTerritory> territoriesToPrevent, PlayerIDType opponentID, int maxDeployment, BotTerritory.DeploymentType conservativeLevel) { var outvar = new Moves(); if (territoriesToPrevent.Count == 0) { return(outvar); } var opponentAttacks = CalculateGuessedOpponentTakeOverMoves(state, territoriesToPrevent, opponentID, true, conservativeLevel); if (opponentAttacks == null) { return(outvar); } // Just try to prevent the territory with the highest defense territory value var highestDefenceTerritoryValue = 0; BotTerritory highestDefenceValueTerritory = null; foreach (var territory in territoriesToPrevent) { if (territory.OwnerPlayerID == state.Me.ID && territory.DefenceTerritoryValue >= highestDefenceTerritoryValue) { highestDefenceValueTerritory = territory; highestDefenceTerritoryValue = territory.DefenceTerritoryValue; } } var currentArmies = highestDefenceValueTerritory.GetArmiesAfterDeploymentAndIncomingMoves().DefensePower; var attackingArmies = CalculateOpponentAttackingArmies(highestDefenceValueTerritory, opponentAttacks); var minimumNeededArmies = SharedUtility.Round(attackingArmies.AttackPower * state.Settings.OffenseKillRate); //var minimumNeededArmies = SharedUtility.Round(attackingArmies.AttackPower * state.Settings.OffensiveKillRate); var maximumNeededArmies = minimumNeededArmies; var maximumMissingArmies = Math.Max(0, maximumNeededArmies - currentArmies); var minimumMissingArmies = Math.Max(0, minimumNeededArmies - currentArmies); if (maximumMissingArmies <= maxDeployment && maximumMissingArmies > 0) { outvar.AddOrder(new BotOrderDeploy(state.Me.ID, highestDefenceValueTerritory, maximumMissingArmies)); } else if (minimumMissingArmies <= maxDeployment && maxDeployment > 0) { outvar.AddOrder(new BotOrderDeploy(state.Me.ID, highestDefenceValueTerritory, maxDeployment)); } // If no solution then empty moves instead of null return(outvar); }
/// <summary>Calculates the minimum opponent moves that he needs to make if we don't deploy. /// </summary> /// <param name="state"></param> /// <param name="ownedTerritories"></param> /// <returns></returns> private static Moves CalculateMinimumOpponentMoves(BotMain state, PlayerIDType opponentID, List <BotTerritory> ownedTerritories, BotTerritory.DeploymentType conservativeLevel) { var outvar = new Moves(); foreach (var ownedTerritory in ownedTerritories) { var attackingOpponentTerritory = GetOpponentNeighborMaxIdleArmies(state, opponentID, ownedTerritory, outvar); if (attackingOpponentTerritory == null) { continue; } var stilIdleArmies = CalculateStillOpponentIdleArmies(state, attackingOpponentTerritory, outvar); var attackingOpponentArmies = SharedUtility.Round(ownedTerritory.GetArmiesAfterDeploymentAndIncomingAttacks(conservativeLevel).DefensePower / state.Settings.OffenseKillRate); var opponentDeployment = Math.Max(0, attackingOpponentArmies - stilIdleArmies.DefensePower); if (opponentDeployment > 0) { outvar.AddOrder(new BotOrderDeploy(opponentID, attackingOpponentTerritory, opponentDeployment)); } outvar.AddOrder(new BotOrderAttackTransfer(opponentID, attackingOpponentTerritory, ownedTerritory, new Armies(attackingOpponentArmies), "PreventTerritoriesTask")); } // Now let's assume that the opponent doesen't leave armies idle var hasSomethingChanged = true; while (hasSomethingChanged) { hasSomethingChanged = false; foreach (var attackTransferMove in outvar.Orders.OfType <BotOrderAttackTransfer>()) { var stillIdleArmies = CalculateStillOpponentIdleArmies(state, attackTransferMove.From, outvar); if (stillIdleArmies.IsEmpty == false) { hasSomethingChanged = true; attackTransferMove.Armies = attackTransferMove.Armies.Add(new Armies(1)); } } } return(outvar); }
/// <remarks>Returns null if none of the specified territories can get broken.</remarks> /// <param name="territoriesToBreak"></param> /// <param name="maxDeployment"></param> /// <returns></returns> public static Moves CalculateBreakTerritoriesTask(BotMain state, List <BotTerritory> territoriesToBreak, int maxDeployment, BotTerritory.DeploymentType lowerConservativeLevel, BotTerritory.DeploymentType upperConservativeLevel) { var sortedTerritories = state.TerritoryValueCalculator.SortAttackValue(territoriesToBreak ); foreach (var opponentTerritory in sortedTerritories) { var breakTerritoryMoves = state.BreakTerritoryTask.CalculateBreakTerritoryTask(opponentTerritory, maxDeployment, lowerConservativeLevel, upperConservativeLevel, "CalculateBreakTerritoriesTask"); if (breakTerritoryMoves != null) { return(breakTerritoryMoves); } } return(null); }
private void CalculateXBonusMoves(Moves moves, BotTerritory.DeploymentType lowerBoundConservative, BotTerritory.DeploymentType upperBoundConservative) { var solutionFound = true; List <BotBonus> alreadyHandledBonuses = new List <BotBonus>(); while (solutionFound) { solutionFound = false; BotState.BonusValueCalculator.CalculateBonusValues(BotState.WorkingMap, BotState.VisibleMap); BotState.TerritoryValueCalculator.CalculateTerritoryValues(BotState.VisibleMap, BotState.WorkingMap); List <BotBonus> bonusesToX = BotState.BonusValueCalculator.GetSortedBonusesAdjustedFactor(BotState.VisibleMap); //bonusesToX.RemoveAll(alreadyHandledBonuses); bonusesToX.RemoveAll(i => alreadyHandledBonuses.Contains(i)); foreach (var bonus in bonusesToX) { alreadyHandledBonuses.Add(bonus); var stillAvailableDeployment = BotState.MyIncome.Total - moves.GetTotalDeployment(); var plan = BotState.BonusValueCalculator.GetPlanForBonus(bonus); if (plan == BonusPlan.Break) { var visibleTerritories = bonus.GetVisibleOpponentTerritories(); var breakBonusMoves = BreakTerritoriesTask.CalculateBreakTerritoriesTask(BotState, visibleTerritories, stillAvailableDeployment, lowerBoundConservative, upperBoundConservative); if (breakBonusMoves != null) { MovesCommitter.CommittMoves(BotState, breakBonusMoves); moves.MergeMoves(breakBonusMoves); solutionFound = true; break; } } else if (plan == BonusPlan.Defend) { var defendBonusMoves = DefendBonusTask.CalculateDefendBonusTask(BotState, bonus, stillAvailableDeployment, false, (BotTerritory.DeploymentType)Math.Max(1, (int)lowerBoundConservative), (BotTerritory.DeploymentType)Math.Max(1, (int)upperBoundConservative)); if (defendBonusMoves != null) { MovesCommitter.CommittMoves(BotState, defendBonusMoves); moves.MergeMoves(defendBonusMoves); solutionFound = true; break; } } else if (plan == BonusPlan.TakeOver) { var takeOverMoves = TakeBonusOverTask.CalculateTakeBonusOverTask(BotState, stillAvailableDeployment, bonus, lowerBoundConservative); if (takeOverMoves != null) { MovesCommitter.CommittMoves(BotState, takeOverMoves); moves.MergeMoves(takeOverMoves); solutionFound = true; break; } } else if (plan == BonusPlan.PreventTakeOver && bonus.PreventTakeOverOpponent.HasValue) { var preventTakeOverMoves = PreventBonusTask.CalculatePreventBonusTask(BotState, bonus, bonus.PreventTakeOverOpponent.Value, stillAvailableDeployment, lowerBoundConservative); MovesCommitter.CommittMoves(BotState, preventTakeOverMoves); moves.MergeMoves(preventTakeOverMoves); solutionFound = true; break; } else { throw new Exception("Unexpected plan"); } } } }
private void CalculateNoPlanBreakDefendMoves(Moves moves, bool lowImportance, bool mediumImportance, bool highImportance, BotTerritory.DeploymentType lowerConservative, BotTerritory.DeploymentType upperConservative) { List <BotTerritory> territoriesToDefend = new List <BotTerritory>(); foreach (var territory in BotState.VisibleMap.GetOwnedTerritories()) { var importance = territory.DefenceTerritoryValue; var lowImportant = importance < TerritoryValueCalculator.LOWEST_MEDIUM_PRIORITY_VALUE; var mediumImportant = importance < TerritoryValueCalculator.LOWEST_HIGH_PRIORITY_VALUE && importance >= TerritoryValueCalculator.LOWEST_MEDIUM_PRIORITY_VALUE; var highImportant = importance >= TerritoryValueCalculator.LOWEST_HIGH_PRIORITY_VALUE; if ((lowImportance && lowImportant) || (mediumImportance && mediumImportant) || (highImportance && highImportant)) { territoriesToDefend.Add(territory); } } var possibleTerritoriesToAttack = new List <BotTerritory>(); foreach (var opponentTerritory in BotState.VisibleMap.Territories.Values.Where(o => o.IsVisible && BotState.IsOpponent(o.OwnerPlayerID))) { var wmOpponentTerritory = BotState.WorkingMap.Territories[opponentTerritory.ID]; if (BotState.IsOpponent(wmOpponentTerritory.OwnerPlayerID)) { possibleTerritoriesToAttack.Add(opponentTerritory); } } var territoriesToAttack = new List <BotTerritory>(); foreach (var territory_1 in possibleTerritoriesToAttack) { var importance = territory_1.AttackTerritoryValue; var lowImportant = importance < TerritoryValueCalculator.LOWEST_MEDIUM_PRIORITY_VALUE; var mediumImportant = importance < TerritoryValueCalculator.LOWEST_HIGH_PRIORITY_VALUE && importance >= TerritoryValueCalculator.LOWEST_MEDIUM_PRIORITY_VALUE; var highImportant = importance >= TerritoryValueCalculator.LOWEST_HIGH_PRIORITY_VALUE; if ((lowImportance && lowImportant) || (mediumImportance && mediumImportant) || (highImportance && highImportant)) { territoriesToAttack.Add(territory_1); } } var combinedTerritories = new List <BotTerritory>(); combinedTerritories.AddRange(territoriesToDefend); combinedTerritories.AddRange(territoriesToAttack); var sortedTerritories = BotState.TerritoryValueCalculator.SortTerritoriesAttackDefense(combinedTerritories); foreach (var territory_2 in sortedTerritories) { var maxDeployment = BotState.MyIncome.Total - moves.GetTotalDeployment(); Moves defendBreakMoves = null; if (territory_2.OwnerPlayerID == BotState.Me.ID) { defendBreakMoves = BotState.DefendTerritoryTask.CalculateDefendTerritoryTask(territory_2, maxDeployment, true, lowerConservative, upperConservative); } else { defendBreakMoves = BotState.BreakTerritoryTask.CalculateBreakTerritoryTask(territory_2, maxDeployment, lowerConservative, upperConservative, "CalculateNoPlanBreakDefendMoves"); } if (defendBreakMoves != null) { MovesCommitter.CommittMoves(BotState, defendBreakMoves); moves.MergeMoves(defendBreakMoves); } } }