Esempio n. 1
0
        /// <summary>
        /// Runs the commander away from opponents
        /// </summary>
        private static void DoCommander(BotMain bot, TerritoryStanding cmdrTerritory, Commander cmdr)
        {
            var directive = CommanderDirective(bot, cmdrTerritory.ID);

            if (directive.HasValue)
            {
                AILog.Log("SpecialUnits", "Directive directs us to move the commander from " + bot.TerrString(cmdrTerritory.ID) + " to " + bot.TerrString(directive.Value));

                if (directive.Value != cmdrTerritory.ID)
                {
                    bot.Orders.AddAttack(cmdrTerritory.ID, directive.Value, AttackTransferEnum.AttackTransfer, cmdrTerritory.NumArmies.NumArmies, false, commanders: true);
                }
                bot.AvoidTerritories.Add(cmdrTerritory.ID); //add this so we don't deploy there, we want the commander to stay alone
                return;
            }

            var powerDiff = bot.Map.Territories[cmdrTerritory.ID].ConnectedTo.Keys
                            .Select(o => bot.Standing.Territories[o])
                            .Where(o => bot.IsOpponent(o.OwnerPlayerID) && o.NumArmies.Fogged == false)
                            .Sum(o => o.NumArmies.AttackPower)
                            - cmdrTerritory.NumArmies.DefensePower;
            var toDeploy = Math.Max(0, powerDiff);

            if (powerDiff > 0)
            {
                if (bot.UseRandomness)
                {
                    toDeploy = SharedUtility.Round(toDeploy * RandomUtility.BellRandom(0.5, 1.5));
                }
                if (toDeploy > bot.MakeOrders.IncomeTracker.RemainingUndeployed)
                {
                    toDeploy = bot.MakeOrders.IncomeTracker.RemainingUndeployed;
                }

                if (toDeploy > 0 && bot.Orders.TryDeploy(cmdrTerritory.ID, toDeploy))
                {
                    AILog.Log("SpecialUnits", "Deployed " + toDeploy + " to defend commander");
                }
            }

            //Consider this territory and all adjacent territories.  Which is the furthest from any enemy?
            var terrDistances = bot.Map.Territories[cmdrTerritory.ID].ConnectedTo.Keys.ConcatOne(cmdrTerritory.ID)
                                .Where(o => bot.Standing.Territories[o].OwnerPlayerID == bot.PlayerID || bot.Standing.Territories[o].NumArmies.DefensePower <= 4) //don't go somewhere that's defended heavily
                                .ToDictionary(o => o, o => bot.DistanceFromEnemy(o));

            AILog.Log("SpecialUnits", "Commander run options: " + terrDistances.Select(o => bot.TerrString(o.Key) + " dist=" + o.Value).JoinStrings(", "));

            var sorted = terrDistances.OrderByDescending(o => o.Value).ToList();

            sorted.RemoveWhere(o => o.Value < sorted[0].Value);

            var runTo = bot.UseRandomness ? sorted.Random().Key : sorted[0].Key;

            if (runTo == cmdrTerritory.ID)
            {
                return; //already there
            }
            AILog.Log("SpecialUnits", "Moving commander from " + bot.TerrString(cmdrTerritory.ID) + " to " + bot.TerrString(runTo));
            bot.Orders.AddAttack(cmdrTerritory.ID, runTo, AttackTransferEnum.AttackTransfer, cmdrTerritory.NumArmies.NumArmies + toDeploy, false, commanders: true);
        }
Esempio n. 2
0
        public static void PrintTerritoryValues(BotMap map, BotMain BotState)
        {
            AILog.Log("Territory attack values:");
            foreach (BotTerritory territory in map.Territories.Values)
            {
                if (territory.IsVisible && BotState.IsOpponent(territory.OwnerPlayerID))
                {
                    AILog.Log(territory.Details.Name + ": " + territory.AttackTerritoryValue);
                }
            }

            AILog.Log("Territory expansion values:");
            foreach (BotTerritory territory in map.Territories.Values)
            {
                if (territory.IsVisible && territory.OwnerPlayerID == TerritoryStanding.NeutralPlayerID)
                {
                    AILog.Log(territory.Details.Name + ": " + territory.ExpansionTerritoryValue);
                }
            }

            AILog.Log("Territory defend values:");
            foreach (BotTerritory territory in map.Territories.Values)
            {
                if (territory.OwnerPlayerID == BotState.Me.ID && territory.GetOpponentNeighbors().Count > 0)
                {
                    AILog.Log(territory.Details.Name + ": " + territory.DefenceTerritoryValue);
                }
            }
        }
