示例#1
0
        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);
        }
示例#2
0
        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);
        }
示例#4
0
        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);
            }
        }
示例#8
0
        /// <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);
        }
示例#9
0
        /// <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);
        }
示例#10
0
        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);
        }
示例#12
0
        // 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);
            }
        }
示例#15
0
        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);
        }
示例#16
0
        /// <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);
        }
示例#18
0
        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);
        }
示例#20
0
        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);
        }
示例#22
0
        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);
        }
示例#23
0
        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);
        }
示例#24
0
        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--;
                }
            }
        }