/// <summary>Updates the working map according to the move input</summary> /// <param name="attackTransferMove"></param> public void UpdateMap(BotOrderAttackTransfer attackTransferMove, BotMap mapToUpdate, BotTerritory.DeploymentType conservativeLevel) { var toTerritoryID = attackTransferMove.To.ID; var wmTerritory = BotState.WorkingMap.Territories[toTerritoryID]; var vmTerritory = BotState.VisibleMap.Territories[toTerritoryID]; var toBeKilledArmies = vmTerritory.GetArmiesAfterDeployment(BotTerritory.DeploymentType.Normal); var attackingArmies = vmTerritory.GetIncomingArmies(); if (vmTerritory.getOwnKills(attackingArmies.AttackPower, toBeKilledArmies.DefensePower) >= toBeKilledArmies.DefensePower) { wmTerritory.OwnerPlayerID = BotState.Me.ID; } }
/// <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); }
/// <param name="maxMovesBeforeRiskyAttack">the maximum amount of moves that should happen before the first risky attack. /// </param> /// <returns></returns> public static Moves CalculateDelayTask(BotMain state, Moves movesSoFar, int maxMovesBeforeRiskyAttack, int minMovesBeforeRiskyAttack) { var outvar = new Moves(); if (!IsRiskyAttackPresent(state, movesSoFar)) { return(outvar); } var amountOfSafeMoves = CalculateAmountOfSafeMoves(state, movesSoFar); // Step 1: Try to move armies next to neutral territories. // Step 1: Try to move armies next to neutral territories. var maximumNewDelays = Math.Max(0, maxMovesBeforeRiskyAttack - amountOfSafeMoves); foreach (var territory in state.VisibleMap.GetNonOpponentBorderingBorderTerritories()) { var ownedNeighbors = territory.GetOwnedNeighbors(); var sortedDistanceNeighbors = state.VisibleMap.SortTerritoriesDistanceToBorder (ownedNeighbors); var maxPossibleDelays = Math.Min(sortedDistanceNeighbors.Count, territory.GetIdleArmies().NumArmies); var delaysToAdd = Math.Min(maximumNewDelays, maxPossibleDelays); for (var i = 0; i < delaysToAdd; i++) { var territoryToTransferTo = sortedDistanceNeighbors[i]; var atm = new BotOrderAttackTransfer(state.Me.ID, territory, territoryToTransferTo, new Armies(1), "DelayTask"); outvar.AddOrder(atm); maximumNewDelays--; } } // Step 2: If the minMovesBeforeRiskyAttack constraint isn't fulfilled // then also add delay moves next to the opponent var stillNeededDelays = Math.Max(0, minMovesBeforeRiskyAttack - (amountOfSafeMoves + outvar.Orders.OfType <BotOrderAttackTransfer>().Count())); foreach (var territory_1 in state.VisibleMap.GetOpponentBorderingTerritories()) { var ownedNeighbors = territory_1.GetOwnedNeighbors(); var sortedDistanceNeighbors = state.VisibleMap.SortTerritoriesDistanceToBorder (ownedNeighbors); var maxPossibleDelays = Math.Min(sortedDistanceNeighbors.Count, territory_1.GetIdleArmies().NumArmies); var delaysToAdd = Math.Min(stillNeededDelays, maxPossibleDelays); for (var i = 0; i < delaysToAdd; i++) { var territoryToTransferTo = sortedDistanceNeighbors[i]; var atm = new BotOrderAttackTransfer(state.Me.ID, territory_1, territoryToTransferTo, new Armies(1), "DelayTask2"); outvar.AddOrder(atm); stillNeededDelays--; } } return(outvar); }
public static Moves CalculateJoinStackMoves(BotMain state) { // Calculate the border territories and the territories bordering border territories var outvar = new Moves(); var possibleFromTerritories = new HashSet <BotTerritory>(); possibleFromTerritories.AddRange(state.VisibleMap.GetBorderTerritories()); var temp = new HashSet <BotTerritory>(); foreach (var territory in possibleFromTerritories) { temp.AddRange(territory.GetOwnedNeighbors()); } possibleFromTerritories.AddRange(temp); // Calculate which territories use for transferring List <BotTerritory> goodTransferTerritories = new List <BotTerritory>(); foreach (var possibleFromTerritory in possibleFromTerritories) { if (possibleFromTerritory.GetOpponentNeighbors().Count == 0 || possibleFromTerritory.DefenceTerritoryValue < TerritoryValueCalculator.LOWEST_HIGH_PRIORITY_VALUE) { goodTransferTerritories.Add(possibleFromTerritory); } } // Calculate where to transfer to foreach (var territory_1 in goodTransferTerritories) { if (territory_1.GetOwnedNeighbors().Count > 0 && territory_1.GetIdleArmies().IsEmpty == false) { var territoryValue = territory_1.DefenceTerritoryValue; BotTerritory bestNeighbor = null; var bestNeighborValue = -1; foreach (var neighbor in territory_1.GetOwnedNeighbors()) { if (neighbor.GetOpponentNeighbors().Count > 0 && neighbor.DefenceTerritoryValue > bestNeighborValue) { bestNeighbor = neighbor; bestNeighborValue = neighbor.DefenceTerritoryValue; } } if (bestNeighbor != null && bestNeighborValue > territoryValue) { var atm = new BotOrderAttackTransfer(state.Me.ID, territory_1, bestNeighbor, territory_1.GetIdleArmies(), "TransferMovesChooser1"); outvar.AddOrder(atm); } } } return(outvar); }
private static bool IsAddingArmiesBeneficial(BotOrderAttackTransfer expansionMove) { var isBeneficial = true; var containsToTerritoryOpponentNeighbor = expansionMove.To.GetOpponentNeighbors ().Count > 0 ? true : false; var containsFromTerritoryOpponentBorderingNeighbor = false; foreach (var ownedNeighbor in expansionMove.From.GetOwnedNeighbors()) { if (ownedNeighbor.GetOpponentNeighbors().Count > 0) { containsFromTerritoryOpponentBorderingNeighbor = true; } } if (containsToTerritoryOpponentNeighbor == false && containsFromTerritoryOpponentBorderingNeighbor == true) { isBeneficial = false; } return(isBeneficial); }
/// <param name="expansionMoves">only moves where the toTerritory is neutral are allowed /// </param> /// <returns></returns> private static BotOrderAttackTransfer GetBestExpansionMoveToAddArmies(List <BotOrderAttackTransfer> expansionMoves) { BotOrderAttackTransfer bestExpansionMove = null; List <BotOrderAttackTransfer> expansionMovesToOpponent = new List <BotOrderAttackTransfer >(); foreach (BotOrderAttackTransfer atm in expansionMoves) { if (atm.To.GetOpponentNeighbors().Count > 0) { expansionMovesToOpponent.Add(atm); } } if (expansionMovesToOpponent.Count > 0) { bestExpansionMove = expansionMovesToOpponent[0]; foreach (BotOrderAttackTransfer atm_1 in expansionMovesToOpponent) { if (atm_1.To.AttackTerritoryValue > bestExpansionMove.To.AttackTerritoryValue) { bestExpansionMove = atm_1; } } } else { if (expansionMoves.Count > 0) { bestExpansionMove = expansionMoves[0]; foreach (BotOrderAttackTransfer atm_1 in expansionMoves) { if (atm_1.To.GetNonOwnedNeighbors().Count > bestExpansionMove.To.GetNonOwnedNeighbors().Count) { bestExpansionMove = atm_1; } } } } return(bestExpansionMove); }