public List<AttackPlan> BuildActionPlan(Universe uni)
    {
        currentUniverse = uni;
        StartOfTurn();
        DefendOnwedPlanets();
        DefendNeutralPlanets(MaxTurnLookaheadForNeutralDefense);
        List<AttackPlan> battleplan = new List<AttackPlan>();
        foreach (Planet onwedPlanet in currentUniverse.Me.Planets.Where(OwnedPlanetCanSendAttackForce))
        {
            if (SourcePlanetSelected(onwedPlanet))
            {
                var planetTravelMap = Universe.TravelMap[onwedPlanet.PlanetID];
                if (PlanetRouteSelected(onwedPlanet, planetTravelMap))
                {
                    bool continueRoute = true;
                    AttackPlan attack = new AttackPlan();
                    foreach (Route route in planetTravelMap)
                    {
                        Planet hostile = currentUniverse.AllPlanetsOnPlanetId[route.TagetPlanetId];
                        if (!hostile.IsMine)
                        {
                            attack.Distance = route.DistanceInTurns;
                            attack.Source = onwedPlanet;
                            attack.Target = hostile;
                            attack.Enabled = false;

                            CreateAttackPlanForOwnedPlanet(attack, route, planetTravelMap, ref continueRoute);

                            if (attack.Enabled)
                            {
                                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;
    }
Beispiel #2
0
        private void AddPlan(AttackPlan plan)
        {
            if (IsHelpVisible)
            {
                toolStrip1.Items.OfType <ToolStripItem>().Where(x => x.Tag == null || x.Tag.ToString() != "OWN_VISIBILITY").ForEach(x => x.Visible = true);
                toolStrip2.Visible = true;
                AllPlans.Controls.Clear();
            }

            var newPlanDropdownItm = new ToolStripMenuItem("", null, SelectPlan);

            newPlanDropdownItm.Text = GetAttackToolstripText(plan);
            AttackDropDown.DropDownItems.Add(newPlanDropdownItm);

            var newPlan = new AttackPlanControl(WorldUnits.Default.ImageList, plan);

            newPlan.Visible = false;
            newPlan.Dock    = DockStyle.Fill;
            _plans.Add(plan, new Tuple <ToolStripMenuItem, AttackPlanControl>(newPlanDropdownItm, newPlan));
            AllPlans.Controls.Add(newPlan);

            foreach (AttackPlanFrom attack in plan.Attacks)
            {
                newPlan.AddAttacker(attack);
            }

            Timer.Enabled = true;
        }
Beispiel #3
0
        public ActionResult Attack(Board b, Player p, AttackPlan plan)
        {
            // Basic tests
            if (b.AttackIsInvalid(plan))
            {
                return(ActionResult.INVALID);
            }

            // Always win
            var r = new ActionResult()
            {
                AttackWasInvalid = false,
                Plan             = plan,
                AttackSucceeded  = true,
                Animations       = new List <BaseAnimation>()
            };

            // Add battle animation
            r.Animations.Add(new AttackAnimation(b, plan.Attacker, plan.Defender, new System.Threading.Tasks.Task(() =>
            {
                if (plan.Defender.Owner != null)
                {
                    plan.Defender.Owner.Zones.Remove(plan.Defender);
                    if (plan.Defender.Owner.Zones.Count == 0)
                    {
                        plan.Defender.Owner.IsDead = true;
                    }
                }
                plan.Defender.Owner = plan.Attacker.Owner;
                plan.Attacker.Owner.Zones.Add(plan.Defender);
                plan.Defender.Strength = plan.Attacker.Strength - 1;
                plan.Attacker.Strength = 1;
            })));
            return(r);
        }
Beispiel #4
0
        private void RemovePlan(AttackPlan plan)
        {
            var attackControls = _plans[plan];

            AllPlans.Controls.Remove(attackControls.Item2);
            AttackDropDown.DropDownItems.Remove(attackControls.Item1);
            _plans.Remove(plan);

            if (ActivePlan == attackControls.Item2)
            {
                if (AttackDropDown.DropDownItems.Count > 0)
                {
                    SelectPlan(AttackDropDown.DropDownItems[0], EventArgs.Empty);
                }
                else
                {
                    SelectPlan(null, EventArgs.Empty);
                }
            }

            if (!_plans.Any())
            {
                ShowHelp();
            }
        }
Beispiel #5
0
 private void cbAttackPlans_TextUpdate(object sender, EventArgs e)
 {
     if (attackPlansBindingSource.Current != null)
     {
         AttackPlan plan = (AttackPlan)attackPlansBindingSource.Current;
         plan.Name = cbAttackPlans.Text;
     }
 }
Beispiel #6
0
        public AttackPlanControl(ImageList imageList, AttackPlan plan)
        {
            InitializeComponent();
            _unitImageList = imageList;

            Plan = plan;
            SetControlProperties();
        }
Beispiel #7
0
        public AttackPlanControl(ImageList imageList, AttackPlan plan)
        {
            InitializeComponent();
            _unitImageList = imageList;

            Plan = plan;
            SetControlProperties();
        }
Beispiel #8
0
        public void AttackRemoveTarget(object sender, AttackPlan plan)
        {
            var e = new AttackEventArgs(plan, null);

            if (TargetRemoved != null)
            {
                TargetRemoved(sender, e);
            }
        }
Beispiel #9
0
 /// <summary>
 /// Returns true if this attack is invalid
 /// </summary>
 /// <param name="plan"></param>
 /// <returns></returns>
 public bool AttackIsInvalid(AttackPlan plan)
 {
     return(plan == null ||
            plan.Attacker == null ||
            plan.Defender == null ||
            plan.Attacker.Owner == null ||
            plan.Attacker.Strength <= 1 ||
            !plan.Attacker.Neighbors.Contains(plan.Defender) ||
            plan.Attacker.Owner == plan.Defender.Owner);
 }
Beispiel #10
0
        private string GetAttackToolstripText(AttackPlan plan)
        {
            Village vil        = plan.Target;
            string  attackDesc = string.Format(ControlsRes.AttackPlanCollectionControl_PlanExportCaption, vil.LocationString, vil.Name, Common.GetPrettyNumber(vil.Points), plan.Attacks.Count());

            if (vil.HasPlayer)
            {
                attackDesc += string.Format(ControlsRes.AttackPlanCollectionControl_PlanExportCaption_OnPlayer, vil.Player.Name);
            }
            return(attackDesc);
        }
Beispiel #11
0
 private static void AssignPlan(AttackPlan assignPlan, World world)
 {
     if (assignPlan != null)
     {
         var gelu      = world.Objects.OfType <Gelu>().Single();
         var catherine = world.Objects.OfType <Catherine>().Single();
         var shift     = new Point(1, 1);
         gelu.SetPathPlan(assignPlan.GeluPath.Select(p => p.Add(shift)).ToArray());
         catherine.SetPathPlan(assignPlan.CatherinePath.Select(p => p.Add(shift)).ToArray());
     }
 }
Beispiel #12
0
        public VillageContextMenu(Map map, Village village, Action onVillageTypeChangeDelegate = null)
        {
            _village = village;
            _map     = map;
            _onVillageTypeChangeDelegate = onVillageTypeChangeDelegate;
            _attackPlan = World.Default.Map.Manipulators.AttackManipulator.GetPlan(_village, out _isActiveAttackPlan, out _attacker, false);

            _menu = JanusContextMenu.Create();

            AddAttackPlanItems();

            _menu.AddSeparator();

            if (map.Display.IsVisible(village))
            {
                _menu.AddCommand(ControlsRes.ContextMenu_QuickDetails, OnPinPoint, Properties.Resources.LeftNavigation_QuickFind);
            }
            _menu.AddCommand(ControlsRes.ContextMenu_PinpointAndCenter, OnPinpointAndCenter, Properties.Resources.TeleportIcon);

            _menu.AddSeparator();
            _menu.AddSetVillageTypeCommand(OnVillageTypeChange, village);

            if (World.Default.Settings.Church)
            {
                var church = _map.Manipulators.ChurchManipulator.GetChurch(_village);
                AddChurchCommands(_menu, church, ChurchChange_Click);
            }

            if (village.HasPlayer)
            {
                _menu.AddSeparator();

                _menu.AddPlayerContextCommands(map, village.Player, false);

                if (village.HasTribe)
                {
                    _menu.AddTribeContextCommands(map, village.Player.Tribe);
                }

                if (village.PreviousVillageDetails != null && village.PreviousVillageDetails.Player != village.Player && village.PreviousVillageDetails.Player != null)
                {
                    var oldPlayer = World.Default.GetPlayer(village.PreviousVillageDetails.Player.Name);
                    _menu.AddPlayerNobledContextCommands(map, oldPlayer ?? village.PreviousVillageDetails.Player, true);
                }
            }

            _menu.AddSeparator();
            _menu.AddCommand(ControlsRes.ContextMenu_TwStats, OnTwStats);
            _menu.AddCommand(ControlsRes.ContextMenu_ToClipboard, OnToClipboard, Properties.Resources.clipboard);
            _menu.AddCommand(ControlsRes.ContextMenu_ToBbCode, OnBbCode, Properties.Resources.clipboard);
        }
Beispiel #13
0
        public void HandleTouch(object sender, SKPoint location)
        {
            if (!GameBoard.CurrentPlayer.IsHuman)
            {
                return;
            }

            // Was this an end turn touch?
            if (Dimensions.EndTurnRect.Rect.Contains(location))
            {
                Playing = GameBoard.EndTurn();
            }

            // Figure out what zone was touched
            var zone = HitTestZone(location);

            if (zone == null)
            {
                return;
            }

            // Set an attacker
            if (this.Attacking == null)
            {
                if (zone.Owner.Number != GameBoard.CurrentTurn)
                {
                    return;
                }
                this.Attacking = zone;
                return;
            }

            // Setup attack plan
            var plan = new AttackPlan()
            {
                Attacker = Attacking,
                Defender = zone
            };

            // Execute the attack and see what the result is
            ExecuteAttackPlan(plan);
        }
Beispiel #14
0
        public ActionResult Attack(Board b, Player p, AttackPlan plan)
        {
            // Basic tests
            if (b.AttackIsInvalid(plan))
            {
                return(ActionResult.INVALID);
            }

            // Roll dice based on strength - note that one unit must stay home for attacker
            int  attacker_roll = b.Roll(plan.Attacker.Strength - 1, 6);
            int  defender_roll = b.Roll(plan.Defender.Strength, 6);
            bool wins          = attacker_roll > defender_roll;

            // Handle the best roll
            var r = new ActionResult()
            {
                AttackWasInvalid = false,
                Plan             = plan,
                AttackSucceeded  = wins,
                Animations       = new List <BaseAnimation>()
            };

            r.Animations.Add(new AttackAnimation(b, plan.Attacker, plan.Defender, new System.Threading.Tasks.Task(() =>
            {
                if (wins)
                {
                    if (plan.Defender.Owner != null)
                    {
                        plan.Defender.Owner.Zones.Remove(plan.Defender);
                        if (plan.Defender.Owner.Zones.Count == 0)
                        {
                            plan.Defender.Owner.IsDead = true;
                        }
                    }
                    plan.Defender.Owner = plan.Attacker.Owner;
                    plan.Attacker.Owner.Zones.Add(plan.Defender);
                    plan.Defender.Strength = plan.Attacker.Strength - 1;
                }
                plan.Attacker.Strength = 1;
            })));
            return(r);
        }
Beispiel #15
0
        private void btnDelAttackPlan_Click(object sender, EventArgs e)
        {
            if (attackPlansBindingSource.Current != null)
            {
                AttackPlan plan = (AttackPlan)attackPlansBindingSource.Current;

                string msg     = "Den Angriffsplan '" + plan.Name + "' wirklich löschen?";
                string caption = "Angriffsplan löschen?";
                if (Program.Language == LanguageType.English)
                {
                    msg     = "Really delete '" + plan.Name + "'?";
                    caption = "Delete Attack Plan?";
                }

                // Sicherheitsabfrage!
                if (MessageBox.Show(msg, caption, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    m_AttackHandler.AttackPlans.Remove(plan);
                }
            }
        }
Beispiel #16
0
        public void ExecuteAttackPlan(AttackPlan plan)
        {
            var result = GameBoard.BattleRule.Attack(GameBoard, GameBoard.Players[GameBoard.CurrentTurn], plan);

            // Safety check
            if (result.AttackWasInvalid)
            {
                return;
            }

            // Set up all animations in sequence
            if (result.Animations != null)
            {
                foreach (var a in result.Animations)
                {
                    PlayQueue.Enqueue(a);
                }
            }

            // Clear attacker animation if any
            this.Attacking = null;
        }
    private IEnumerable <AttackPlan> BuildDefensePlan(Planet planetUnderAttack, int maxTurnLookAhead)
    {
        List <AttackPlan> resultBuilder = new List <AttackPlan>();

        planetUnderAttack.IsLost = true;
        int defenseRequired = planetUnderAttack.ShipsRequiredToSurviveAttack;
        //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 recaptureArmadaStrength = -planetUnderAttack.GrowthRate;
        int armadaVictoryTurn       = planetUnderAttack.LostAfterNumberOfTurns;

        //defend, remember, it's sorted on distance so the closest planets are considered first.
        foreach (Route route in Universe.TravelMap[planetUnderAttack.PlanetID])
        {
            if (route.DistanceInTurns <= maxTurnLookAhead)
            {
                //look for planet with defense capability
                Planet defender = currentUniverse.AllPlanetsOnPlanetId[route.TagetPlanetId];
                if (defender.IsMine && planetUnderAttack.PlanetID != defender.PlanetID)
                {
                    //is it close enough to contribute to the defense?
                    int defenseTravelTime = (route.DistanceInTurns - 1);
                    if (defenseTravelTime <= armadaVictoryTurn)
                    {
                        //How many ships can we use
                        int maxDelivarableShips;
                        maxDelivarableShips = defender.AttackForce;
                        if (defender.CanSurviveIncommingAttack)
                        {
                            maxDelivarableShips = defender.AttackForce;
                            // How many turns left before reinforcements will not make it in time?
                            // armadaVictoryTurn - turnsLeftForDefense
                            maxDelivarableShips += (armadaVictoryTurn - defenseTravelTime) * defender.GrowthRate;
                            //can we do a recapture, count the fleets we can use for a counter attack in the turn after capture.
                            recaptureArmadaStrength += defender.GrowthRate;
                        }


                        if (maxDelivarableShips > 0)
                        {
                            int prevRequired = defenseRequired;
                            defenseRequired -= maxDelivarableShips;
                            if (defender.NumShips > 0)
                            {
                                AttackPlan armada = new AttackPlan();
                                armada.Target  = planetUnderAttack;
                                armada.Source  = defender;
                                armada.Enabled = true;
                                if (defenseRequired > -1)
                                {
                                    armada.ShipCount = Math.Min(defender.AttackForce, defender.NumShips);
                                    resultBuilder.Add(armada);
                                }
                                else
                                {
                                    armada.ShipCount = Math.Min(Math.Min(defender.AttackForce, defender.NumShips), maxDelivarableShips - prevRequired);
                                    resultBuilder.Add(armada);
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }
        if (defenseRequired < 0)
        {
            planetUnderAttack.CanSurviveIncommingAttack = true;
            planetUnderAttack.AttackMovesAllowed        = false;
            planetUnderAttack.IsLost = false;
        }

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

        return(resultBuilder);
    }
    public List <AttackPlan> BuildActionPlan(Universe uni)
    {
        currentUniverse = uni;
        StartOfTurn();
        DefendOnwedPlanets();
        DefendNeutralPlanets(MaxTurnLookaheadForNeutralDefense);
        List <AttackPlan> battleplan = new List <AttackPlan>();

        foreach (Planet onwedPlanet in currentUniverse.Me.Planets.Where(OwnedPlanetCanSendAttackForce))
        {
            if (SourcePlanetSelected(onwedPlanet))
            {
                var planetTravelMap = Universe.TravelMap[onwedPlanet.PlanetID];
                if (PlanetRouteSelected(onwedPlanet, planetTravelMap))
                {
                    bool       continueRoute = true;
                    AttackPlan attack        = new AttackPlan();
                    foreach (Route route in planetTravelMap)
                    {
                        Planet hostile = currentUniverse.AllPlanetsOnPlanetId[route.TagetPlanetId];
                        if (!hostile.IsMine)
                        {
                            attack.Distance = route.DistanceInTurns;
                            attack.Source   = onwedPlanet;
                            attack.Target   = hostile;
                            attack.Enabled  = false;

                            CreateAttackPlanForOwnedPlanet(attack, route, planetTravelMap, ref continueRoute);

                            if (attack.Enabled)
                            {
                                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);
    }
 protected abstract void CreateAttackPlanForOwnedPlanet(AttackPlan attack, Route attackRoute, PlanetaryTravelRoute planetTravelMap, ref bool continueRoute);
Beispiel #20
0
        public ActionResult Attack(Board b, Player p, AttackPlan plan)
        {
            // Basic tests
            if (b.AttackIsInvalid(plan))
            {
                return(ActionResult.INVALID);
            }

            // Roll one die per strength counter, sort by highest rolls descending
            var attacker_rolls = (from x in b.MultiRoll(plan.Attacker.Strength - 1, 6) orderby x descending select x).ToList();
            var defender_rolls = (from x in b.MultiRoll(plan.Defender.Strength, 6) orderby x descending select x).ToList();

            // Compare each die from attacker to defender
            // Defender wins ties
            // Attacker wins any excess attackers that were not paired to a defender
            int attacker_losses = 0, defender_losses = 0;

            for (int i = 0; i < attacker_rolls.Count; i++)
            {
                if (i < defender_rolls.Count)
                {
                    if (attacker_rolls[i] > defender_rolls[i])
                    {
                        defender_losses++;
                    }
                    else if (attacker_rolls[i] < defender_rolls[i])
                    {
                        attacker_losses++;
                    }
                }
                else
                {
                    defender_losses++;
                }
            }

            // Attacker wins if defender is reduced to zero
            var wins = (defender_losses >= plan.Defender.Strength);

            // Handle results
            var r = new ActionResult()
            {
                AttackWasInvalid = false,
                Plan             = plan,
                AttackSucceeded  = wins,
                Animations       = new List <BaseAnimation>()
            };

            r.Animations.Add(new AttackAnimation(b, plan.Attacker, plan.Defender, new System.Threading.Tasks.Task(() =>
            {
                if (wins)
                {
                    if (plan.Defender.Owner != null)
                    {
                        plan.Defender.Owner.Zones.Remove(plan.Defender);
                        if (plan.Defender.Owner.Zones.Count == 0)
                        {
                            plan.Defender.Owner.IsDead = true;
                        }
                    }
                    plan.Defender.Owner = plan.Attacker.Owner;
                    plan.Attacker.Owner.Zones.Add(plan.Defender);
                    plan.Defender.Strength = plan.Attacker.Strength - attacker_losses - 1;
                    plan.Attacker.Strength = 1;
                }
                else
                {
                    plan.Attacker.Strength = plan.Attacker.Strength - attacker_losses;
                    plan.Defender.Strength = plan.Defender.Strength - defender_losses;
                }
            })));
            return(r);
        }
        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);
            //}
        }
Beispiel #22
0
 public AttackEventArgs(AttackPlan plan, AttackPlanFrom attacker)
 {
     Debug.Assert(attacker == null || attacker.Plan == plan);
     Attacker = attacker;
     Plan     = 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);
            }
        }
    protected override void CreateAttackPlanForOwnedPlanet(AttackPlan attack, Route attackRoute, PlanetaryTravelRoute planetTravelMap, ref bool continueRoute)
    {
        Planet myPlanet = attack.Source;
        Planet hostile  = attack.Target;

        if (Universe.TurnCount > 1 && hostile.GrowthRate > 0)
        {
            //check to see if we need our strength (and leave some)
            if (myPlanet.IsUnderAttack && myPlanet.CanSurviveIncommingAttack && myPlanet.AttackForce < 10)
            {
                return;
            }
            if (myPlanet.PlanetID == 2)
            {
                if (hostile.PlanetID == 17)
                {
                }
            }

            if (Universe.TurnCount < SuperDefenseCutOffPoint)
            {
                //VERY aggressive move, putting a great army very near me.
                if ((attackRoute.DistanceInTurns < 5) &&
                    (hostile.IsUnderAttack) &&
                    ((double)hostile.Armada.EnemyFleetSize / ((double)myPlanet.AttackForce + 1) > 0.5))
                {
                    //Counter with aggressive defense, I will capture the planet
                    // how many ships needed to block enemy?
                    int shipsNeeded = Math.Max(hostile.Armada.EnemyFleetSize - hostile.Armada.FriendlyFleetSize, hostile.NumShips + attackRoute.GrowthForTravelDistance);
                    currentUniverse.MakeMove(myPlanet, hostile, shipsNeeded + 1);
                    continueRoute = false;
                    return;
                }

                //Close quarters fighting is special. Can I kill him early?
                if (hostile.IsEnemy && (attackRoute.GrowthForTravelDistance + hostile.NumShips) < myPlanet.ShipCountAtStartOfTurn)
                {
                    if (myPlanet.IsUnderAttack)
                    {
                        // Do not lose the planet, be defensive.
                        continueRoute = false;
                        return;
                    }
                    else
                    {
                        if (hostile.CanSurviveIncommingAttack)
                        {
                            //He is still healthy, attack
                            int max = attackRoute.GrowthForTravelDistance + hostile.NumShips + hostile.GrowthRate;
                            currentUniverse.MakeUnsafeMove(myPlanet, hostile, Math.Min(max, myPlanet.NumShips));
                            continueRoute = false;
                            return;
                        }
                        //ok, so this planet is beat. next please.
                    }
                }

                if (NearestEnemy == null || attackRoute.ActualDistance > NearestEnemy.ActualDistance)
                {
                    return;
                }
            }

            if (Universe.IsDominating)
            {
                if (!myPlanet.IsUnderAttack)
                {
                    if (hostile.CanSurviveIncommingAttack)
                    {
                        attack.ShipCount = (int)(myPlanet.AttackForce * 0.9);
                        attack.Enabled   = true;

                        if (hostile.IsNeutral)
                        {
                            attack.Sweetness = (double)hostile.GrowthRate - 2;
                        }
                        if (hostile.IsEnemy)
                        {
                            attack.Sweetness = (double)hostile.GrowthRate;
                        }
                    }
                }
            }
            else
            {
                bool isNear = attackRoute.ActualDistance < Universe.TravelMap.AverageDistance;
                if (myPlanet.PlanetID == 7)
                {
                    if (hostile.PlanetID == 14)
                    {
                    }
                }

                double ConnectedNess = Universe.TravelMap.AverageDistance / attackRoute.TargetConnectiveNess;


                if (isNear || Universe.IsDominating)
                {
                    double powerbase = hostile.GrowthRate;
                    if (hostile.IsNeutral)
                    {
                        powerbase += 0.5;
                    }
                    attack.Sweetness = (Math.Pow(powerbase, ConnectedNess) / (attackRoute.ActualDistance));

                    attack.ShipCount = myPlanet.AttackForce;

                    if (hostile.IsEnemy)
                    {
                        bool fleetStrongrThanPlanet = attackRoute.GrowthForTravelDistance + hostile.NumShips < myPlanet.AttackForce;
                        if (fleetStrongrThanPlanet || hostile.IsOnWishList)
                        {
                            //attack.Sweetness = -(hostile.NumShips + (hostile.GrowthRate * attackRoute.Distance));
                            //attack.Sweetness = Math.Pow(hostile.GrowthRate, 3) / Math.Pow(attackRoute.DistanceInTurns, 1.5);

                            attack.Enabled = true;
                        }
                    }
                    else
                    {
                        if (Universe.IsDominating || hostile.Armada.EffectiveFleetSizeForMe() < myPlanet.AttackForce || hostile.IsOnWishList)
                        {
                            //attack.ShipCount = (int)(hostile.NumShips * 1.10);
                            attack.Enabled = true;
                        }
                    }

                    System.Diagnostics.Debug.WriteLine(
                        "(" + myPlanet.PlanetID + ") " + attack.ShipCount + " ==> (" + hostile.PlanetID + ") C: " + ConnectedNess + "  D: (" + attackRoute.ActualDistance + ") Like:" + attack.Sweetness);
                }
            }
        }
    }
Beispiel #25
0
        public void AttackSelect(object sender, AttackPlan plan)
        {
            var e = new AttackEventArgs(plan, null);

            AttackSelect(sender, e);
        }
        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;
        }
 protected abstract void CreateAttackPlanForOwnedPlanet(AttackPlan attack, Route attackRoute, PlanetaryTravelRoute planetTravelMap, ref bool continueRoute);
        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;
        }
Beispiel #29
0
 public AttackEventArgs(AttackPlan plan, AttackPlanFrom attacker)
 {
     Debug.Assert(attacker == null || attacker.Plan == plan);
     Attacker = attacker;
     Plan = plan;
 }
        protected bool ExecutePlans(AttackPlan sweetPlan)
        {
            bool movemade = false;
            foreach (AttackPlanParticipant attacker in sweetPlan.Participants)
            {
                Planet agressor = attacker.Source;
                agressor.IsInAttackQueue = attacker.ScheduledTurn > 0;
                if (attacker.ScheduledTurn <= 0)
                {
                    if (attacker.DefendersTurn.Owner != 1 || sweetPlan.DominationMove)
                    {
                        if (agressor.IsMine)
                        {
                            int ships = attacker.AttackersTurn.NumShips;
                            if (!sweetPlan.Target.IsMine)
                            {
                                ships = Math.Min(attacker.DefendersTurn.NumShips + 1, ships);
                            }
                            ships = Math.Min(ships, agressor.AttackForce);

                            currentUniverse.MakeMove(agressor, sweetPlan.Target, ships);
                            movemade = true;
                            agressor.CreateTurnPredictions();
                        }
                    }
                }
                else
                {
                    //attacker.Source.MaxDesertersAllowed = 0;
                }
                attacker.ScheduledTurn--;
            }
            if (sweetPlan.Target.IsMine || sweetPlan.Participants.Count == 0)
            {
                foreach (AttackPlanParticipant attacker in sweetPlan.Participants)
                {
                    attacker.Source.IsInAttackQueue = false;
                }
                attackQueue.Remove(sweetPlan);
            }
            sweetPlan.Target.AttackMovesAllowed = false;
            return movemade;
        }
    protected override void CreateAttackPlanForOwnedPlanet(AttackPlan attack, Route attackRoute, PlanetaryTravelRoute planetTravelMap, ref bool continueRoute)
    {
        Planet hostile     = attack.Target;
        Planet onwedPlanet = attack.Source;

        if (!hostile.IsMine)
        {
            //No use for planets that do not produce.
            if (hostile.GrowthRate == 0)
            {
                return;
            }

            // If my enemy is attacking this planet, but not doing this strong enough,
            // Do not attack this planet and let my enemies ships crash and burn.
            if (hostile.IsNeutral && hostile.IsUnderAttack && hostile.CanSurviveIncommingAttack && !hostile.IsOnWishList)
            {
                return;
            }
            double isNeutralBias = 0;
            double defenseBias   = 0;
            if (hostile.IsNeutral)
            {
                isNeutralBias = 1;
                defenseBias   = Math.Max(Math.Min(onwedPlanet.AttackForce / (hostile.NumShips + 1.0), 5), 0) / 2;
            }
            else
            {
                defenseBias = (Math.Max((int)Math.Min(onwedPlanet.AttackForce / (attackRoute.GrowthForTravelDistance + 1), 5), 0)) / 2.0;
            }

            //we are dominating, favor enemy.
            if (Universe.IsDominating)
            {
                if (hostile.IsNeutral)
                {
                    isNeutralBias = -2;
                }
                else
                {
                    isNeutralBias = 2;
                }
            }

            double wishListBias = 0;
            if (hostile.IsOnWishList)
            {
                //	wishListBias = 3;
            }


            //Dominate planet?
            double dominatePlanetBias = 0.0;
            if (!hostile.IsNeutral)
            {
                if ((currentUniverse.Me.ShipCountInBase / 3 > attackRoute.GrowthForTravelDistance + hostile.NumShips) &&
                    (attackRoute.RelativePlanetDistance < 0.3))
                {
                    dominatePlanetBias    = 2.72;
                    attack.DominationMove = true;
                }
            }

            double growthBias = attackRoute.RelativeGrowthRate * 2;

            attack.ShipCount = (int)(onwedPlanet.NumShips * 0.6);

            attack.Sweetness =
                //favor closer planets
                attackRoute.RelativePlanetDistance +
                attackRoute.RelativeUniverseDistance +
                //favor stronger growing planets
                growthBias +
                //favor neutrals, they do not grow.
                isNeutralBias +
                wishListBias +
                dominatePlanetBias +
                defenseBias +
                hostile.GrowthRate
            ;

            attack.Enabled = true;
        }
    }
    protected override void CreateAttackPlanForOwnedPlanet(AttackPlan attack, Route attackRoute, PlanetaryTravelRoute planetTravelMap, ref bool continueRoute)
    {
        Planet hostile = attack.Target;
        Planet onwedPlanet = attack.Source;
        if (!hostile.IsMine)
        {
            //No use for planets that do not produce.
            if (hostile.GrowthRate == 0)
            {
                return;
            }

            // If my enemy is attacking this planet, but not doing this strong enough,
            // Do not attack this planet and let my enemies ships crash and burn.
            if (hostile.IsNeutral && hostile.IsUnderAttack && hostile.CanSurviveIncommingAttack && !hostile.IsOnWishList)
            {
                return;
            }
            double isNeutralBias = 0;
            double defenseBias = 0;
            if (hostile.IsNeutral)
            {
                isNeutralBias = 1;
                defenseBias = Math.Max(Math.Min(onwedPlanet.AttackForce / (hostile.NumShips + 1.0), 5), 0) / 2;
            }
            else
            {
                defenseBias = (Math.Max((int)Math.Min(onwedPlanet.AttackForce / (attackRoute.GrowthForTravelDistance + 1), 5), 0)) / 2.0;
            }

            //we are dominating, favor enemy.
            if (Universe.IsDominating)
            {
                if (hostile.IsNeutral)
                {
                    isNeutralBias = -2;
                }
                else
                {
                    isNeutralBias = 2;
                }
            }

            double wishListBias = 0;
            if (hostile.IsOnWishList)
            {
                //	wishListBias = 3;
            }

            //Dominate planet?
            double dominatePlanetBias = 0.0;
            if (!hostile.IsNeutral)
            {
                if ((currentUniverse.Me.ShipCountInBase / 3 > attackRoute.GrowthForTravelDistance + hostile.NumShips)
                    && (attackRoute.RelativePlanetDistance < 0.3))
                {
                    dominatePlanetBias = 2.72;
                    attack.DominationMove = true;
                }
            }

            double growthBias = attackRoute.RelativeGrowthRate * 2;

            attack.ShipCount = (int)(onwedPlanet.NumShips * 0.6);

            attack.Sweetness =
                //favor closer planets
                attackRoute.RelativePlanetDistance +
                attackRoute.RelativeUniverseDistance +
                //favor stronger growing planets
                growthBias +
                //favor neutrals, they do not grow.
                isNeutralBias +
                wishListBias +
                dominatePlanetBias +
                defenseBias +
                hostile.GrowthRate
                ;

            attack.Enabled = true;
        }
    }