Пример #1
0
        private MultiMoves GetBreakBonusMoves(BonusIDType opponentBonus, MultiMoves presentMoves)
        {
            var bonusTerritories                     = GameState.Map.Bonuses[opponentBonus].Territories;
            var distances                            = MapInformer.GetDistancesFromTerritories(bonusTerritories);
            var ownedBorderTerritories               = MapInformer.GetOwnedBorderTerritories(presentMoves.GetTerritoryStandingsAfterAllMoves(), GameState.MyPlayerId);
            int minDistance                          = ownedBorderTerritories.Min(o => distances[o.ID]);
            var bestStartTerritory                   = ownedBorderTerritories.Where(o => distances[o.ID] == minDistance).First();
            int currentDistance                      = minDistance;
            var currentTerritoryInAttackPath         = bestStartTerritory.ID;
            List <TerritoryIDType> territoriesToTake = new List <TerritoryIDType>();

            while (currentDistance != 0)
            {
                var neighbors = MapInformer.GetNeighborTerritories(currentTerritoryInAttackPath);
                var possibleAttackNeighbors = neighbors.Where(n => distances[n] == currentDistance - 1).ToList();
                var bestNeighborToAttack    = GetBestNeighborToAttack(possibleAttackNeighbors);
                territoriesToTake.Add(bestNeighborToAttack);
                currentTerritoryInAttackPath = bestNeighborToAttack;
                currentDistance--;
            }
            TakeTerritoriesTask takeTerritoriesTask = new TakeTerritoriesTask(REASON);
            MultiMoves          resultMoves         = takeTerritoriesTask.CalculateTakeTerritoriesMoves(territoriesToTake, presentMoves);

            return(resultMoves);
        }
 private MultiAttackPathToBonus(BotMain bot, TerritoryIDType startFrom, BonusIDType bonusID, int jumpsToGetToBonus, int armiesNeededToCapture, int armiesNeedToKillToGetThere, List <TerritoryIDType> pathToGetThere)
 {
     this.Bot                        = bot;
     this.StartFrom                  = startFrom;
     this.BonusID                    = bonusID;
     this.JumpsToGetToBonus          = jumpsToGetToBonus;
     this.EstArmiesNeededToCapture   = armiesNeededToCapture;
     this.ArmiesNeedToKillToGetThere = armiesNeedToKillToGetThere;
     this.PathToGetThere             = pathToGetThere;
 }
Пример #3
0
 public int BonusValue(BonusIDType bonusID)
 {
     if (Settings.OverriddenBonuses.ContainsKey(bonusID))
     {
         return(Settings.OverriddenBonuses[bonusID]);
     }
     else
     {
         return(Map.Bonuses[bonusID].Amount);
     }
 }
Пример #4
0
        /// <summary>
        /// Estimate how many turns it would take us to complete the bonus, assuming full deployment and usage of armies in or next to it.
        /// </summary>
        /// <param name="bonusID"></param>
        /// <param name="bonusPath"></param>
        /// <returns></returns>
        private CaptureTerritories TurnsToTake(BonusIDType bonusID, BonusPath path)
        {
            var bonus       = Bot.Map.Bonuses[bonusID];
            var terrsToTake = bonus.Territories.Where(o => Bot.Standing.Territories[o].OwnerPlayerID != Bot.PlayerID).ToHashSet(true);

            var terrsWeOwnInOrAroundBonus   = bonus.Territories.Concat(bonus.Territories.SelectMany(o => Bot.Map.Territories[o].ConnectedTo.Keys)).Where(o => Bot.Standing.Territories[o].OwnerPlayerID == Bot.PlayerID).ToHashSet(false);
            var armiesWeHaveInOrAroundBonus = terrsWeOwnInOrAroundBonus.Sum(o => Bot.MakeOrders.GetArmiesAvailable(o));

            var armiesPerTurn = Bot.BaseIncome.FreeArmies;

            return(CaptureTerritories.TryFindTurnsToTake(Bot, path, armiesWeHaveInOrAroundBonus, armiesPerTurn, terrsToTake, o => o.NumArmies.Fogged ? ExpansionHelper.GuessNumberOfArmies(Bot, o.ID).DefensePower : o.NumArmies.DefensePower));
        }
