public SquadLogic DefenseLogic()
        {
            Mothership MS = Bot.Engine.EnemyMotherships[0];
            int        SCORE_EXTREME_DANGER_TIME   = 7;
            int        SCORE_DANGER_TIME           = 12;
            int        EXTREME_DANGER_DETAIL_COUNT = 2;

            Delegates.FilterFunction <Pirate>  EnemyHasPush          = x => Bot.Engine.GetEnemyPiratesInRange(x.GetLocation(), Bot.Engine.PushRange).Count > 1;
            Delegates.DefenseFunction <Pirate> ExtremeDangerFunction = p =>
            {
                bool CapsuleInGame = Bot.Engine.EnemyLivingCapsules.Any(y => y.IsHeld());
                return(new DefenseStats((p.HasCapsule() || !CapsuleInGame) && ((PirateShip)p).TurnsToReach(MS) <= SCORE_EXTREME_DANGER_TIME ? p.Distance(MS) : 0,
                                        p.NumPushesForCapsuleLoss));
            };
            Delegates.DefenseFunction <Pirate> DangerFunction = p =>
            {
                bool CapsuleInGame = Bot.Engine.EnemyLivingCapsules.Any(y => y.IsHeld());
                return(new DefenseStats((p.HasCapsule() || !CapsuleInGame) && EnemyHasPush(p) && (p.Distance(MS) - (EnemyHasPush(p) ? p.PushDistance : 0)) / p.MaxSpeed <= SCORE_DANGER_TIME ? p.Distance(MS) : 0,
                                        p.NumPushesForCapsuleLoss));
            };
            BasicDefenseSquad <Pirate> DefensePlugin = new BasicDefenseSquad <Pirate>(MS.Location,
                                                                                      EXTREME_DANGER_DETAIL_COUNT, () => Bot.Engine.EnemyLivingPirates.Select(x => (Pirate)x).ToArray(), ExtremeDangerFunction, DangerFunction);
            SquadLogic logic = new SquadLogic(DefensePlugin);

            return(logic);
        }
 /// <summary>
 /// Constructs a defense squad
 /// </summary>
 /// <param name="Camp">Camping location</param>
 /// <param name="ExtremeDangerDetailCount">Size of extreme danger minimal detail</param>
 /// <param name="PossibleDangers">A function to return possible dangers</param>
 /// <param name="ExtremeDangerFunction">A function that determines wether a danger is considered extreme</param>
 /// <param name="DangerFunction">A function that determines wether a possible danger poses a threat</param>
 public BasicDefenseSquad(Location Camp, int ExtremeDangerDetailCount, System.Func <T[]> PossibleDangers, Delegates.DefenseFunction <T> ExtremeDangerFunction, Delegates.DefenseFunction <T> DangerFunction)
 {
     this.Camp = Camp;
     this.ExtremeDangerDetailCount = ExtremeDangerDetailCount;
     this.PossibleDangers          = PossibleDangers;
     this.ExtremeDangerFunction    = ExtremeDangerFunction;
     this.DangerFunction           = DangerFunction;
     this.PushMapper = (x, y) => Bot.Engine.DefaultPush(x, y);
 }