Esempio n. 3
0
        private void DeleteBadAttacks(Moves movesSoFar)
        {
            var interestingAttacks = new List <BotOrderAttackTransfer>();

            foreach (var atm in movesSoFar.Orders.OfType <BotOrderAttackTransfer>())
            {
                if (atm.Armies.AttackPower > 1 && BotState.IsOpponent(atm.To.OwnerPlayerID))
                {
                    var isInteresting   = false;
                    var attackTerritory = atm.To.IncomingMoves[0].From;
                    foreach (var incomingMove in atm.To.IncomingMoves)
                    {
                        if (incomingMove.From != attackTerritory)
                        {
                            isInteresting = true;
                        }
                    }
                    if (isInteresting)
                    {
                        interestingAttacks.Add(atm);
                    }
                }
            }
            var territoriesWithInterestingAttacks = new HashSet <BotTerritory>();

            foreach (BotOrderAttackTransfer atm_1 in interestingAttacks)
            {
                territoriesWithInterestingAttacks.Add(atm_1.From);
            }
        }
Esempio n. 4
0
        private static bool PlayBombCard(BotMain bot, CardInstance card)
        {
            var allBombableEnemyTerritories = bot.Standing.Territories.Values
                                              .Where(o => o.OwnerPlayerID == bot.PlayerID)
                                              .SelectMany(o => bot.Map.Territories[o.ID].ConnectedTo.Keys)
                                              .Distinct()
                                              .Select(o => bot.Standing.Territories[o])
                                              .Where(o => bot.IsOpponent(o.OwnerPlayerID) && o.NumArmies.Fogged == false)
                                              .ToList();

            var minArmies = !bot.UseRandomness ? bot.BaseIncome.Total * 2 : SharedUtility.Round(bot.BaseIncome.Total * RandomUtility.BellRandom(1, 3));

            var weights = allBombableEnemyTerritories.Where(o => o.NumArmies.NumArmies > minArmies).ToDictionary(o => o.ID, o => o.NumArmies.NumArmies - minArmies);

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

            var bomb = bot.UseRandomness ? RandomUtility.WeightedRandom(weights.Keys, o => weights[o]) : weights.OrderByDescending(o => o.Value).First().Key;

            AILog.Log("PlayCards", "Bombing " + bot.TerrString(bomb));
            bot.Orders.AddOrder(GameOrderPlayCardBomb.Create(card.ID, bot.PlayerID, bomb));
            return(true);
        }
        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);
        }
Esempio n. 6
0
 private static void HasSeenOpponent(BotMain state)
 {
     foreach (BotTerritory terr in state.VisibleMap.Territories.Values)
     {
         if (state.IsOpponent(terr.OwnerPlayerID))
         {
             hasSeenOpponent = true;
             return;
         }
     }
     hasSeenOpponent = false;
 }
        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);
        }
Esempio n. 8
0
 private static bool IsRiskyAttackPresent(BotMain state, Moves movesSoFar)
 {
     foreach (var atm in movesSoFar.Orders.OfType <BotOrderAttackTransfer>())
     {
         if (state.IsOpponent(atm.To.OwnerPlayerID))
         {
             var attackingArmies   = atm.Armies;
             var maxOpponentArmies = atm.To.Armies.Add(new Armies(state.GetGuessedOpponentIncome(atm.To.OwnerPlayerID, state.VisibleMap)));
             if (attackingArmies.AttackPower > 1 && attackingArmies.AttackPower * state.Settings.OffensiveKillRate <= maxOpponentArmies.DefensePower * state.Settings.DefensiveKillRate)
             {
                 return(true);
             }
         }
     }
     return(false);
 }
        private int GetCounteredTerritories(BotBonus bonus, PlayerIDType playerID)
        {
            var outvar = 0;

            foreach (var territory in bonus.Territories)
            {
                if (territory.GetOpponentNeighbors().Count > 0 && playerID == BotState.Me.ID)
                {
                    outvar++;
                }
                else if (territory.GetOwnedNeighbors().Count > 0 && BotState.IsOpponent(playerID))
                {
                    outvar++;
                }
            }
            return(outvar);
        }
