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);
        }
예제 #2
0
        /// <summary>Calculates the expansion territory value for a territory.</summary>
        /// <remarks>Calculates the expansion territory value for a territory.</remarks>
        /// <param name="territory">the territory which can be part of an arbitrary map</param>
        /// <param name="mapToWriteIn">the map in which the calculated territory value is to be inserted
        /// </param>
        private void CalculateExpansionTerritoryValue(BotTerritory territory, BotMap mapToWriteIn)
        {
            var currentValue         = 0;
            var neighborsWithinBonus = territory.GetNeighborsWithinSameBonus();

            // Add 1000 for each unknown neighbor within the same Bonus
            foreach (var neighbor in neighborsWithinBonus)
            {
                if (neighbor.OwnerPlayerID == TerritoryStanding.NeutralPlayerID && neighbor.GetOwnedNeighbors().Count == 0)
                {
                    currentValue += 1000;
                }
            }
            // Add 100 for each neighbor within the same Bonus
            foreach (var neighbor_1 in neighborsWithinBonus)
            {
                if (neighbor_1.OwnerPlayerID == TerritoryStanding.NeutralPlayerID)
                {
                    currentValue += 100;
                }
            }
            // Add 10 for each opponent neighbor
            currentValue += 10 * territory.GetOpponentNeighbors().Count;

            // Add 1 for each neutral neighbor in another Bonus
            foreach (var neighbor_2 in territory.Neighbors)
            {
                if (neighbor_2.OwnerPlayerID == TerritoryStanding.NeutralPlayerID && !neighborsWithinBonus.Contains(neighbor_2))
                {
                    currentValue += 1;
                }
            }

            mapToWriteIn.Territories[territory.ID].ExpansionTerritoryValue = currentValue;
        }
        /// <summary>Returns the needed moves to defend the territory.</summary>
        /// <remarks>
        /// Returns the needed moves to defend the territory. If not possible then returns null. If no defense needed returns
        /// empty moves. First tries to fulfill the needed armies with background armies.
        /// </remarks>
        /// <param name="territoryToDefend"></param>
        /// <param name="maxDeployment"></param>
        /// <returns></returns>
        public Moves CalculateDefendTerritoryTask(BotTerritory territoryToDefend, int maxDeployment, bool useBackgroundArmies, BotTerritory.DeploymentType lowerConservativeLevel, BotTerritory.DeploymentType upperConservativeLevel)
        {
            var outvar       = new Moves();
            var oppNeighbors = territoryToDefend.GetOpponentNeighbors();

            if (oppNeighbors.Count == 0)
            {
                return(null);
            }

            var maxOpponentDeployment = oppNeighbors.Select(o => o.OwnerPlayerID).Distinct().Max(o => BotState.GetGuessedOpponentIncome(o, BotState.VisibleMap));

            for (var i = 0; i < maxOpponentDeployment; i++)
            {
                var defendMoves = CalculateDefendTerritoryMoves(territoryToDefend, maxDeployment, useBackgroundArmies, i, lowerConservativeLevel, upperConservativeLevel);
                if (defendMoves != null)
                {
                    outvar = defendMoves;
                }
                else
                {
                    return(outvar);
                }
            }
            return(null);
        }
예제 #4
0
        private bool CanAnyOpponentAttackTerritory(BotTerritory ourTerritory)
        {
            var oppNeighbors = ourTerritory.GetOpponentNeighbors();

            if (oppNeighbors.Count == 0)
            {
                return(false);
            }

            foreach (var group in oppNeighbors.GroupBy(o => o.OwnerPlayerID))
            {
                var opponentIncome          = BotState.GetGuessedOpponentIncome(group.Key, BotState.VisibleMap);
                var ourArmies               = ourTerritory.Armies;
                var opponentAttackingArmies = opponentIncome;
                foreach (var opponentNeighbor in group)
                {
                    opponentAttackingArmies += opponentNeighbor.Armies.AttackPower - BotState.MustStandGuardOneOrZero;
                }

                if (Math.Round(opponentAttackingArmies * BotState.Settings.OffensiveKillRate) >= Math.Round(ourArmies.DefensePower * BotState.Settings.DefensiveKillRate))
                {
                    return(true);
                }
            }

            return(false);
        }
예제 #5
0
        private bool CanOpponentAttackTerritory(PlayerIDType opponentID, BotTerritory ourTerritory)
        {
            if (ourTerritory.GetOpponentNeighbors().Count == 0)
            {
                return(false);
            }
            var opponentIncome          = BotState.GetGuessedOpponentIncome(opponentID, BotState.VisibleMap);
            var ourArmies               = ourTerritory.Armies;
            var opponentAttackingArmies = opponentIncome;

            foreach (var opponentNeighbor in ourTerritory.GetOpponentNeighbors())
            {
                opponentAttackingArmies += opponentNeighbor.Armies.AttackPower - BotState.MustStandGuardOneOrZero;
            }

            return(Math.Round(opponentAttackingArmies * BotState.Settings.OffensiveKillRate) >= Math.Round(ourArmies.DefensePower * BotState.Settings.DefensiveKillRate));
        }
예제 #6
0
        private static BotTerritory GetBestSeriouslyAttackedNeighbor(BotTerritory ourTerritory)
        {
            BotTerritory outvar = null;
            var          bestNeighborAttackValue = -1;

            foreach (var opponentNeighbor in ourTerritory.GetOpponentNeighbors())
            {
                if (IsTerritorySeriouslyAttacked(opponentNeighbor) && opponentNeighbor.AttackTerritoryValue > bestNeighborAttackValue)
                {
                    bestNeighborAttackValue = opponentNeighbor.AttackTerritoryValue;
                    outvar = opponentNeighbor;
                }
            }
            return(outvar);
        }
