示例#1
0
        public void AddParticipant(Planet participant, PlanetTurn turn, int scheduledTurn)
        {
            AttackPlanParticipant order = new AttackPlanParticipant();

            order.Source        = participant;
            order.AttackersTurn = turn;
            order.ScheduledTurn = scheduledTurn;
            Participants.Add(order);
        }
示例#2
0
        public void AddParticipant(Planet participant, PlanetTurn turn, PlanetTurn defendersTurn)
        {
            AttackPlanParticipant order = new AttackPlanParticipant();

            order.Source        = participant;
            order.AttackersTurn = turn;
            order.ScheduledTurn = turn.TurnsFromNow;
            order.DefendersTurn = defendersTurn;
            Participants.Add(order);
        }
示例#3
0
 public void DeterminePlanetStrengthOnFleetArrival()
 {
     foreach (Planet defendingPlanet in All.PlanetsUnderattack())
     {
         PlanetTurn lastTurn = defendingPlanet.TurnPrediction.LastTurn;
         if (defendingPlanet.DoesNotChangeOwner)
         {
             //defendingPlanet.MaxDesertersAllowed = Math.Min(defendingPlanet.NumShips, lastTurn.NumShips);
         }
         else
         {
             //So it does change owner, but is the owner me?
             if (lastTurn.Owner == 1)
             {
                 defendingPlanet.ShipsRequiredToSurviveAttack = -1;
                 //If I did not own it from the start, I can send no ships.
                 if (defendingPlanet.IsMine)
                 {
                     //So the part that's left standing does not have to be here.
                     // (this is a too simplified prediction, improve later.
                     defendingPlanet.MaxDesertersAllowed =
                         Math.Max(0                                                              // Negative value, not good for the engine.
                                  , Math.Min(defendingPlanet.MaxDesertersAllowed
                                             , lastTurn.NumShips                                 // Do not send ships we do not have, will end game quickly.
                                             ));
                 }
                 else
                 {
                     defendingPlanet.MaxDesertersAllowed = -1;
                 }
             }
             else
             {
                 //no, it is not mine, how many ships (at least) do we need to capture this?
                 if (defendingPlanet.IsMine)
                 {
                     defendingPlanet.ShipsRequiredToSurviveAttack = lastTurn.NumShips + 1;
                     defendingPlanet.MaxDesertersAllowed          = -1;
                 }
                 else
                 {
                     if (defendingPlanet.WinningArmadaIsMine)
                     {
                     }
                     else
                     {
                         defendingPlanet.MaxDesertersAllowed          = 0;
                         defendingPlanet.ShipsRequiredToSurviveAttack = defendingPlanet.LastAttackTurn.NumShips + 1;
                     }
                 }
             }
         }
     }
 }