Esempio n. 10
0
        private static bool PlayDiplomacyCard(BotMain bot, CardInstance card)
        {
            var canDip = bot.Players.Values.Where(o =>
                                                  o.State == GamePlayerState.Playing && //only diplomacy people in the game
                                                  bot.IsOpponent(o.ID) && //only diplomacy opponents
                                                  bot.Orders.Orders.Concat(bot.Standing.ActiveCards.Select(z => (GameOrder)z.Card)).OfType <GameOrderPlayCardDiplomacy>().None(z => z.AffectsPlayer(o.ID) && z.AffectsPlayer(bot.PlayerID)) //don't diplomacy someone we're already in diplomacy with, or that we already played a diplomacy card on this turn
                                                  ).ToList();

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

            var dip = bot.UseRandomness ? RandomUtility.WeightedRandom(canDip, o => bot.WeightedNeighbors[o.ID]) : canDip.OrderByDescending(o => bot.WeightedNeighbors[o.ID]).First();

            AILog.Log("PlayCards", "Playing a diplomacy card between myself and " + dip);
            bot.Orders.AddOrder(GameOrderPlayCardDiplomacy.Create(card.ID, bot.PlayerID, bot.PlayerID, dip.ID));
            return(true);
        }
Esempio n. 11
0
        private List <PossibleAttack> WeightAttacks()
        {
            //build all possible attacks
            List <PossibleAttack> ret = Bot.Standing.Territories.Values
                                        .Where(o => o.OwnerPlayerID == Bot.PlayerID && !Bot.AvoidTerritories.Contains(o.ID))
                                        .SelectMany(us =>
                                                    Bot.Map.Territories[us.ID].ConnectedTo.Keys
                                                    .Select(k => Bot.Standing.Territories[k])
                                                    .Where(k => Bot.IsOpponent(k.OwnerPlayerID) && !Bot.AvoidTerritories.Contains(k.ID))
                                                    .Select(k => new PossibleAttack(Bot, us.ID, k.ID))).ToList();


            foreach (PossibleAttack a in ret)
            {
                a.Weight(Bot.WeightedNeighbors);
            }

            NormalizeWeights(ret);

            return(ret);
        }
Esempio n. 12
0
        private static int CalculateAmountOfSafeMoves(BotMain state, Moves movesSoFar)
        {
            var outvar = 0;

            foreach (var atm in movesSoFar.Orders.OfType <BotOrderAttackTransfer>())
            {
                if (atm.Armies.AttackPower <= 1 || state.IsOpponent(atm.To.OwnerPlayerID))
                {
                    outvar++;
                }
                else
                {
                    var maxOpponentArmies = atm.To.Armies.Add(new Armies(state.GetGuessedOpponentIncome(atm.To.OwnerPlayerID, state.VisibleMap)));
                    var attackingArmies   = atm.Armies;
                    if (attackingArmies.AttackPower * state.Settings.OffensiveKillRate > maxOpponentArmies.DefensePower * state.Settings.DefensiveKillRate)
                    {
                        outvar++;
                    }
                }
            }
            return(outvar);
        }
Esempio n. 13
0
        public List <BotTerritory> GetSortedAttackValueTerritories()
        {
            var outvar = new List <BotTerritory>();
            var opponentTerritories = BotState.VisibleMap.Territories.Values.Where(o => BotState.IsOpponent(o.OwnerPlayerID)).ToList();
            var copy = new List <BotTerritory>();

            copy.AddRange(opponentTerritories);
            while (!copy.IsEmpty())
            {
                var maxAttackValue          = 0;
                var maxAttackValueTerritory = copy[0];
                foreach (var territory in copy)
                {
                    if (territory.AttackTerritoryValue > maxAttackValue)
                    {
                        maxAttackValue          = territory.AttackTerritoryValue;
                        maxAttackValueTerritory = territory;
                    }
                }
                copy.Remove(maxAttackValueTerritory);
                outvar.Add(maxAttackValueTerritory);
            }
            return(outvar);
        }