Пример #5
0
        public float BonusFuzz(BonusIDType bonusID)
        {
            if (!UseRandomness)
            {
                return(0);
            }

            if (_bonusFuzz == null)
            {
                _bonusFuzz = new Dictionary <BonusIDType, float>();
            }

            if (!_bonusFuzz.ContainsKey(bonusID))
            {
                _bonusFuzz.Add(bonusID, (float)RandomUtility.BellRandom(-2, 2));
            }

            return(_bonusFuzz[bonusID]);
        }
Пример #6
0
        public static float WeighBonus(BotMain bot, BonusIDType bonusID, Func <TerritoryStanding, bool> weOwn, int turnsToTake)
        {
            var bonus      = bot.Map.Bonuses[bonusID];
            int bonusValue = bot.BonusValue(bonusID);

            if (bonusValue <= 0)
            {
                throw new Exception("Considered zero or negative bonuses"); //we should not even be considering zero or negative bonuses, ensure they're filtered out before we get here.
            }
            var weight = BaseBonusWeight;

            //When randomness is enabled, modify the bonus by a fixed amount for this bonus.
            weight += bot.BonusFuzz(bonusID);

            weight += bonusValue * (bot.IsFFA ? 7 : 4);

            //Subtract value for each additional turn it takes to take over one
            weight -= bonusValue * (turnsToTake - 1);

            weight -= bonus.Territories.Count * bot.Settings.OneArmyMustStandGuardOneOrZero;

            float armyMult = ArmyMultiplier(bot.Settings.DefenseKillRate);

            //How many territories do we need to take to get it? Subtract one weight for each army standing in our way
            foreach (var terrInBonus in bonus.Territories)
            {
                var ts = bot.Standing.Territories[terrInBonus];

                if (weOwn(ts))
                {
                    weight += ts.NumArmies.AttackPower * armyMult; //Already own it
                }
                else if (ts.OwnerPlayerID == TerritoryStanding.FogPlayerID)
                {
                    weight -= GuessNumberOfArmies(bot, ts.ID).DefensePower *armyMult;
                }
                else if (bot.IsTeammate(ts.OwnerPlayerID))
                {
                    weight -= bot.Players[ts.OwnerPlayerID].IsAIOrHumanTurnedIntoAI ? 0 : ts.NumArmies.DefensePower * 4 * armyMult; //Human teammate in it. We'll defer to them since humans know best.
                }
                else if (ts.OwnerPlayerID == TerritoryStanding.AvailableForDistribution)
                {
                    weight -= Math.Max(bot.Settings.InitialNeutralsInDistribution, bot.Settings.InitialPlayerArmiesPerTerritory) * armyMult; //assume another player could start there
                }
                else if (ts.IsNeutral)
                {
                    //Neutral in it
                    if (ts.NumArmies.Fogged == false)
                    {
                        weight -= ts.NumArmies.DefensePower * armyMult;
                    }
                    else
                    {
                        weight -= GuessNumberOfArmies(bot, ts.ID).DefensePower *armyMult;
                    }
                }
                else
                {
                    //Opponent in it - expansion less likely
                    if (ts.NumArmies.Fogged == false)
                    {
                        weight -= ts.NumArmies.DefensePower * 3 * armyMult;
                    }
                    else
                    {
                        weight -= GuessNumberOfArmies(bot, ts.ID).DefensePower *armyMult;
                    }
                }
            }

            return(weight);
        }
Пример #7
0
 public BotBonus(BotMap parent, BonusIDType id)
 {
     this.Parent = parent;
     this.ID     = id;
 }
