public void MakeMove(Planet ownedPlanet, Planet target, int shipCount)
 {
     MakeMove(ownedPlanet, target, shipCount, true);
 }
Пример #2
0
        public void CreateTurnPredictionsForPlanet(Planet planet)
        {
            int planetID = planet.PlanetID;

            GrowthRate = planet.GrowthRate;
            ResetStats();
            PlanetTurn lastCalculatedTurn = this[0];

            lastCalculatedTurn.SetValues(planet.Owner, planet.NumShips);
            planet.LastAttackTurn = lastCalculatedTurn;

            PlanetTurn currentCalculatingTurn = lastCalculatedTurn.Next;

            planet.MaxDesertersAllowed          = planet.NumShips;
            planet.ShipsRequiredToSurviveAttack = planet.NumShips;
            planet.DoesNotChangeOwner           = true;

            int currentTurn = 1;

            if (planetID == 15)
            {
            }
            if (planet.Armada.Count > 0)
            {
                planet.IdleForThisNumberOfTurns = 0;
                foreach (var turn in planet.FleetArrivalByTurnsRemaining)
                {
                    do
                    {
                        lastCalculatedTurn     = currentCalculatingTurn;
                        currentCalculatingTurn = GrowTurn(GrowthRate, currentCalculatingTurn);
                    } while (currentTurn++ < turn.Key);

                    LastAttackTurn = lastCalculatedTurn;
                    bool survived = Universe.FightBattleAndOwnerSurvived(lastCalculatedTurn, turn);
                    if (lastCalculatedTurn.IsMine)
                    {
                        planet.MaxDesertersAllowed = Math.Min(planet.MaxDesertersAllowed, lastCalculatedTurn.NumShips);
                    }
                    if (!survived)
                    {
                        planet.DoesNotChangeOwner = false;
                    }
                }
            }

            while (currentCalculatingTurn != null)
            {
                lastCalculatedTurn     = currentCalculatingTurn;
                currentCalculatingTurn = GrowTurn(GrowthRate, currentCalculatingTurn);
            }
            planet.WinningArmadaIsMine = lastCalculatedTurn.Owner == 1;

            //int lastTurn = planet.FleetArrivalByTurnsRemaining.Last().Key;
            //lastAttackTurn = this[lastTurn];
            //for (int turnNumber = 1; turnNumber <= lastTurn; turnNumber++)
            //{
            //    lastCalculatedTurn = this[turnNumber];
            //    calc.Grow();
            //    lastCalculatedTurn.SetValues(calc.Owner, calc.NumShips);

            //    if (Universe.FightBattle(calc, turnNumber))
            //    {
            //        lastCalculatedTurn.SetValues(calc.Owner, calc.NumShips);
            //        planet.LastAttackTurn = lastCalculatedTurn;
            //        if (calc.IsMine)
            //        {
            //            planet.MaxDesertersAllowed = Math.Min(planet.MaxDesertersAllowed, calc.NumShips);
            //        }
            //        if (calc.IsEnemy)
            //        {
            //            planet.ShipsRequiredToSurviveAttack = Math.Max(planet.MaxDesertersAllowed, calc.NumShips + 1);
            //        }
            //        if (calc.IsNeutral)
            //        {
            //            planet.ShipsRequiredToSurviveAttack = Math.Min(planet.ShipsRequiredToSurviveAttack, calc.NumShips + 1);
            //        }
            //    }
            //    else
            //    {
            //        lastCalculatedTurn.SetValues(calc.Owner, calc.NumShips);
            //    }

            //    if (!calc.DoesNotChangeOwner)
            //    {
            //        planet.DoesNotChangeOwner = false;
            //    }
            //}
        }
        // Parses a game state from a string. On success, returns 1. On failure,
        // returns 0.
        private int ParseGameState(string boardLayout)
        {
            List <Fleet> fleetbuilder = new List <Fleet>();
            Dictionary <int, EditablePlayer> playerBuilder = new Dictionary <int, EditablePlayer>();
            int planetID = 0;

            string[] lines = boardLayout.Replace("\r", "").Split('\n');
            for (int i = 0; i < lines.Length; ++i)
            {
                string line         = lines[i];
                int    commentBegin = line.IndexOf('#');
                if (commentBegin >= 0)
                {
                    line = line.Substring(0, commentBegin);
                }
                if (line.Trim().Length == 0)
                {
                    continue;
                }
                string[] tokens = line.Split(' ');
                if (tokens.Length == 0)
                {
                    continue;
                }
                switch (tokens[0])
                {
                default:
                    break;

                case "P":
                case "p":
                    #region Add planet
                {
                    if (tokens.Length != 6)
                    {
                        return(0);
                    }
                    Planet         planet = BuildPlanet(planetID++, tokens);
                    EditablePlayer player = EnsurePlayer(playerBuilder, planet.Owner);
                    player.Planets.Add(planet);
                    planet.IdleForThisNumberOfTurns++;
                    player.ShipsOnBase           += planet.NumShips;
                    player.ShipGrowth            += planet.GrowthRate;
                    player.ShipsHeavyPoint.X     += planet.X * (double)planet.NumShips;
                    player.ShipsHeavyPoint.Y     += planet.Y * (double)planet.NumShips;
                    player.AbsolutePlanetFocus.Y += planet.Y;
                    player.AbsolutePlanetFocus.X += planet.X;
                    if (WishList.ContainsKey(planet.PlanetID))
                    {
                        if (planet.IsMine)
                        {
                            WishList.Remove(planet.PlanetID);
                        }
                        else
                        {
                            planet.IsOnWishList = true;
                        }
                    }
                    #endregion
                }
                break;

                case "F":
                case "f":
                {
                    #region AddFleet
                    if (tokens.Length != 7)
                    {
                        return(0);
                    }
                    Fleet          fleet  = BuildFleet(tokens);
                    EditablePlayer player = EnsurePlayer(playerBuilder, fleet.Owner);
                    player.Fleets.Add(fleet);
                    player.Targets.Add(fleet.DestinationPlanetId);
                    fleetbuilder.Add(fleet);
                    player.ShipsInTransit       += fleet.NumShips;
                    player.ShipInTransitFocus.X += fleet.DestinationPlanet.X * (double)fleet.NumShips;
                    player.ShipInTransitFocus.Y += fleet.DestinationPlanet.Y * (double)fleet.NumShips;



                    #endregion
                }
                break;
                }
            }

            //That's me
            EditablePlayer personalityBuilder = EnsurePlayer(playerBuilder, 1);
            Me = new Player(personalityBuilder.Fleets, personalityBuilder.Planets, personalityBuilder.Targets);
            personalityBuilder.InitializePlayer(Me);

            EditablePlayer neutralityBuilder = EnsurePlayer(playerBuilder, 0);
            Neutral = new Player(neutralityBuilder.Fleets, neutralityBuilder.Planets, personalityBuilder.Targets);
            neutralityBuilder.InitializePlayer(Neutral);

            All = new Player(fleetbuilder, Planets.Values.ToList(), new List <int>());

            foreach (EditablePlayer player in playerBuilder.Values)
            {
                TotalFleetCount += player.ShipsOnBase + player.ShipsInTransit;
            }

            EditablePlayer enemyBuilder = EnsurePlayer(playerBuilder, 2);
            Enemy = new Player(enemyBuilder.Fleets, enemyBuilder.Planets, enemyBuilder.Targets);
            enemyBuilder.InitializePlayer(Enemy);

            All.ShipGrowth = Me.ShipGrowth + Enemy.ShipGrowth + Neutral.ShipGrowth;


            if (Universe.TurnCount == 1)
            {
                CreatePlanetaryTravelRoutes();
            }

            foreach (Planet futurePlane in Planets.Values)
            {
                futurePlane.CreateTurnPredictions();
            }

            DeterminePlanetStrengthOnFleetArrival();
            return(1);
        }
 internal void MakeUnsafeMove(Planet ownedPlanet, Planet target, int shipCount)
 {
     MakeMove(ownedPlanet, target, shipCount, false);
 }
        public List <AttackPlan> BuildActionPlan(Universe uni)
        {
            currentUniverse = uni;
            StartOfTurn();
            DefendOnwedPlanets();
            DefendNeutralPlanets(MaxTurnLookaheadForNeutralDefense);
            ProcessAttackQueue();
            List <AttackPlan> battleplan = new List <AttackPlan>();

            foreach (Planet onwedPlanet in currentUniverse.Me.Planets.Where(OwnedPlanetCanSendAttackForce))
            {
                if (SourcePlanetSelected(onwedPlanet))
                {
                    var planetTravelMap = onwedPlanet.Routes;
                    if (PlanetRouteSelected(onwedPlanet, planetTravelMap))
                    {
                        bool       continueRoute = true;
                        AttackPlan attack        = new AttackPlan();
                        foreach (Route route in SortRoutesForBattlePlanCreation(planetTravelMap))
                        {
                            Planet hostile = route.Destination;
                            if (!hostile.IsMine)
                            {
                                attack.Target   = hostile;
                                attack.Enabled  = false;
                                attack.Strategy = GetType().Name;
                                attack.Reason   = "CreateAttackPlanForOwnedPlanet";
                                CreateAttackPlanForOwnedPlanet(attack, route, planetTravelMap, ref continueRoute);

                                if (attack.Enabled)
                                {
                                    if (onwedPlanet.IdleForThisNumberOfTurns >= 15)
                                    {
                                        attack.Sweetness += onwedPlanet.IdleForThisNumberOfTurns;
                                    }
                                    battleplan.Add(attack);
                                    attack = new AttackPlan();
                                }
                            }
                            if (!continueRoute)
                            {
                                break;
                            }
                        }
                    }
                    PlanetRouteDeSelected(onwedPlanet, planetTravelMap);
                }
            }
            if (!TakeGamble_DoNotCountOutgoingShipsForOneTurn)
            {
                //attack planets for all fleets in transit
                foreach (Planet planet in uni.All.Planets)
                {
                    if (!(planet.IsLost || planet.Armada.Count == 0))
                    {
                        foreach (Fleet attackforce in planet.Armada)
                        {
                            if (attackforce.IsMine)
                            {
                                planet.RemoveShips(attackforce.NumShips);
                            }
                        }
                    }
                }
            }
            TakeGamble_DoNotCountOutgoingShipsForOneTurn = false;
            return(battleplan);
        }