Esempio n. 14
0
        private static void DoBoss(BotMain bot, TerritoryStanding terr, SpecialUnit su)
        {
            AILog.Log("SpecialUnits", "Considering boss " + su.ID + " on " + bot.TerrString(terr.ID));

            var routes = bot.Directives.Where(o => o.StartsWith("BossRoute ")).Select(o => new BossRoute(o, bot)).ToList();

            var routeNexts = routes.Select(o => new { Route = o, Terr = o.NextTerr(terr.ID) }).Where(o => o.Terr.HasValue).ToList();

            if (routeNexts.Count > 0)
            {
                var routeNext = routeNexts.WeightedRandom(o => o.Route.Weight);
                AILog.Log("SpecialUnits", routeNexts.Count + " matching routes: " + routeNexts.Select(o => o.Route.Name).JoinStrings(", ") + ", selected " + routeNext.Route);

                if (RandomUtility.RandomPercentage() > routeNext.Route.Chance)
                {
                    AILog.Log("SpecialUnits", "Skipping boss route to " + routeNext.Terr.Value + " due to failed random chance. ");
                }
                else
                {
                    AILog.Log("SpecialUnits", "Moving boss along route to " + bot.TerrString(routeNext.Terr.Value) + ". ");
                    bot.Orders.AddAttack(terr.ID, routeNext.Terr.Value, AttackTransferEnum.AttackTransfer, 0, true, bosses: true);
                    bot.AvoidTerritories.Add(routeNext.Terr.Value);
                    return;
                }
            }
            else if (routes.Count > 0)
            {
                //Move towards the nearest route territory. If there's a tie, take the one that's furthest along in that route
                var terrRoutes = routes.SelectMany(r => r.Route.Select((t, i) => new { Route = r, Terr = t, Index = i }))
                                 .GroupBy(o => o.Terr)
                                 .Select(o => o.MaxSelectorOrDefault(r => r.Index))
                                 .ToDictionary(o => o.Terr, o => o);

                var visited = new HashSet <TerritoryIDType>();
                visited.Add(terr.ID);

                while (true)
                {
                    var visit = visited.SelectMany(o => bot.Map.Territories[o].ConnectedTo.Keys).ToHashSet(false);
                    if (visit.Count == 0)
                    {
                        throw new Exception("Never found route territory");
                    }

                    var visitOnRoute = visit.Where(o => terrRoutes.ContainsKey(o)).ToList();
                    if (visitOnRoute.Count > 0)
                    {
                        var final = visitOnRoute.Select(o => terrRoutes[o]).MaxSelectorOrDefault(o => o.Index);
                        if (RandomUtility.RandomPercentage() > final.Route.Chance)
                        {
                            AILog.Log("SpecialUnits", "Skipping moving boss to route due to failed random check: " + final.Route);
                            break;
                        }
                        else
                        {
                            var move = FindPath.TryFindShortestPath(bot, terr.ID, t => t == final.Terr);
                            AILog.Log("SpecialUnits", "Moving boss to get back to route. Moving to " + bot.TerrString(move[0]) + " to get to " + bot.TerrString(final.Terr) + " index=" + final.Index + " " + final.Route);
                            bot.Orders.AddAttack(terr.ID, move[0], AttackTransferEnum.AttackTransfer, 0, true, bosses: true);
                            bot.AvoidTerritories.Add(final.Terr);
                            return;
                        }
                    }

                    visited.AddRange(visit);
                }
            }

            var attackCandidates = bot.Map.Territories[terr.ID].ConnectedTo.Keys.Select(o => bot.Standing.Territories[o])
                                   .Where(o => !bot.IsTeammateOrUs(o.OwnerPlayerID) && o.NumArmies.DefensePower < 300 && !bot.AvoidTerritories.Contains(o.ID))
                                   .ToList();

            if (attackCandidates.Count > 0)
            {
                var ranks = attackCandidates.ToDictionary(o => o.ID, ts =>
                {
                    if (bot.IsOpponent(ts.OwnerPlayerID))
                    {
                        return(bot.Players[ts.OwnerPlayerID].IsAI ? 3 : 2); //prefer human player
                    }
                    else if (ts.OwnerPlayerID == TerritoryStanding.NeutralPlayerID)
                    {
                        return(1);
                    }
                    else
                    {
                        throw new Exception("Unexpected owner " + ts.OwnerPlayerID);
                    }
                });

                var max = ranks.Values.Max();
                var to  = ranks.Where(o => o.Value == max).Random().Key;
                AILog.Log("SpecialUnits", "Normal boss move to " + bot.TerrString(to));
                bot.Orders.AddAttack(terr.ID, to, AttackTransferEnum.AttackTransfer, 0, false, bosses: true);
                bot.AvoidTerritories.Add(to);
            }
            else
            {
                //Surrounded by ourself or teammates. Move towards enemy
                var move = bot.MoveTowardsNearestBorderNonNeutralThenNeutral(terr.ID);
                if (move.HasValue)
                {
                    AILog.Log("SpecialUnits", "Landlocked boss move to " + bot.TerrString(move.Value));
                    bot.Orders.AddAttack(terr.ID, move.Value, AttackTransferEnum.AttackTransfer, 0, false, bosses: true);
                }
            }
        }