예제 #7
0
        /// <summary>Returns whether it makes sense to perform an unplanned expansion step from our territory to the neutral territory.
        /// </summary>
        /// <remarks>
        /// Returns whether it makes sense to perform an unplanned expansion step from our territory to the neutral territory. The
        /// parameters considered therefore are the distance to the opponent and whether we can take that territory.
        /// </remarks>
        /// <param name="fromTerritory">an owned territory, not bordering the opponent</param>
        /// <param name="toTerritory">a neutral territory</param>
        /// <returns></returns>
        private static bool IsUnplannedExpansionStepSmart(BotMain state, BotTerritory fromTerritory, BotTerritory toTerritory)
        {
            var isSmart = true;

            if (fromTerritory.GetIdleArmies().AttackPower <= 1)
            {
                isSmart = false;
            }

            if (toTerritory.Armies.DefensePower > toTerritory.getOwnKills(fromTerritory.GetIdleArmies().AttackPower, toTerritory.Armies.DefensePower))
            {
                isSmart = false;
            }
            var distanceCondition1 = fromTerritory.DistanceToOpponentBorder <= 4;
            var distanceCondition2 = toTerritory.GetOpponentNeighbors().Count == 0;

            if (distanceCondition1 && distanceCondition2)
            {
                isSmart = false;
            }
            return(isSmart);
        }
예제 #8
0
        /// <remarks>Calculates the attack territory values.</remarks>
        /// <param name="territory">allowed are neutral and opponent territories</param>
        public void CalculateAttackTerritoryValue(BotTerritory territory, BotMap mapToWriteIn
                                                  )
        {
            var currentValue = 0;

            // Add 100.000 * armies reward to the value if it's a spot in an
            // opponent Bonus
            if (territory.Bonuses.Any(o => o.IsOwnedByAnyOpponent()))
            {
                currentValue += LOWEST_HIGH_PRIORITY_VALUE * territory.Bonuses.Sum(o => o.Amount);
            }
            // Add 1000 to the value for each bordering own Bonus
            currentValue += territory.AttackTerritoryValue + LOWEST_MEDIUM_PRIORITY_VALUE * territory.GetAmountOfBordersToOwnBonus();
            // Add 1000 to the value for each bordering opponent Bonus
            currentValue += LOWEST_MEDIUM_PRIORITY_VALUE * territory.GetAmountOfBordersToOpponentBonus();

            foreach (var bonus in territory.Bonuses)
            {
                // Add 1000 * armies reward for the opponent having all but one neutral spot in the Bonus
                var neutralArmiesInBonus     = bonus.NeutralArmies.DefensePower;
                var amountOfOwnedTerritories = bonus.GetOwnedTerritories().Count;
                if (amountOfOwnedTerritories == 0 && neutralArmiesInBonus <= 2 && neutralArmiesInBonus > 0)
                {
                    currentValue += bonus.Amount * LOWEST_MEDIUM_PRIORITY_VALUE;
                }
            }

            // Add up to 30 to the armies reward for being close to an opponent
            // Bonus
            if (territory.DistanceToOpponentBonus == 1)
            {
                currentValue += 30;
            }
            else if (territory.DistanceToOpponentBonus == 2)
            {
                currentValue += 20;
            }
            else if (territory.DistanceToOpponentBonus == 3)
            {
                currentValue += 10;
            }

            // Add up to 30 to the armies reward for being close to an own bonus
            if (territory.DistanceToOwnBonus == 1)
            {
                currentValue += 30;
            }
            else if (territory.DistanceToOwnBonus == 2)
            {
                currentValue += 20;
            }
            else if (territory.DistanceToOwnBonus == 3)
            {
                currentValue += 10;
            }

            // Add 1 to the value for each opponent bordering territory
            currentValue += 1 * territory.GetOpponentNeighbors().Count;

            foreach (var vmBonus in territory.Bonuses)
            {
                // Add 10 - the amount of neutrals in the Bonus
                currentValue += Math.Max(0, 10 - vmBonus.NeutralArmies.DefensePower);


                // Add stuff if the opponent seems to currently expand in that Bonus
                if (BotState.NumberOfTurns > 0 && vmBonus.GetOwnedTerritories
                        ().Count == 0 && vmBonus.Amount > 0 && !vmBonus.IsOwnedByAnyOpponent())
                {
                    var opponentIsExpanding = false;
                    foreach (var opponentTerritory in vmBonus.GetVisibleOpponentTerritories())
                    {
                        var lwmTerritory = BotMain.LastVisibleMap.Territories[opponentTerritory.ID];
                        if (lwmTerritory.IsVisible && lwmTerritory.OwnerPlayerID == TerritoryStanding.NeutralPlayerID)
                        {
                            opponentIsExpanding = true;
                        }
                    }
                    if (opponentIsExpanding)
                    {
                        if (vmBonus.NeutralArmies.DefensePower <= 2)
                        {
                            currentValue += vmBonus.Amount * 30;
                        }
                        else if (vmBonus.NeutralArmies.DefensePower <= 4)
                        {
                            currentValue += vmBonus.Amount * 10;
                        }
                        else
                        {
                            currentValue += vmBonus.Amount * 5;
                        }
                    }
                }
            }

            currentValue *= ATTACK_ADJUSTMENT_FACTOR;
            mapToWriteIn.Territories[territory.ID].AttackTerritoryValue = currentValue;
        }