private Moves CalculateAttackNeutralMoves(BotTerritory neutralTerritory, int maxDeployment) { Moves outvar = null; var neededAttackArmies = neutralTerritory.getNeededBreakArmies(neutralTerritory.Armies.DefensePower); var ownedNeighbors = neutralTerritory.GetOwnedNeighbors(); var bestNeighbor = ownedNeighbors[0]; foreach (var ownedNeighbor in ownedNeighbors) { if (ownedNeighbor.GetIdleArmies().AttackPower > bestNeighbor.GetIdleArmies().ArmiesOrZero) { bestNeighbor = ownedNeighbor; } } var neededDeployment = Math.Max(0, neededAttackArmies - bestNeighbor.GetIdleArmies().ArmiesOrZero); if (neededDeployment <= maxDeployment) { outvar = new Moves(); if (neededDeployment > 0) { outvar.AddOrder(new BotOrderDeploy(BotState.Me.ID, bestNeighbor, neededDeployment)); } var atm = new BotOrderAttackTransfer(BotState.Me.ID, bestNeighbor, neutralTerritory, new Armies(neededAttackArmies), "PreventOpponentExpandBonusTask"); // TODO bad? if (bestNeighbor.GetOpponentNeighbors().Count == 0) { atm.Message = AttackMessage.Snipe; } outvar.AddOrder(atm); } return(outvar); }
public static Moves CalculateBreakTerritoryTask(BotMain state, BotTerritory opponentTerritory, int maxDeployment, BotTerritory.DeploymentType conservativeLevel) { var outvar = new Moves(); var opponentArmies = opponentTerritory.GetArmiesAfterDeploymentAndIncomingAttacks(conservativeLevel); var neededAttackArmies = opponentTerritory.getNeededBreakArmies(opponentArmies.DefensePower); var ownedNeighbors = opponentTerritory.GetOwnedNeighbors(); var presortedOwnedNeighbors = state.TerritoryValueCalculator.SortDefenseValue(ownedNeighbors); var sortedOwnedNeighbors = BotMap.GetOrderedListOfTerritoriesByIdleArmies(presortedOwnedNeighbors); var territoryToUse = sortedOwnedNeighbors[0]; var idleArmies = territoryToUse.GetIdleArmies(); var neededDeployment = Math.Max(0, neededAttackArmies - idleArmies.AttackPower); if (neededDeployment > maxDeployment) { return(null); } if (neededDeployment > 0) { outvar.AddOrder(new BotOrderDeploy(state.Me.ID, territoryToUse, neededDeployment)); } Armies attackArmies = new Armies(neededAttackArmies); //var atm = new BotOrderAttackTransfer(state.Me.ID, territoryToUse, opponentTerritory, idleArmies.Add(new Armies(neededDeployment)), "OneHitBreakTerritoryTask"); var atm = new BotOrderAttackTransfer(state.Me.ID, territoryToUse, opponentTerritory, attackArmies, "OneHitBreakTerritoryTask"); outvar.AddOrder(atm); return(outvar); }
/// <summary>Calculates the necessary moves to take the specified territories to take.</summary> /// <param name="maxDeployment">the maximum allowed deployment. If no deployment constraint then put -1. /// </param> /// <param name="territoriesToTake">the territories that should be taken this turn.</param> /// <returns>the necessary moves to take the territories or null if no solution was found. /// </returns> public Moves CalculateTakeTerritoriesTask(int maxDeployment, List <BotTerritory> territoriesToTake, BotTerritory.DeploymentType conservativeLevel, string attackSource) { var outvar = new Moves(); if (maxDeployment == -1) { maxDeployment = int.MaxValue; } var stillAvailableDeployment = maxDeployment; foreach (var missingTerritory in territoriesToTake) { var bestNeighborTerritory = GetBestNeighborTerritory(missingTerritory, outvar, territoriesToTake); var missingTerritoryArmies = missingTerritory.GetArmiesAfterDeploymentAndIncomingAttacks(conservativeLevel); var neededAttackArmies = missingTerritory.getNeededBreakArmies(missingTerritory.Armies.DefensePower); //var neededAttackArmies = (int)Math.Round(missingTerritoryArmies.DefensePower / BotState.Settings.OffensiveKillRate); var missingArmies = GetMissingArmies(bestNeighborTerritory, missingTerritory, outvar, conservativeLevel); if (missingArmies > stillAvailableDeployment) { return(null); } if (missingArmies > 0) { var pam = new BotOrderDeploy(BotState.Me.ID, bestNeighborTerritory, missingArmies); outvar.AddOrder(pam); stillAvailableDeployment -= missingArmies; } outvar.AddOrder(new BotOrderAttackTransfer(BotState.Me.ID, bestNeighborTerritory, missingTerritory, new Armies(neededAttackArmies), attackSource)); } return(outvar); }
public static void PlayCards(BotMain state, Moves moves) { if (state.Me.Team != PlayerInvite.NoTeam && state.Players.Values.Any(o => state.IsTeammate(o.ID) && !o.IsAIOrHumanTurnedIntoAI && o.State == GamePlayerState.Playing && !o.HasCommittedOrders)) { return; //If there are any humans on our team that have yet to take their turn, do not play cards. } //For now, just play all reinforcement cards, and discard if we must use any others. var teammatesOrders = state.TeammatesOrders.Values.Where(o => o.Orders != null).SelectMany(o => o.Orders); var cardsPlayedByTeammate = teammatesOrders.OfType <GameOrderPlayCard>().Select(o => o.CardInstanceID).Concat(teammatesOrders.OfType <GameOrderDiscard>().Select(o => o.CardInstanceID)).ToHashSet(true); int numMustPlay = state.CardsMustPlay; foreach (var card in state.Cards) { if (cardsPlayedByTeammate.Contains(card.ID)) { continue; } if (card is ReinforcementCardInstance) { moves.AddOrder(new BotOrderGeneric(GameOrderPlayCardReinforcement.Create(card.ID, state.Me.ID))); state.MyIncome.FreeArmies += card.As <ReinforcementCardInstance>().Armies; numMustPlay--; } else if (numMustPlay > 0) //For now, just discard all non-reinforcement cards if we must use the card { moves.AddOrder(new BotOrderGeneric(GameOrderDiscard.Create(state.Me.ID, card.ID))); numMustPlay--; } } }
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); }
/// <param name="opponentTerritory"></param> /// <param name="maxDeployment"></param> /// <returns></returns> public static Moves CalculateAttackTerritoryTask(BotMain state, BotTerritory opponentTerritory, int maxDeployment) { var outvar = new Moves(); var ownedNeighbors = opponentTerritory.GetOwnedNeighbors(); var presortedOwnedNeighbors = state.TerritoryValueCalculator.SortDefenseValue(ownedNeighbors ); var sortedOwnedNeighbors = BotMap.GetOrderedListOfTerritoriesByIdleArmies( presortedOwnedNeighbors); // Calculate the attacks for (var i = 0; i < sortedOwnedNeighbors.Count; i++) { var attackingTerritory = sortedOwnedNeighbors[i]; if (i == 0 && maxDeployment > 0) { var pam = new BotOrderDeploy(state.Me.ID, attackingTerritory, maxDeployment); outvar.AddOrder(pam); if (attackingTerritory.GetIdleArmies().AttackPower + maxDeployment > 1) { var atm = new BotOrderAttackTransfer(state.Me.ID, attackingTerritory, opponentTerritory, attackingTerritory.GetIdleArmies().Add(new Armies(maxDeployment)), "AttackTerritoriesTask1"); outvar.AddOrder(atm); } } else { if (attackingTerritory.GetIdleArmies().AttackPower > 1) { var atm = new BotOrderAttackTransfer(state.Me.ID, attackingTerritory, opponentTerritory, attackingTerritory.GetIdleArmies(), "AttackTerritoriesTask2"); outvar.AddOrder(atm); } } } // Check if we are killing more or equal armies than the opponent // double currentOpponentArmies = opponentTerritory.ArmiesAfterDeployment; var currentOpponentArmies = opponentTerritory.GetArmiesAfterDeploymentAndIncomingAttacks(BotTerritory.DeploymentType.Normal).DefensePower; double opponentKills = 0; double ownKills = 0; foreach (var atm_1 in outvar.Orders.OfType <BotOrderAttackTransfer>()) { int ourKills = opponentTerritory.getOwnKills(atm_1.Armies.AttackPower, currentOpponentArmies); //var ourKills = Math.Min(currentOpponentArmies, atm_1.Armies.AttackPower * state.Settings.OffensiveKillRate); var opponentKillsAttack = Math.Min(atm_1.Armies.AttackPower, currentOpponentArmies * state.Settings.DefenseKillRate); ownKills += ourKills; opponentKills += opponentKillsAttack; currentOpponentArmies = Math.Max(0, currentOpponentArmies - ourKills); } if (ownKills >= opponentKills && outvar.Orders.OfType <BotOrderAttackTransfer>().Any()) { return(outvar); } else { return(null); } }
private Moves CalculateBreakTerritoryMoves(BotTerritory opponentTerritory, int maxDeployment, int opponentDeployment, string source) { var outvar = new Moves(); var opponentArmies = opponentTerritory.Armies.DefensePower; opponentArmies += opponentDeployment; var neededAttackArmies = opponentTerritory.getNeededBreakArmies(opponentArmies); //var neededAttackArmies = SharedUtility.Round(opponentArmies / BotState.Settings.OffensiveKillRate); var ownedNeighbors = opponentTerritory.GetOwnedNeighbors(); var presortedOwnedNeighbors = BotState.TerritoryValueCalculator.SortDefenseValue(ownedNeighbors); var sortedOwnedNeighbors = BotMap.GetOrderedListOfTerritoriesByIdleArmies( presortedOwnedNeighbors); // First deploy and then pull in more territories if necessary. // First deploy and then pull in more territories if necessary. var attackedWithSoFar = 0; for (var i = 0; i < sortedOwnedNeighbors.Count; i++) { if (i == 0) { var neededDeployment = Math.Max(0, neededAttackArmies - sortedOwnedNeighbors[0].GetIdleArmies().NumArmies); var totalDeployment = Math.Min(neededDeployment, maxDeployment); if (totalDeployment > 0) { var pam = new BotOrderDeploy(BotState.Me.ID, sortedOwnedNeighbors[0], totalDeployment); outvar.AddOrder(pam); } var attackingArmies = Math.Min(neededAttackArmies, sortedOwnedNeighbors[0].GetIdleArmies().NumArmies + totalDeployment); outvar.AddOrder(new BotOrderAttackTransfer(BotState.Me.ID, sortedOwnedNeighbors[0], opponentTerritory, new Armies(attackingArmies), source)); attackedWithSoFar += attackingArmies; } else { // i != 0 var stillNeededArmies = neededAttackArmies - attackedWithSoFar; if (stillNeededArmies > 0 && sortedOwnedNeighbors[i].GetIdleArmies().NumArmies > 1) { var newAttackingArmies = Math.Min(stillNeededArmies, sortedOwnedNeighbors[i].GetIdleArmies().NumArmies); outvar.AddOrder(new BotOrderAttackTransfer(BotState.Me.ID, sortedOwnedNeighbors[i], opponentTerritory, new Armies(newAttackingArmies), "BreakTerritoryTask2")); attackedWithSoFar += newAttackingArmies; } } } if (attackedWithSoFar >= neededAttackArmies) { return(outvar); } else { return(null); } }
/// <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 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 = 0d; 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.OffensiveKillRate); //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); }
public static Moves CalculateMoveIdleArmiesTask(BotMain state) { var outvar = new Moves(); foreach (var ownedTerritory in state.VisibleMap.GetOwnedTerritories()) { var outgoingMoves = ownedTerritory.OutgoingMoves; BotOrderAttackTransfer mostImportantMove = null; var currentHighestValue = -1; foreach (var atm in outgoingMoves) { if (state.IsOpponent(atm.To.OwnerPlayerID) && atm.Armies.AttackPower > 1 && atm.Message != AttackMessage.TryoutAttack) { var attackValue = atm.To.AttackTerritoryValue; if (attackValue > currentHighestValue) { currentHighestValue = attackValue; mostImportantMove = atm; } } } var idleArmies = ownedTerritory.GetIdleArmies(); if (mostImportantMove != null && idleArmies.IsEmpty == false) { var atm_1 = new BotOrderAttackTransfer(state.Me.ID, ownedTerritory, mostImportantMove.To, ownedTerritory.GetIdleArmies(), "MoveIdleArmiesTask1"); outvar.AddOrder(atm_1); } } return(outvar); }
// TODO weitermachen private void DeleteBadTransferMoves(Moves movesSoFar) { var interestingTransfers = new List <BotOrderAttackTransfer>(); foreach (var atm in movesSoFar.Orders.OfType <BotOrderAttackTransfer>()) { if (atm.Armies.AttackPower > 1 && atm.To.OwnerPlayerID == BotState.Me.ID && atm.From.GetTotalDeployment(BotTerritory.DeploymentType.Normal) > 0) { interestingTransfers.Add(atm); } } foreach (var atm_1 in interestingTransfers) { var deploymentToShift = Math.Min(atm_1.From.GetTotalDeployment(BotTerritory.DeploymentType.Normal), atm_1.Armies.AttackPower); atm_1.Armies = atm_1.Armies.Subtract(new Armies(deploymentToShift)); var pam = new BotOrderDeploy(BotState.Me.ID, atm_1.To, deploymentToShift); MovesCommitter.CommittPlaceArmiesMove(pam); movesSoFar.AddOrder(pam); foreach (var oldDeployment in atm_1.From.GetDeployment(BotTerritory.DeploymentType.Normal)) { while (deploymentToShift > 0) { if (oldDeployment.Armies > 0) { deploymentToShift--; oldDeployment.Armies = oldDeployment.Armies - 1; } else { break; } } } } }
public static Moves CalculateTransferMoves2(BotMain state) { var outvar = new Moves(); foreach (var territory in state.VisibleMap.GetOwnedTerritories()) { if (territory.GetIdleArmies().IsEmpty == false && territory.GetOpponentNeighbors().Count == 0) { var ownedNeighbors = GetOwnedNeighborsAfterExpansion(state, territory); if (ownedNeighbors.Count > 0) { var bestNeighbor = territory; foreach (var neighbor in ownedNeighbors) { bestNeighbor = GetCloserTerritory(bestNeighbor, neighbor); } if (bestNeighbor != territory) { var atm = new BotOrderAttackTransfer(state.Me.ID, territory, bestNeighbor, territory.GetIdleArmies(), "TransferMovesChooser2"); outvar.AddOrder(atm); } } } } return(outvar); }
public Moves CalculateOneStepExpandBonusTask(int maxDeployment, BotBonus bonus, bool acceptStackOnly, BotMap workingMap, BotTerritory.DeploymentType conservativeLevel) { var outvar = new Moves(); if (maxDeployment == -1) { maxDeployment = 1000; } var visibleNeutralTerritories = bonus.GetVisibleNeutralTerritories(); var territoriesToRemove = new List <BotTerritory>(); foreach (var territory in visibleNeutralTerritories) { if (workingMap.Territories[territory.ID].OwnerPlayerID == BotState.Me.ID) { territoriesToRemove.Add(territory); } } visibleNeutralTerritories.RemoveAll(territoriesToRemove); if (visibleNeutralTerritories.Count == 0) { return(null); } var sortedNeutralTerritories = BotState.TerritoryValueCalculator.SortExpansionValue(visibleNeutralTerritories); var territoryToTake = new List <BotTerritory>(); territoryToTake.Add(sortedNeutralTerritories[0]); var takeTerritoryMoves = CalculateTakeTerritoriesTask(-1, territoryToTake, conservativeLevel, "CalculateOneStepExpandBonusTask"); if (takeTerritoryMoves.GetTotalDeployment() > maxDeployment) { if (acceptStackOnly) { if (maxDeployment > 0) { var territoryToDeploy = takeTerritoryMoves.Orders.OfType <BotOrderDeploy>().First().Territory; var pam = new BotOrderDeploy(BotState.Me.ID, territoryToDeploy, maxDeployment); outvar.AddOrder(pam); return(outvar); } else { return(null); } } else { return(null); } } else { outvar = takeTerritoryMoves; return(outvar); } }
public static Moves CalculateNoPlanCleanupDeploymentTask(BotMain state, int armiesToDeploy, Moves movesSoFar) { var outvar = new Moves(); if (armiesToDeploy > 0) { var bestDeploymentTerritory = GetBestDeploymentTerritory(state, movesSoFar); outvar.AddOrder(new BotOrderDeploy(state.Me.ID, bestDeploymentTerritory, armiesToDeploy)); } 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.OffensiveKillRate); 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); }
public static Moves CalculateNoPlanAttackBestTerritoryTask(BotMain state, int maxDeployment) { var outvar = new Moves(); // If true attacks are possible then go with them // If true attacks are possible then go with them var sortedOpponentTerritories = state.TerritoryValueCalculator.GetSortedAttackValueTerritories(); var territoriesToAttack = NoPlanBreakBestTerritoryTask.RemoveTerritoriesThatWeTook (state, sortedOpponentTerritories); foreach (var territory in territoriesToAttack) { if (territory.IsVisible) { var attackTerritoryMoves = AttackTerritoryTask.CalculateAttackTerritoryTask(state, territory, maxDeployment); if (attackTerritoryMoves != null) { return(attackTerritoryMoves); } // If we can't truly attack then attack with 1's var allowedSmallAttacks = territory.Armies.NumArmies - state.MustStandGuardOneOrZero; allowedSmallAttacks -= GetAlreadyPresentSmallAttacks(territory); foreach (var ownedNeighbor in territory.GetOwnedNeighbors()) { if (allowedSmallAttacks > 0 && ownedNeighbor.GetIdleArmies().NumArmies > 0 && !IsTerritoryAlreadySmallAttackedFromOurTerritory(ownedNeighbor, territory)) { var alreadyAttacksOpponent = false; foreach (var atm in ownedNeighbor.OutgoingMoves) { if (atm.Armies.AttackPower > 1 && state.IsOpponent(atm.To.OwnerPlayerID)) { alreadyAttacksOpponent = true; } } if (!alreadyAttacksOpponent) { var atm_1 = new BotOrderAttackTransfer(state.Me.ID, ownedNeighbor, territory, new Armies(1), "NoPlanAttackBestTerritoryTask"); outvar.AddOrder(atm_1); allowedSmallAttacks--; } } } if (outvar.Orders.OfType <BotOrderAttackTransfer>().Any()) { return(outvar); } } } // If absolutely no attack possible then return null return(null); }
public static Moves CalculateJoinInAttacksTask(BotMain state) { var outvar = new Moves(); foreach (var ourTerritory in state.VisibleMap.GetOpponentBorderingTerritories()) { var bestSeriouslyAttackedNeighbor = GetBestSeriouslyAttackedNeighbor(ourTerritory); if (ourTerritory.GetIdleArmies().AttackPower > 1 && bestSeriouslyAttackedNeighbor != null) { outvar.AddOrder(new BotOrderAttackTransfer(state.Me.ID, ourTerritory, bestSeriouslyAttackedNeighbor, ourTerritory.GetIdleArmies(), "JoinInAttacksTask")); } } 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); }
public static void PlayCardsBeginTurn(BotMain state, Moves moves) { //If there are any humans on our team that have yet to take their turn, do not play cards. if (state.Me.Team != PlayerInvite.NoTeam && state.Players.Values.Any(o => state.IsTeammate(o.ID) && !o.IsAIOrHumanTurnedIntoAI && o.State == GamePlayerState.Playing && !o.HasCommittedOrders)) { return; } foreach (var reinforcementCard in state.CardsHandler.GetCards(CardTypes.Reinforcement)) { var numArmies = reinforcementCard.As <ReinforcementCard>().Armies; AILog.Log("PlayCardsTask", "Playing reinforcement card " + reinforcementCard.CardInstanceId + " for " + numArmies + " armies"); moves.AddOrder(new BotOrderGeneric(GameOrderPlayCardReinforcement.Create(reinforcementCard.CardInstanceId, state.Me.ID))); state.MyIncome.FreeArmies += numArmies; } }
/// <summary>Calculates the movement of idle armies to join in expansion steps.</summary> /// <remarks>Calculates the movement of idle armies to join in expansion steps.</remarks> /// <returns></returns> public static Moves CalculateMoveIdleExpansionArmiesTask(BotMain state) { var outvar = new Moves(); foreach (var ourTerritory in state.VisibleMap.GetNonOpponentBorderingBorderTerritories()) { if (ourTerritory.GetIdleArmies().IsEmpty == false && ourTerritory.GetExpansionMoves().Count > 0) { var bestMove = GetBestExpansionMoveToAddArmies(ourTerritory.GetExpansionMoves()); if (IsAddingArmiesBeneficial(bestMove)) { outvar.AddOrder(new BotOrderAttackTransfer(state.Me.ID, ourTerritory, bestMove.To, ourTerritory.GetIdleArmies(), "MoveIdleArmiesTask2")); } } } return(outvar); }
private Moves GetSortedMoves(List <BotOrder> movesSoFar) { Moves sortedMoves = new Moves(); sortedMoves.Orders.AddRange(GetSortedDeployment(movesSoFar)); List <BotOrder> unhandledMoves = movesSoFar.Where(o => !(o is BotOrderDeploy)).ToList(); BotMap movesMap = BotState.VisibleMap.GetMapCopy(); while (unhandledMoves.Count > 0) { var nextMove = GetNextMove(unhandledMoves, movesMap); unhandledMoves.Remove(nextMove); sortedMoves.AddOrder(nextMove); if (nextMove is BotOrderAttackTransfer) { BotState.MapUpdater.UpdateMap((BotOrderAttackTransfer)nextMove, movesMap, BotTerritory.DeploymentType.Conservative); } } return(sortedMoves); }
public static Moves CalculateNoPlanCleanupExpansionTask(BotMain state, Moves movesSoFar) { var outvar = new Moves(); foreach (var fromTerritory in state.VisibleMap.GetNonOpponentBorderingBorderTerritories()) { var possibleToTerritories = new List <BotTerritory>(); foreach (var nonOwnedNeighbor in fromTerritory.GetNonOwnedNeighbors()) { if (nonOwnedNeighbor.OwnerPlayerID == TerritoryStanding.NeutralPlayerID && IsUnplannedExpansionStepSmart(state, fromTerritory, nonOwnedNeighbor)) { possibleToTerritories.Add(nonOwnedNeighbor); } } if (possibleToTerritories.Count > 0) { var territoryToAttack = possibleToTerritories.OrderByDescending(t => t.Bonuses.Sum(b => b.GetExpansionValue()) * 100 + t.ExpansionTerritoryValue).First(); outvar.AddOrder(new BotOrderAttackTransfer(state.Me.ID, fromTerritory, territoryToAttack, fromTerritory.GetIdleArmies(), "NoPlanCleanupTask")); } } return(outvar); }
public static void DiscardCardsEndTurn(BotMain state, Moves moves) { //If there are players on our team that have yet to take their turn, do not discard cards if (state.Me.Team != PlayerInvite.NoTeam && state.Players.Values.Any(o => state.IsTeammate(o.ID) && o.State == GamePlayerState.Playing && !o.HasCommittedOrders)) { return; } // Discard as many cards as needed var cardsWePlayed = moves.Convert().OfType <GameOrderPlayCard>().Select(o => o.CardInstanceID).ToHashSet(true); var cardsPlayedByAnyone = state.CardsPlayedByTeammates.Concat(cardsWePlayed).ToHashSet(true); int numMustPlay = state.CardsMustPlay; foreach (var card in state.Cards) { if (numMustPlay > 0 && !cardsPlayedByAnyone.Contains(card.ID)) { AILog.Log("PlayCardsTask", "Discarding card " + card.ID); moves.AddOrder(new BotOrderGeneric(GameOrderDiscard.Create(state.Me.ID, card.ID))); numMustPlay--; } } }