Esempio n. 15
0
 private void FillMoveTypes(List <BotOrder> unhandledMoves, BotMap movesMap)
 {
     foreach (var atm in unhandledMoves.OfType <BotOrderAttackTransfer>())
     {
         var mmToTerritory   = movesMap.Territories[atm.To.ID];
         var mmFromTerritory = movesMap.Territories[atm.From.ID];
         if (atm.Message == AttackMessage.EarlyAttack)
         {
             EarlyAttacks.Add(atm);
         }
         else
         {
             // Opponent attack moves
             if (BotState.IsOpponent(mmToTerritory.OwnerPlayerID))
             {
                 if (atm.Armies.AttackPower == 1)
                 {
                     DelayAttackMoves.Add(atm);
                 }
                 else if (!CanOpponentAttackTerritory(mmToTerritory.OwnerPlayerID, atm.From) && GetSlipperyOpponentTerritoryNumber(atm.To) > -1 && IsProbablyCrushingMove(atm))
                 {
                     CrushingAttackMovesToSlipperyTerritories.Add(atm);
                 }
                 else if (!CanOpponentAttackTerritory(mmToTerritory.OwnerPlayerID, atm.From) && IsAlwaysGoodAttackMove(atm))
                 {
                     SafeAttackMovesWithGoodAttack.Add(atm);
                 }
                 else if (!CanOpponentAttackTerritory(mmToTerritory.OwnerPlayerID, atm.From) && !IsAlwaysGoodAttackMove(atm))
                 {
                     SafeAttackMovesWithPossibleBadAttack.Add(atm);
                 }
                 else if (CanOpponentAttackTerritory(mmToTerritory.OwnerPlayerID, atm.From))
                 {
                     RiskyAttackMoves.Add(atm);
                 }
             }
             else if (mmToTerritory.OwnerPlayerID == BotState.Me.ID) // Transfer moves
             {
                 if (mmToTerritory.GetOpponentNeighbors().Count > 0 && CanOpponentBreakTerritory(mmToTerritory))
                 {
                     SupportMovesWhereOpponentMightBreak.Add(atm);
                 }
                 else if (mmToTerritory.GetOpponentNeighbors().Count > 0 && CanOpponentGetAGoodAttack(mmToTerritory))
                 {
                     SupportMovesWhereOpponentMightGetAGoodAttack.Add(atm);
                 }
                 else if (mmToTerritory.GetOpponentNeighbors().Count > 0 && CanAnyOpponentAttackTerritory(mmToTerritory))
                 {
                     SupportMovesWhereOpponentMightAttack.Add(atm);
                 }
                 else if (mmToTerritory.GetOpponentNeighbors().Count > 0 && !CanAnyOpponentAttackTerritory(mmToTerritory))
                 {
                     NormalSupportMoves.Add(atm);
                 }
                 else if (mmToTerritory.GetOpponentNeighbors().Count == 0)
                 {
                     TransferMoves.Add(atm);
                 }
             }
             else if (mmToTerritory.OwnerPlayerID == TerritoryStanding.NeutralPlayerID) // Expansion moves
             {
                 if (atm.Message == AttackMessage.Snipe)
                 {
                     SnipeMoves.Add(atm);
                 }
                 else if (Math.Round(atm.Armies.AttackPower * BotState.Settings.OffensiveKillRate) < mmToTerritory.Armies.DefensePower)
                 {
                     TransferingExpansionMoves.Add(atm);
                 }
                 else if (atm.Armies.AttackPower > 3 && !CanAnyOpponentAttackTerritory(mmFromTerritory))
                 {
                     BigExpansionMovesNonAttack.Add(atm);
                 }
                 else if (atm.Armies.AttackPower <= 3 && mmToTerritory.GetOpponentNeighbors().Count == 0 && !CanAnyOpponentAttackTerritory(mmFromTerritory))
                 {
                     NonOpponentBorderingSmallExpansionMovesNonAttack.Add(atm);
                 }
                 else if (atm.Armies.AttackPower <= 3 && mmToTerritory.GetOpponentNeighbors().Count > 0 && !CanAnyOpponentAttackTerritory(mmFromTerritory))
                 {
                     OpponentBorderingSmallExpansionMovesNonAttack.Add(atm);
                 }
                 else if (atm.Armies.AttackPower > 3 && CanAnyOpponentAttackTerritory(mmFromTerritory))
                 {
                     BigExpansionMovesWithAttack.Add(atm);
                 }
                 else if (atm.Armies.AttackPower <= 3 && mmToTerritory.GetOpponentNeighbors().Count == 0 && CanAnyOpponentAttackTerritory(mmFromTerritory))
                 {
                     NonOpponentBorderingSmallExpansionMovesWithAttack.Add(atm);
                 }
                 else if (atm.Armies.AttackPower <= 3 && mmToTerritory.GetOpponentNeighbors().Count > 0 && CanAnyOpponentAttackTerritory(mmFromTerritory))
                 {
                     OpponentBorderingSmallExpansionMovesWithAttack.Add(atm);
                 }
             }
         }
     }
 }