Пример #8
0
 public string BonusString(BonusIDType bonusID)
 {
     return(BonusString(Map.Bonuses[bonusID]));
 }
        /// <summary>
        /// Returns null if we can't find a way to take the bonus or if we already own it
        /// </summary>
        /// <param name="bot"></param>
        /// <param name="bonusID"></param>
        /// <returns></returns>
        public static MultiAttackPathToBonus TryCreate(BotMain bot, TerritoryIDType startFrom, BonusIDType bonusID, GameStanding standing, int maxDistance)
        {
            var bonus = bot.Map.Bonuses[bonusID];
            var allUnownedTerrsInBonus = bonus.Territories.Where(o => standing.Territories[o].OwnerPlayerID != bot.PlayerID).ToHashSet(true);

            if (allUnownedTerrsInBonus.Count == 0)
            {
                return(null); //already own it
            }
            HashSet <TerritoryIDType> terrsWeEnterBonus;

            int jumpsToGetToBonus = DistanceToTerrs(bot, startFrom, bonus.Territories.ToHashSet(true), standing, maxDistance, out terrsWeEnterBonus);

            if (jumpsToGetToBonus == int.MaxValue)
            {
                return(null); //can't take it within a reasonable searching distance
            }
            if (jumpsToGetToBonus == 0)
            {
                //We're already in it
                var armiesNeededToCapture = bot.ArmiesToTakeMultiAttack(allUnownedTerrsInBonus.Select(o => ExpansionHelper.GuessNumberOfArmies(bot, o, standing, MultiAttackExpand.GuessOpponentNumberOfArmiesInFog)));
                return(new MultiAttackPathToBonus(bot, startFrom, bonusID, 0, armiesNeededToCapture, 0, new List <TerritoryIDType>()));
            }
            else
            {
                var pathToGetThere = FindPath.TryFindShortestPath(bot, startFrom, t => terrsWeEnterBonus.Contains(t), visit => visit == startFrom || bot.IsTeammateOrUs(standing.Territories[visit].OwnerPlayerID) == false);
                if (pathToGetThere == null)
                {
                    return(null);
                }

                var getThere = pathToGetThere.ExceptOne(pathToGetThere.Last());
                var armiesNeededToCapture = bot.ArmiesToTakeMultiAttack(getThere.Concat(allUnownedTerrsInBonus).Select(o => ExpansionHelper.GuessNumberOfArmies(bot, o, standing, MultiAttackExpand.GuessOpponentNumberOfArmiesInFog)));

                return(new MultiAttackPathToBonus(bot, startFrom, bonusID, jumpsToGetToBonus, armiesNeededToCapture, getThere.Sum(o => ExpansionHelper.GuessNumberOfArmies(bot, o, standing).DefensePower), pathToGetThere));
            }
        }