Пример #6
0
 public Route(Planet source, Planet destination)
 {
     Source      = source;
     Destination = destination;
 }
 protected abstract bool OwnedPlanetCanSendAttackForce(Planet ownedPlanet);
 protected virtual void PlanetRouteDeSelected(Planet onwedPlanet, PlanetaryTravelRoute planetTravelMap)
 {
 }
 //return true if we should should search this route. false to skip it
 protected virtual bool PlanetRouteSelected(Planet onwedPlanet, PlanetaryTravelRoute routesFromPlanet)
 {
     return(true);
 }
 //return true if we should should search this planet. false to skip it.
 protected virtual bool SourcePlanetSelected(Planet onwedPlanet)
 {
     return(true);
 }
        private AttackPlan BuildDefensePlan(Planet planetUnderAttack, int maxTurnLookAhead)
        {
            AttackPlan defensePlan = new AttackPlan();

            defensePlan.Target       = planetUnderAttack;
            defensePlan.Reason       = "Defense";
            planetUnderAttack.IsLost = !planetUnderAttack.WinningArmadaIsMine;

            PlanetTurn turn            = planetUnderAttack.TurnPrediction.FirstTurn;
            int        defenseRequired = 0;

            if (turn != null)
            {
                //this is weird, we are in no danger of losing the planet still this method was called. Abort.
                if (planetUnderAttack.WinningArmadaIsMine)
                {
                    return(defensePlan);
                }
                //the next turns tells me how many ships I needed, only works if my fleet was not the winning fleet.
                //that's why the previous exit.
                defenseRequired = planetUnderAttack.TurnPrediction[turn.TurnsFromNow + 1].NumShips + 1;
            }
            else
            {
                // So apparently I did not lose ownership of the planet, which means I never did own it.
                //see if we can block the attack.
                turn            = planetUnderAttack.TurnPrediction.FirstTurn;
                defenseRequired = turn.NumShips;
            }

            int armadaVictoryTurn = turn.TurnsFromNow;

            //if we want to recapture the planet the next turn how many ships do we need.
            //Since the enemy gets reinforces immediately after a capture, we are at a -GrowthRate disadvantage.
            int maxWorthItDistance;

            switch (planetUnderAttack.GrowthRate)
            {
            case 0:
            case 1: maxWorthItDistance = 5; break;

            case 2: maxWorthItDistance = 10; break;

            case 3:
            case 4: maxWorthItDistance = 15; break;

            default: maxWorthItDistance = 25; break;
            }

            //defend, remember, it's sorted on distance so the closest planets are considered first.
            foreach (Route route in planetUnderAttack.Routes)
            {
                if (route.DistanceInTurns <= Math.Min(maxTurnLookAhead, maxWorthItDistance))
                {
                    //look for planet with defense capability
                    Planet defender = route.Destination;
                    if (defender.IsMine && planetUnderAttack.PlanetID != defender.PlanetID)
                    {
                        //is it close enough to contribute to the defense?
                        int defenseTravelTime = (route.DistanceInTurns - 1);
                        if (defenseTravelTime <= armadaVictoryTurn + 1)
                        {
                            //How many ships can we use
                            int maxDelivarableShips = defender.AttackForce;
                            if (defender.DoesNotChangeOwner)
                            {
                                int turnIndex = Math.Max(armadaVictoryTurn - defenseTravelTime, 0);
                                maxDelivarableShips = defender.TurnPrediction[turnIndex].NumShips;
                            }

                            if (maxDelivarableShips > 0)
                            {
                                int prevRequired = defenseRequired;
                                defenseRequired -= maxDelivarableShips;
                                if (defender.NumShips > 0)
                                {
                                    defensePlan.Enabled = true;
                                    int shipCount;
                                    if (defenseRequired > -1)
                                    {
                                        shipCount = Math.Min(defender.AttackForce, defender.NumShips);
                                        defensePlan.AddParticipant(defender, null, shipCount);
                                    }
                                    else
                                    {
                                        shipCount = Math.Min(Math.Min(defender.AttackForce, defender.NumShips), prevRequired);
                                        defensePlan.AddParticipant(defender, null, shipCount);
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            if (defenseRequired < 0)
            {
                planetUnderAttack.DoesNotChangeOwner = true;
                planetUnderAttack.AttackMovesAllowed = false;
                planetUnderAttack.IsLost             = false;
            }

            //Planet is lost, no defense plan.
            if (planetUnderAttack.IsLost)
            {
                defensePlan.Participants.Clear();
            }
            return(defensePlan);
        }