Esempio n. 16
0
        private static bool PlayBlockadeCard(BotMain bot, CardInstance card)
        {
            //Look for bonuses that we can't hold and should blockade
            foreach (var bonus in bot.Map.Bonuses.Values)
            {
                var grouped = bonus.Territories.GroupBy(o => bot.Standing.Territories[o].OwnerPlayerID).ToDictionary(o => o.Key, o => o);
                if (!grouped.ContainsKey(bot.PlayerID))
                {
                    continue; //we're not in it
                }
                if (grouped.ContainsKey(TerritoryStanding.NeutralPlayerID))
                {
                    continue; //only complete bonuses -- if it's never been taken, don't blockade
                }
                var opps = grouped.Keys.Where(o => bot.IsOpponent(o)).ToList();
                if (opps.Count == 0)
                {
                    continue; //no opponents in it
                }
                if (bonus.Territories.Any(t => bot.AvoidTerritories.Contains(t)))
                {
                    continue; //already doing something here, perhaps already blockading it.
                }
                var oppTerrs       = opps.SelectMany(o => grouped[o].ToList()).ToHashSet(false);
                var friendlyTerrs  = grouped.Where(o => bot.IsTeammateOrUs(o.Key)).SelectMany(o => o.Value.ToList()).ToList();
                var friendlyArmies = friendlyTerrs.Sum(o => bot.Standing.Territories[o].NumArmies.DefensePower);
                var enemyArmies    = oppTerrs.Sum(o => ExpansionHelper.GuessNumberOfArmies(bot, o).AttackPower);
                var ratio          = bot.UseRandomness ? RandomUtility.BellRandom(1, 3) : 2;
                if (friendlyArmies * ratio > enemyArmies)
                {
                    continue;
                }

                var armies = SharedUtility.Round(bot.EffectiveIncome.FreeArmies * (bot.UseRandomness ? RandomUtility.BellRandom(.1, .4) : .25));
                if (armies < 5)
                {
                    armies = 5;
                }

                var canBlockade = friendlyTerrs.Where(o =>
                                                      bot.Standing.Territories[o].OwnerPlayerID == bot.PlayerID &&
                                                      bot.Map.Territories[o].ConnectedTo.Keys.None(t => oppTerrs.Contains(t)) &&
                                                      bot.Standing.Territories[o].NumArmies.SpecialUnits.Length == 0 &&
                                                      bot.Standing.Territories[o].NumArmies.NumArmies < armies * 2
                                                      ).ToList();
                if (canBlockade.Count == 0)
                {
                    continue;
                }
                var blockade = bot.UseRandomness ? canBlockade.Random() : canBlockade.First();
                var deploy   = Math.Max(0, armies - bot.Standing.Territories[blockade].NumArmies.NumArmies);

                if (!bot.Orders.TryDeploy(blockade, deploy))
                {
                    continue;
                }

                AILog.Log("PlayCards", "Blockading " + bot.TerrString(blockade) + " with " + armies + " (had to deploy " + deploy + ")");

                bot.Orders.AddOrder(GameOrderPlayCardBlockade.Create(card.ID, bot.PlayerID, blockade));
                bot.AvoidTerritories.Add(blockade);
                return(true);
            }

            return(false);
        }