示例#4
0
        internal static bool FightBattleAndOwnerSurvived(PlanetTurn lastCalculatedTurn, IGrouping <int, Fleet> turn)
        {
            Dictionary <int, int> participants = new Dictionary <int, int>();

            participants.Add(lastCalculatedTurn.Owner, lastCalculatedTurn.NumShips);

            foreach (Fleet fl in turn)
            {
                int attackForce;
                if (participants.TryGetValue(fl.Owner, out attackForce))
                {
                    participants[fl.Owner] = attackForce + fl.NumShips;
                }
                else
                {
                    participants.Add(fl.Owner, fl.NumShips);
                }
            }


            Fleet winner = new Fleet(0, 0, null, null, 0, 0);
            Fleet second = new Fleet(0, 0, null, null, 0, 0);

            foreach (var fleet in participants)
            {
                if (fleet.Value > second.NumShips)
                {
                    if (fleet.Value > winner.NumShips)
                    {
                        second = winner;
                        winner = new Fleet(fleet.Key, fleet.Value, null, null, 0, 0);
                    }
                    else
                    {
                        second = new Fleet(fleet.Key, fleet.Value, null, null, 0, 0);
                    }
                }
            }

            bool survived;

            if (winner.NumShips > second.NumShips)
            {
                survived = lastCalculatedTurn.Owner == winner.Owner;
                lastCalculatedTurn.SetValues(winner.Owner, winner.NumShips - second.NumShips);
            }
            else
            {
                survived = true;
                lastCalculatedTurn.SetValues(lastCalculatedTurn.Owner, 0);
            }
            return(survived);
        }
        public void DoTurn(Universe uni)
        {
            currentUniverse = uni;
            ProcessAttackQueue();
            bool attackMade = false;
            int sumAttackForce = 0;

            List<AttackPlan> possibleTargets = new List<AttackPlan>();

            foreach (var planet in CanUseInAtttack())
            {
                sumAttackForce += planet.AttackForce;
                //possibleTargets.Clear();
                PlanetTurn attackTurn = planet.TurnPrediction[0];

                PlanetTurn highestStateTakeOver = new PlanetTurn(0);
                //find planets that can be attacked with this planets force, from which I have most to gain
                foreach (var route in planet.Routes
                    .Where(target => IsNotEventuallyMine(target.Destination)
                                     && target.Destination.GrowthRate > 0))
                {
                    PlanetTurn stateTakeOver = null;
                    PlanetTurn destinationState = route.DestinationStateOnArrival;
                    PlanetTurn startAttackOnRun = attackTurn;
                    if (!destinationState.IsMine)
                    {
                        AttackPlan plan = new AttackPlan();

                        if (planet.AttackForce > destinationState.NumShips)
                        {
                            stateTakeOver = route.Destination.CalcMaxGainUsingThisManyShips(planet, route.DistanceInTurns, destinationState.NumShips + 5);
                            plan.Enabled = true;
                        }
                        else
                        {
                            do
                            {
                                destinationState = destinationState.Next;
                                startAttackOnRun = startAttackOnRun.Next;

                            } while (destinationState != null
                                && startAttackOnRun.NumShips < destinationState.NumShips);
            plan.Enabled = destinationState != null && startAttackOnRun != null;
                            if (plan.Enabled)
                            {
                                stateTakeOver = route.Destination.CalcMaxGainUsingThisManyShips(planet, destinationState.TurnsFromNow, startAttackOnRun.NumShips);
                            }

                        }

                        if (plan.Enabled)
                        {
                            plan.AddParticipant(planet, startAttackOnRun, destinationState);
                            plan.Target = route.Destination;
                            plan.Enabled = true;
                            plan.Sweetness = stateTakeOver.NumShips;
                            possibleTargets.Add(plan);
                            highestStateTakeOver = stateTakeOver;
                        }
                    }
                    //PlanetTurn fullAttackState = planet.TurnPrediction.CalcMaxGainUsingThisManyShips(destinationState, planet.AttackForce, TurnPrediction);
                    //planet.TurnPrediction.FindCheapestTakeOverPoint(destinationState.TurnsFromNow, TurnPrediction);
                }
            }
            foreach (AttackPlan plan in possibleTargets.OrderBy(item => -item.Sweetness).Take(10))
            {
                ExecutePlans(plan);
            }
            var centerPlanet = currentUniverse.Me.Planets
                .OrderBy(item => Universe.Center.Delta(item)).FirstOrDefault();

            if (centerPlanet != null)
            {
                int supportCount = 0;
                foreach (var planet in CanUseInAtttack())
                {
                    if (centerPlanet != planet)
                    {
                        supportCount++;
                        currentUniverse.MakeMove(planet, centerPlanet, Math.Min(planet.AttackForce, 2));
                    }
                }

            }

            //if (!attackMade)
            //{
            //    int targetOwnerId = 0;
            //    if (!currentUniverse.IsDominating)
            //    {
            //        if (rnd.NextDouble() > currentUniverse.Neutral.Planets.Count / (currentUniverse.Enemy.Planets.Count + 0.1))
            //        {
            //            targetOwnerId = 2;
            //        }
            //    }
            //    else
            //    {
            //        targetOwnerId = 2;
            //    }
            //    var target = currentUniverse.Planets.Values
            //           .Where(planet => planet.LastAttackTurn.NumShips < sumAttackForce - planet.GrowthRate * 2
            //                            && IsNotEventuallyMine(planet)
            //                            && planet.GrowthRate > 1
            //                            && planet.Owner == targetOwnerId
            //                            )
            //        .OrderBy(planet => -((planet.GrowthRate + Math.Sqrt(planet.NumShips)) / 3) * 3)
            //        .ThenBy(planet => currentUniverse.Me.ShipOnPlanetFocus.Delta(planet))
            //        .FirstOrDefault();

            //    if (target != null)
            //    {
            //        AttackPlan plan = new AttackPlan();
            //        plan.Enabled = true;
            //        plan.Target = target;
            //        foreach (var planet in CanUseInAtttack())
            //        {
            //            plan.AddParticipant(planet, planet.TurnPrediction[0], target.TurnPrediction[0]);
            //        }
            //        attackMade = true;
            //        ExecutePlans(plan);
            //    }
            //}

            //if (!attackMade && sumAttackForce > 100)
            //{

            //    AttackPlan plan = new AttackPlan();
            //    plan.Enabled = true;
            //    plan.DominationMove = true;
            //    plan.Target = centerPlanet;
            //    foreach (var planet in CanUseInAtttack().Where(item => item != centerPlanet))
            //    {
            //        plan.AddParticipant(planet, planet.TurnPrediction[0], centerPlanet.TurnPrediction[0]);
            //    }
            //    attackMade = true;
            //    ExecutePlans(plan);
            //}
        }
        public void DoTurn(Universe uni)
        {
            currentUniverse = uni;
            ProcessAttackQueue();
            bool attackMade     = false;
            int  sumAttackForce = 0;


            Dictionary <Planet, PlanetTurn> possibleTargets = new Dictionary <Planet, PlanetTurn>();

            foreach (var planet in CanUseInAtttack())
            {
                sumAttackForce += planet.AttackForce;
                possibleTargets.Clear();
                PlanetTurn attackTurn = planet.TurnPrediction[0];
                //find planets that can be attacked with this planets force.
                foreach (var route in planet.Routes
                         .Where(target => IsNotEventuallyMine(target.Destination) &&
                                target.Destination.GrowthRate > 0))
                {
                    PlanetTurn state = route.Destination.TurnPrediction[route.DistanceInTurns + 1];
                    if (state.Owner != 1 && state.NumShips < planet.AttackForce)
                    {
                        possibleTargets.Add(route.Destination, state);
                    }
                }
                // from the list find the planets from which I have most to gain or which are nearest.

                if (Universe.TurnCount < 3)
                {
                    foreach (var item in possibleTargets.OrderBy(
                                 target => - target.Key.GrowthRate)
                             .ThenBy(target => target.Value.NumShips))
                    {
                        if (planet.IsNeutral)
                        {
                            if (planet.AttackForce > item.Value.NumShips)
                            {
                                AttackPlan plan = new AttackPlan();
                                plan.Enabled = true;
                                plan.AddParticipant(planet, attackTurn, item.Value);
                                plan.Target = item.Key;
                                attackMade  = true;
                                ExecutePlans(plan);
                            }
                            else
                            {
                                break;
                            }
                        }
                    }
                }
                else
                {
                    foreach (var item in possibleTargets.OrderBy(
                                 target => - ((target.Key.IsNeutral ? 2 : 0) + target.Key.GrowthRate) / currentUniverse.Me.ShipOnPlanetFocus.Delta(target.Key)))
                    {
                        if (planet.AttackForce > item.Value.NumShips)
                        {
                            AttackPlan plan = new AttackPlan();
                            plan.Enabled = true;
                            plan.AddParticipant(planet, attackTurn, item.Value);
                            plan.Target = item.Key;
                            attackMade  = true;
                            ExecutePlans(plan);
                        }
                        else
                        {
                            break;
                        }
                    }
                }
            }

            var centerPlanet = currentUniverse.Me.Planets
                               .OrderBy(item => Universe.Center.Delta(item)
                                        + currentUniverse.Enemy.ShipOnPlanetFocus.Delta(item)).FirstOrDefault();

            if (centerPlanet != null)
            {
                int supportCount = 0;
                foreach (var planet in CanUseInAtttack())
                {
                    if (centerPlanet != planet)
                    {
                        supportCount++;
                        currentUniverse.MakeMove(planet, centerPlanet, Math.Min(planet.AttackForce, 2));
                    }
                }
            }


            if (!attackMade)
            {
                int targetOwnerId = 0;
                if (!currentUniverse.IsDominating)
                {
                    if (rnd.NextDouble() > currentUniverse.Neutral.Planets.Count / (currentUniverse.Enemy.Planets.Count + 0.1))
                    {
                        targetOwnerId = 2;
                    }
                }
                else
                {
                    targetOwnerId = 2;
                }
                var target = currentUniverse.Planets.Values
                             .Where(planet => planet.LastAttackTurn.NumShips < sumAttackForce - planet.GrowthRate * 2 &&
                                    IsNotEventuallyMine(planet) &&
                                    planet.GrowthRate > 1 &&
                                    planet.Owner == targetOwnerId
                                    )
                             .OrderBy(planet => - ((planet.GrowthRate + Math.Sqrt(planet.NumShips)) / 3) * 3)
                             .ThenBy(planet => currentUniverse.Me.ShipOnPlanetFocus.Delta(planet))
                             .FirstOrDefault();

                if (target != null)
                {
                    AttackPlan plan = new AttackPlan();
                    plan.Enabled = true;
                    plan.Target  = target;
                    foreach (var planet in CanUseInAtttack())
                    {
                        plan.AddParticipant(planet, planet.TurnPrediction[0], target.TurnPrediction[0]);
                    }
                    attackMade = true;
                    ExecutePlans(plan);
                }
            }



            if (!attackMade && sumAttackForce > 100)
            {
                AttackPlan plan = new AttackPlan();
                plan.Enabled        = true;
                plan.DominationMove = true;
                plan.Target         = centerPlanet;
                foreach (var planet in CanUseInAtttack().Where(item => item != centerPlanet))
                {
                    plan.AddParticipant(planet, planet.TurnPrediction[0], centerPlanet.TurnPrediction[0]);
                }
                attackMade = true;
                ExecutePlans(plan);
            }
        }
        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);
        }
        public void DoTurn(Universe uni)
        {
            currentUniverse = uni;
            ProcessAttackQueue();
            bool attackMade     = false;
            int  sumAttackForce = 0;


            List <AttackPlan> possibleTargets = new List <AttackPlan>();

            foreach (var planet in CanUseInAtttack())
            {
                sumAttackForce += planet.AttackForce;
                //possibleTargets.Clear();
                PlanetTurn attackTurn = planet.TurnPrediction[0];


                PlanetTurn highestStateTakeOver = new PlanetTurn(0);
                //find planets that can be attacked with this planets force, from which I have most to gain
                foreach (var route in planet.Routes
                         .Where(target => IsNotEventuallyMine(target.Destination) &&
                                target.Destination.GrowthRate > 0))
                {
                    PlanetTurn stateTakeOver    = null;
                    PlanetTurn destinationState = route.DestinationStateOnArrival;
                    PlanetTurn startAttackOnRun = attackTurn;
                    if (!destinationState.IsMine)
                    {
                        AttackPlan plan = new AttackPlan();

                        if (planet.AttackForce > destinationState.NumShips)
                        {
                            stateTakeOver = route.Destination.CalcMaxGainUsingThisManyShips(planet, route.DistanceInTurns, destinationState.NumShips + 5);
                            plan.Enabled  = true;
                        }
                        else
                        {
                            do
                            {
                                destinationState = destinationState.Next;
                                startAttackOnRun = startAttackOnRun.Next;
                            } while (destinationState != null &&
                                     startAttackOnRun.NumShips < destinationState.NumShips);
                            plan.Enabled = destinationState != null && startAttackOnRun != null;
                            if (plan.Enabled)
                            {
                                stateTakeOver = route.Destination.CalcMaxGainUsingThisManyShips(planet, destinationState.TurnsFromNow, startAttackOnRun.NumShips);
                            }
                        }

                        if (plan.Enabled)
                        {
                            plan.AddParticipant(planet, startAttackOnRun, destinationState);
                            plan.Target    = route.Destination;
                            plan.Enabled   = true;
                            plan.Sweetness = stateTakeOver.NumShips;
                            possibleTargets.Add(plan);
                            highestStateTakeOver = stateTakeOver;
                        }
                    }
                    //PlanetTurn fullAttackState = planet.TurnPrediction.CalcMaxGainUsingThisManyShips(destinationState, planet.AttackForce, TurnPrediction);
                    //planet.TurnPrediction.FindCheapestTakeOverPoint(destinationState.TurnsFromNow, TurnPrediction);
                }
            }
            foreach (AttackPlan plan in possibleTargets.OrderBy(item => - item.Sweetness).Take(10))
            {
                ExecutePlans(plan);
            }
            var centerPlanet = currentUniverse.Me.Planets
                               .OrderBy(item => Universe.Center.Delta(item)).FirstOrDefault();

            if (centerPlanet != null)
            {
                int supportCount = 0;
                foreach (var planet in CanUseInAtttack())
                {
                    if (centerPlanet != planet)
                    {
                        supportCount++;
                        currentUniverse.MakeMove(planet, centerPlanet, Math.Min(planet.AttackForce, 2));
                    }
                }
            }


            //if (!attackMade)
            //{
            //    int targetOwnerId = 0;
            //    if (!currentUniverse.IsDominating)
            //    {
            //        if (rnd.NextDouble() > currentUniverse.Neutral.Planets.Count / (currentUniverse.Enemy.Planets.Count + 0.1))
            //        {
            //            targetOwnerId = 2;
            //        }
            //    }
            //    else
            //    {
            //        targetOwnerId = 2;
            //    }
            //    var target = currentUniverse.Planets.Values
            //           .Where(planet => planet.LastAttackTurn.NumShips < sumAttackForce - planet.GrowthRate * 2
            //                            && IsNotEventuallyMine(planet)
            //                            && planet.GrowthRate > 1
            //                            && planet.Owner == targetOwnerId
            //                            )
            //        .OrderBy(planet => -((planet.GrowthRate + Math.Sqrt(planet.NumShips)) / 3) * 3)
            //        .ThenBy(planet => currentUniverse.Me.ShipOnPlanetFocus.Delta(planet))
            //        .FirstOrDefault();

            //    if (target != null)
            //    {
            //        AttackPlan plan = new AttackPlan();
            //        plan.Enabled = true;
            //        plan.Target = target;
            //        foreach (var planet in CanUseInAtttack())
            //        {
            //            plan.AddParticipant(planet, planet.TurnPrediction[0], target.TurnPrediction[0]);
            //        }
            //        attackMade = true;
            //        ExecutePlans(plan);
            //    }
            //}



            //if (!attackMade && sumAttackForce > 100)
            //{

            //    AttackPlan plan = new AttackPlan();
            //    plan.Enabled = true;
            //    plan.DominationMove = true;
            //    plan.Target = centerPlanet;
            //    foreach (var planet in CanUseInAtttack().Where(item => item != centerPlanet))
            //    {
            //        plan.AddParticipant(planet, planet.TurnPrediction[0], centerPlanet.TurnPrediction[0]);
            //    }
            //    attackMade = true;
            //    ExecutePlans(plan);
            //}
        }