Пример #10
0
        public static BonusPath TryCreate(BotMain bot, BonusIDType bonusID, Func <TerritoryStanding, bool> weOwn)
        {
            var bonus = bot.Map.Bonuses[bonusID];
            var allUnownedTerrsInBonus = bonus.Territories.Where(o => !weOwn(bot.Standing.Territories[o])).ToHashSet(true);

            if (allUnownedTerrsInBonus.Count == 0)
            {
                return(new BonusPath(bonusID, 0, new HashSet <TerritoryIDType>())); //Already own the bonus. We'll only get here with one-territory bonuses during distribution
            }
            var terrsToTake = allUnownedTerrsInBonus.ToHashSet(true);

            var ownedTerritoriesTraverse = bot.Standing.Territories.Values.Where(o => weOwn(o)).Select(o => o.ID).ToHashSet(true);
            HashSet <TerritoryIDType> finalTerritoriesCaptured = null;

            var turns = 1;

            while (true)
            {
                var takeThisTurn = terrsToTake.Where(o => bot.Map.Territories[o].ConnectedTo.Keys.Any(z => ownedTerritoriesTraverse.Contains(z))).ToHashSet(true);

                if (takeThisTurn.Count == 0)
                {
                    //We can't take it without leaving the bonus.
                    AILog.Log("BonusPath", "  Could not find a way to take bonus " + bot.BonusString(bonus) + " without leaving it");
                    return(null);
                }

                if (takeThisTurn.Count == terrsToTake.Count)
                {
                    //We captured the bonus
                    finalTerritoriesCaptured = takeThisTurn;
                    break;
                }

                //Keep expanding!
                turns++;
                ownedTerritoriesTraverse.AddRange(takeThisTurn);
                terrsToTake.RemoveAll(takeThisTurn);
            }

            var terrsWeOwnInOrAroundBonus = bonus.Territories.Concat(bonus.Territories.SelectMany(o => bot.Map.Territories[o].ConnectedTo.Keys)).Where(o => weOwn(bot.Standing.Territories[o])).ToHashSet(false);
            var traverse = allUnownedTerrsInBonus.Concat(terrsWeOwnInOrAroundBonus).ToHashSet(false);

            var criticalPath = new HashSet <TerritoryIDType>();

            foreach (var final in finalTerritoriesCaptured)
            {
                var path = FindPath.TryFindShortestPathReversed(bot, o => weOwn(bot.Standing.Territories[o]), final, o => traverse.Contains(o));

                if (path != null)
                {
                    //AILog.Log("BonusPath", "  Critical path to " + bot.TerrString(final) + " goes " + path.Select(o => bot.TerrString(o)).JoinStrings(" -> "));
                    criticalPath.AddRange(path);
                }
                else
                {
                    AILog.Log("BonusPath", "  Could not find a path to " + bot.TerrString(final));
                }
            }

            //AILog.Log("BonusPath", "With infinite armies, we can take bonus " + bot.BonusString(bonus) + " in " + TurnsToTake + " turns. " + /*" Final territories=" + finalTerritoriesCaptured.Select(o => bot.TerrString(o)).JoinStrings(", ") +*/ "  Critical path=" + TerritoriesOnCriticalPath.Select(o => bot.TerrString(o)).JoinStrings(", "));

            return(new BonusPath(bonusID, turns, criticalPath));
        }
Пример #11
0
        public int TurnsToTakeByDistance; //how long to take the bonus, assuming we have infinite armies

        public BonusPath(BonusIDType bonusID, int turnsToTakeByDistance, HashSet <TerritoryIDType> terrsOnCriticalPath)
        {
            this.BonusID = bonusID;
            this.TurnsToTakeByDistance     = turnsToTakeByDistance;
            this.TerritoriesOnCriticalPath = terrsOnCriticalPath;
        }
Пример #12
0
 /// <param name="id">: a Bonus id number</param>
 /// <returns>: the matching Bonus object</returns>
 public BotBonus GetBonus(BonusIDType id)
 {
     return(Bonuses[id]);
 }
Пример #13
0
 public BotBonus(CowzowBot bot, BonusIDType id)
 {
     this.Bot          = bot;
     this.ID           = id;
     this.ArmiesReward = bot.Settings.OverriddenBonuses.ContainsKey(id) ? bot.Settings.OverriddenBonuses[id] : Details.Amount;
 }
Пример #14
0
        /// <summary>
        /// Estimate how many turns it would take us to complete the bonus, assuming we start in the passed territory and can use full deployment every turn
        /// </summary>
        /// <param name="bonusID"></param>
        /// <param name="bonusPath"></param>
        /// <returns></returns>
        private static CaptureTerritories TurnsToTake(BotMain bot, TerritoryIDType terrID, BonusIDType bonusID, BonusPath path)
        {
            var bonus       = bot.Map.Bonuses[bonusID];
            var terrsToTake = bonus.Territories.ExceptOne(terrID).ToHashSet(true);

            return(CaptureTerritories.TryFindTurnsToTake(bot, path, bot.Settings.InitialPlayerArmiesPerTerritory, bot.Settings.MinimumArmyBonus, terrsToTake, o => o.OwnerPlayerID == TerritoryStanding.AvailableForDistribution ? bot.Settings.InitialNeutralsInDistribution : o.NumArmies.DefensePower));
        }