Esempio n. 17
0
        private static bool PlaySanctionsCard(BotMain bot, CardInstance card)
        {
            var canSanction = bot.Players.Values.Where(o => o.State == GamePlayerState.Playing && bot.IsOpponent(o.ID)).Select(o => o.ID).ToList();

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

            var sanction = bot.UseRandomness ? RandomUtility.WeightedRandom(canSanction, o => bot.WeightedNeighbors[o]) : canSanction.OrderByDescending(o => bot.WeightedNeighbors[o]).First();

            AILog.Log("PlayCards", "Sanctioning " + sanction);
            bot.Orders.AddOrder(GameOrderPlayCardSanctions.Create(card.ID, bot.PlayerID, sanction));
            return(true);
        }
Esempio n. 18
0
        private void CalculateNoPlanBreakDefendMoves(Moves moves, bool lowImportance, bool mediumImportance, bool highImportance, BotTerritory.DeploymentType lowerConservative, BotTerritory.DeploymentType upperConservative)
        {
            List <BotTerritory> territoriesToDefend = new List <BotTerritory>();

            foreach (var territory in BotState.VisibleMap.GetOwnedTerritories())
            {
                var importance      = territory.DefenceTerritoryValue;
                var lowImportant    = importance < TerritoryValueCalculator.LOWEST_MEDIUM_PRIORITY_VALUE;
                var mediumImportant = importance < TerritoryValueCalculator.LOWEST_HIGH_PRIORITY_VALUE && importance >= TerritoryValueCalculator.LOWEST_MEDIUM_PRIORITY_VALUE;
                var highImportant   = importance >= TerritoryValueCalculator.LOWEST_HIGH_PRIORITY_VALUE;
                if ((lowImportance && lowImportant) || (mediumImportance && mediumImportant) || (highImportance && highImportant))
                {
                    territoriesToDefend.Add(territory);
                }
            }
            var possibleTerritoriesToAttack = new List <BotTerritory>();

            foreach (var opponentTerritory in BotState.VisibleMap.Territories.Values.Where(o => o.IsVisible &&
                                                                                           BotState.IsOpponent(o.OwnerPlayerID)))
            {
                var wmOpponentTerritory = BotState.WorkingMap.Territories[opponentTerritory.ID];
                if (BotState.IsOpponent(wmOpponentTerritory.OwnerPlayerID))
                {
                    possibleTerritoriesToAttack.Add(opponentTerritory);
                }
            }
            var territoriesToAttack = new List <BotTerritory>();

            foreach (var territory_1 in possibleTerritoriesToAttack)
            {
                var importance      = territory_1.AttackTerritoryValue;
                var lowImportant    = importance < TerritoryValueCalculator.LOWEST_MEDIUM_PRIORITY_VALUE;
                var mediumImportant = importance < TerritoryValueCalculator.LOWEST_HIGH_PRIORITY_VALUE && importance >= TerritoryValueCalculator.LOWEST_MEDIUM_PRIORITY_VALUE;
                var highImportant   = importance >= TerritoryValueCalculator.LOWEST_HIGH_PRIORITY_VALUE;
                if ((lowImportance && lowImportant) || (mediumImportance && mediumImportant) || (highImportance && highImportant))
                {
                    territoriesToAttack.Add(territory_1);
                }
            }
            var combinedTerritories = new List <BotTerritory>();

            combinedTerritories.AddRange(territoriesToDefend);
            combinedTerritories.AddRange(territoriesToAttack);
            var sortedTerritories = BotState.TerritoryValueCalculator.SortTerritoriesAttackDefense(combinedTerritories);

            foreach (var territory_2 in sortedTerritories)
            {
                var   maxDeployment    = BotState.MyIncome.Total - moves.GetTotalDeployment();
                Moves defendBreakMoves = null;
                if (territory_2.OwnerPlayerID == BotState.Me.ID)
                {
                    defendBreakMoves = BotState.DefendTerritoryTask.CalculateDefendTerritoryTask(territory_2, maxDeployment, true, lowerConservative, upperConservative);
                }
                else
                {
                    defendBreakMoves = BotState.BreakTerritoryTask.CalculateBreakTerritoryTask(territory_2, maxDeployment, lowerConservative, upperConservative, "CalculateNoPlanBreakDefendMoves");
                }

                if (defendBreakMoves != null)
                {
                    MovesCommitter.CommittMoves(BotState, defendBreakMoves);
                    moves.MergeMoves(defendBreakMoves);
                }
            }
        }