示例#3
0
        public override SquadLogic DefenseLogic(Mothership MS)
        {
            #region Scoring Functions
            Delegates.FilterFunction <MapObject>    EnemyHasPush          = x => Bot.Engine.GetEnemyPiratesInRange(x.GetLocation(), Bot.Engine.PushRange).Count > 1;
            Delegates.DefenseFunction <SpaceObject> ExtremeDangerFunction = x =>
            {
                bool CapsuleInGame = Bot.Engine.EnemyLivingCapsules.Any(y => y.IsHeld());
                if (x is Pirate p)
                {
                    return(new DefenseStats((p.HasCapsule() || !CapsuleInGame) && ((PirateShip)p).TurnsToReach(MS) <= SCORE_EXTREME_DANGER_TIME ? p.Distance(MS) : 0, PirateDeployer((PirateShip)p)));
                }
                else if (x is Wormhole w)
                {
                    return(new DefenseStats(w.Distance(MS) / Bot.Engine.MaxPirateSpeed <= SCORE_EXTREME_DANGER_TIME ? w.Distance(MS) + Bot.Engine.MaxPirateSpeed * SCORE_EXTREME_DANGER_TIME : 0, WormholeDeployer(w)));
                }
                else
                {
                    return(new DefenseStats(0, 0));
                }
            };
            Delegates.DefenseFunction <SpaceObject> DangerFunction = x =>
            {
                bool CapsuleInGame = Bot.Engine.EnemyLivingCapsules.Any(y => y.IsHeld());
                if (x is Pirate p)
                {
                    return(new DefenseStats((p.HasCapsule() || !CapsuleInGame) && EnemyHasPush(p) && (p.Distance(MS) - (EnemyHasPush(p) ? p.PushDistance : 0)) / p.MaxSpeed <= SCORE_DANGER_TIME ? p.Distance(MS) : 0, PirateDeployer((PirateShip)p)));
                }
                else if (x is Wormhole w)
                {
                    return(new DefenseStats(w.Distance(MS) / Bot.Engine.MaxPirateSpeed <= SCORE_DANGER_TIME ? w.Distance(MS) + Bot.Engine.MaxPirateSpeed * SCORE_DANGER_TIME : 0, WormholeDeployer(w)));
                }
                else
                {
                    return(new DefenseStats(0, 0));
                }
            };
            #endregion Scoring Functions

            BasicDefenseSquad <SpaceObject> DefensePlugin = new BasicDefenseSquad <SpaceObject>(MS.Location,
                                                                                                EXTREME_DANGER_DETAIL_COUNT, () => Bot.Engine.EnemyLivingPirates.Select(x => (SpaceObject)((Pirate)x)).Concat(Bot.Engine.AllWormholes).ToArray(), ExtremeDangerFunction, DangerFunction,
                                                                                                DefensePushMapper);
            SquadCamperPlugin camper = new SquadCamperPlugin(MS);
            return(new SquadLogic(DefensePlugin, camper));
        }
        private bool HandleDangers(Squad squad, T[] Dangers, Delegates.DefenseFunction <T> Scorer)
        {
            Dangers = Dangers.Where(x => Scorer(x).rank > 0).ToArray();
            SquadPushPlugin Pusher = new SquadPushPlugin(x => Dangers.Any(y => y.UniqueId == x.UniqueId) ? Scorer(x as T).rank : 0, true,
                                                         PushMapper);

            if (!Dangers.IsEmpty() && squad.Count > 0)
            {
                Pusher.DoTurn(squad);
                Squad CurrentSquad = squad;
                foreach (T danger in Dangers.OrderBy(x => Scorer(x).rank))
                {
                    DefenseStats stats      = Scorer(danger);
                    Squad        LocalSquad = CurrentSquad.OrderBy(x => x.Distance(danger)).Take(stats.amount).ToList();
                    LocalSquad.ForEach(x => x.Sail(danger));
                    CurrentSquad = CurrentSquad.FilterOutBySquad(LocalSquad);
                }
                return(true);
            }

            return(false);
        }
        public LogicedPirateSquad[] LogicDefenders(Squad squad)
        {
            #region Distrbution
            if (squad.Count <= 0)
            {
                return(new LogicedPirateSquad[0]);
            }

            int EnemyMotherships = Bot.Engine.EnemyMotherships.Length;
            if (EnemyMotherships <= 0)
            {
                return(new LogicedPirateSquad[0]);
            }
            EnemyMotherships = System.Math.Min(System.Math.Max(1, squad.Count / 2), EnemyMotherships);
            Mothership[] Motherships = Bot.Engine.EnemyMotherships.OrderBy(x => x.Distance(Bot.Engine.EnemyCapsules.Select(y => y.InitialLocation).Nearest(x))).ToArray();

            int BaseSize  = squad.Count / EnemyMotherships;
            int Remainder = System.Math.Max((squad.Count - BaseSize * EnemyMotherships) % EnemyMotherships, 0);
            #endregion Distrbution

            LogicedPirateSquad[] Squads = new LogicedPirateSquad[0];
            for (int idx = 0; idx < EnemyMotherships; idx++)
            {
                Squad CurrentSquad = new Squad(squad.Skip(BaseSize * idx + System.Math.Min(idx, Remainder)).Take(BaseSize + (idx < Remainder ? 1 : 0)));
                if (CurrentSquad.Count <= 0)
                {
                    continue;
                }

                Mothership MS = Bot.Engine.EnemyMotherships[idx];

                #region Scoring Functions
                Delegates.FilterFunction <MapObject>    EnemyHasPush          = x => Bot.Engine.GetEnemyPiratesInRange(x.GetLocation(), Bot.Engine.PushRange).Count > 1;
                Delegates.DefenseFunction <SpaceObject> ExtremeDangerFunction = x =>
                {
                    bool CapsuleInGame = Bot.Engine.EnemyLivingCapsules.Any(y => y.IsHeld());
                    if (x is Pirate p)
                    {
                        return(new DefenseStats((p.HasCapsule() || !CapsuleInGame) && ((PirateShip)p).TurnsToReach(MS) <= SCORE_EXTREME_DANGER_TIME ? p.Distance(MS) : 0, PirateDeployer((PirateShip)p)));
                    }
                    else if (x is Wormhole w)
                    {
                        return(new DefenseStats(w.Distance(MS) / Bot.Engine.MaxPirateSpeed <= SCORE_EXTREME_DANGER_TIME ? w.Distance(MS) + Bot.Engine.MaxPirateSpeed * SCORE_EXTREME_DANGER_TIME : 0, WormholeDeployer(w)));
                    }
                    else
                    {
                        return(new DefenseStats(0, 0));
                    }
                };
                Delegates.DefenseFunction <SpaceObject> DangerFunction = x =>
                {
                    bool CapsuleInGame = Bot.Engine.EnemyLivingCapsules.Any(y => y.IsHeld());
                    if (x is Pirate p)
                    {
                        return(new DefenseStats((p.HasCapsule() || !CapsuleInGame) && EnemyHasPush(p) && (p.Distance(MS) - (EnemyHasPush(p) ? p.PushDistance : 0)) / p.MaxSpeed <= SCORE_DANGER_TIME ? p.Distance(MS) : 0, PirateDeployer((PirateShip)p)));
                    }
                    else if (x is Wormhole w)
                    {
                        return(new DefenseStats(w.Distance(MS) / Bot.Engine.MaxPirateSpeed <= SCORE_DANGER_TIME ? w.Distance(MS) + Bot.Engine.MaxPirateSpeed * SCORE_DANGER_TIME : 0, WormholeDeployer(w)));
                    }
                    else
                    {
                        return(new DefenseStats(0, 0));
                    }
                };
                #endregion Scoring Functions

                SquadPlugin DefensePlugin = new BasicDefenseSquad <SpaceObject>(MS.Location,
                                                                                EXTREME_DANGER_DETAIL_COUNT, () => Bot.Engine.EnemyLivingPirates.Select(x => (SpaceObject)((Pirate)x)).Concat(Bot.Engine.AllWormholes).ToArray(), ExtremeDangerFunction, DangerFunction,
                                                                                DefensePushMapper);
                LogicedPirateSquad LogicedCurrentSquad = new LogicedPirateSquad(CurrentSquad.Select(x => x.LogicPirate(DefenseBaseLogic)).ToArray(), new SquadLogic(DefensePlugin, new SquadCamperPlugin(MS)));

                Squads = Squads.Concat(new LogicedPirateSquad[] { LogicedCurrentSquad }).ToArray();
            }

            return(Squads);
        }
 /// <summary>
 /// Constructs a defense squad
 /// </summary>
 /// <param name="Camp">Camping location</param>
 /// <param name="ExtremeDangerDetailCount">Size of extreme danger minimal detail</param>
 /// <param name="PossibleDangers">A function to return possible dangers</param>
 /// <param name="ExtremeDangerFunction">A function that determines wether a danger is considered extreme</param>
 /// <param name="DangerFunction">A function that determines wether a possible danger poses a threat</param>
 /// <param name="PushMapper">A custom pushing function</param>
 public BasicDefenseSquad(Location Camp, int ExtremeDangerDetailCount, System.Func <T[]> PossibleDangers, Delegates.DefenseFunction <T> ExtremeDangerFunction, Delegates.DefenseFunction <T> DangerFunction, Delegates.PushMapper PushMapper)
     : this(Camp, ExtremeDangerDetailCount, PossibleDangers, ExtremeDangerFunction, DangerFunction)
 {
     this.PushMapper = PushMapper;
 }