Beispiel #1
0
        public void Add(ActionSequence sequence)
        {
            var moveActions = sequence.Where(a => a.ActionType == ActionType.Move && a.Formation != null).ToList();

            if (moveActions.Count > 0)
            {
                var action = moveActions.First();
                if (action.IsAnticollision)
                {
                    if (_internalQueue.Any(s => s.Any(a => a.IsAnticollision &&
                                                      a.Formation == action.Formation &&
                                                      (a.Status == ActionStatus.Pending ||
                                                       a.Status == ActionStatus.Executing))))
                    {
                        return;
                    }
                }
                AbortOldActionsFor(action.Formation);
            }
            _internalQueue.Add(sequence);

            foreach (var action in sequence)
            {
                action.Status = ActionStatus.Pending;
            }
        }
Beispiel #2
0
        public static void InsertToExecutingSequence(MyFormation formation, params Action[] action)
        {
            if (formation != null && formation.Alive && action.Length > 0)
            {
                var executingAction = formation.ExecutingSequence?.GetExecutingAction();

                if (executingAction != null &&
                    executingAction.ActionType == ActionType.Move &&
                    executingAction.Interruptable)
                {
                    action.First().StartCondition = () => true;
                    formation.ExecutingSequence.AddRange(action);

                    var continueAction = executingAction.Clone();
                    continueAction.StartCondition = () =>
                                                    action.Last().Status == ActionStatus.Finished ||
                                                    action.Last().Status == ActionStatus.Aborted;
                    formation.ExecutingSequence.Add(continueAction);
                    executingAction.Abort();
                }
                if (executingAction == null)
                {
                    var newSequence = new ActionSequence(action);
                    Global.ActionQueue.Add(newSequence);
                }
            }
        }
Beispiel #3
0
        public static void SplitFormation(MyFormation formation, int runFromCenter = 0)
        {
            var child = FormationFactory.CreateMyFormation(
                () => formation.Rect.Left,
                () => formation.Rect.Top,
                () => formation.MassCenter.X,
                () => formation.MassCenter.Y);

            formation.Children.Add(child.Formation);
            var sequence = new ActionSequence(child.ActionList.ToArray());

            if (runFromCenter > 0)
            {
                sequence.Add(child.Formation.ShiftTo(-runFromCenter, -runFromCenter));
            }

            child = FormationFactory.CreateMyFormation(
                () => formation.MassCenter.X,
                () => formation.Rect.Top,
                () => formation.Rect.Right,
                () => formation.MassCenter.Y);
            sequence.AddRange(child.ActionList);
            formation.Children.Add(child.Formation);
            if (runFromCenter > 0)
            {
                sequence.Add(child.Formation.ShiftTo(runFromCenter, -runFromCenter));
            }

            child = FormationFactory.CreateMyFormation(
                () => formation.Rect.Left,
                () => formation.MassCenter.Y,
                () => formation.MassCenter.X,
                () => formation.Rect.Bottom);
            sequence.AddRange(child.ActionList);
            formation.Children.Add(child.Formation);
            if (runFromCenter > 0)
            {
                sequence.Add(child.Formation.ShiftTo(-runFromCenter, runFromCenter));
            }
            child = FormationFactory.CreateMyFormation(
                () => formation.MassCenter.X,
                () => formation.MassCenter.Y,
                () => formation.Rect.Right,
                () => formation.Rect.Bottom);
            sequence.AddRange(child.ActionList);
            formation.Children.Add(child.Formation);
            if (runFromCenter > 0)
            {
                sequence.Add(child.Formation.ShiftTo(runFromCenter, runFromCenter));
            }
            Global.ActionQueue.Add(sequence);
        }
Beispiel #4
0
 public static void SetupProductionIfNeed(Facility facility, VehicleType neededType)
 {
     if (facility.Type == FacilityType.VehicleFactory && facility.VehicleType != neededType)
     {
         if (!Global.ActionQueue.HasActionsFor(facility))
         {
             if (Global.MyVehicles.Values.All(v => v.Groups.Length == 0 || !v.IsInside(facility.Rect)))
             {
                 var sequence = new ActionSequence(facility.SetupProduction(neededType));
                 Global.ActionQueue.Add(sequence);
             }
         }
     }
 }
Beispiel #5
0
 public static void FinalSpread()
 {
     if (Global.World.TickIndex > 10000 &&
         Global.World.TickIndex % 1000 == 0 &&
         Global.MyVehicles.Count > 10 * Global.EnemyVehicles.Count &&
         Global.World.GetMyPlayer().Score < Global.World.GetOpponentPlayer().Score)
     {
         Global.ActionQueue.Clear();
         foreach (var formation in Global.MyFormations.Values)
         {
             var scale1   = formation.ScaleCenter(10);
             var scale2   = formation.ScaleCenter(0.1);
             var sequence = new ActionSequence(scale1, scale2);
             Global.ActionQueue.Add(sequence);
         }
     }
 }
Beispiel #6
0
        public static bool OccupyFacilities(MyFormation formation)
        {
            if (formation.Alive && !formation.Busy && formation.AeralPercent < 0.1)
            {
                var freeFacility = Global.World.Facilities
                                   .OrderBy(f => f.Center.SqrDistance(formation.Center))
                                   .FirstOrDefault(f => !f.IsMine && !f.SelectedAsTargetForGroup.HasValue);

                if (freeFacility != null)
                {
                    freeFacility.SelectedAsTargetForGroup = formation.GroupIndex;

                    var actionMove = formation.MoveCenterTo(freeFacility.Center);
                    var sequence   = new ActionSequence(actionMove);
                    Global.ActionQueue.Add(sequence);
                    return(true);
                }
            }
            return(false);
        }
Beispiel #7
0
        public static void AbortAndAddToExecutingSequence(MyFormation formation, params Action[] action)
        {
            if (formation != null && formation.Alive && action.Length > 0)
            {
                var executingAction = formation.ExecutingSequence?.GetExecutingAction();

                if (executingAction != null &&
                    executingAction.ActionType == ActionType.Move &&
                    executingAction.Interruptable)
                {
                    action.First().StartCondition = () => true;
                    formation.ExecutingSequence.AddRange(action);
                    executingAction.Abort();
                }
                if (executingAction == null)
                {
                    var newSequence = new ActionSequence(action);
                    Global.ActionQueue.Add(newSequence);
                }
            }
        }
Beispiel #8
0
        private void Execute(ActionSequence sequence, Action action, Move move)
        {
            if (action == null)
            {
                return;
            }


            move.Action          = action.ActionType;
            move.X               = action.GetX();
            move.Y               = action.GetY();
            move.Group           = action.Group;
            move.Angle           = action.Angle;
            move.Left            = action.GetLeft();
            move.Top             = action.GetTop();
            move.Right           = action.GetRight();
            move.Bottom          = action.GetBottom();
            move.VehicleType     = action.VehicleType;
            move.MaxSpeed        = action.MaxSpeed;
            move.MaxAngularSpeed = action.MaxAngularSpeed;
            move.Factor          = action.Factor;
            move.FacilityId      = action.FacilityId;
            move.VehicleId       = action.VehicleId;

            if (action.Formation != null)
            {
                action.Formation.ExecutingAction   = action;
                action.Formation.ExecutingSequence = sequence;
                if (action.ActionType == ActionType.ClearAndSelect)
                {
                    Global.SelectedFormation = action.Formation;
                }
            }
            action.ExecutingMove = move;


            action.Status = ActionStatus.Executing;
            action.Callback?.Invoke();
            Console.WriteLine($"Action:{action}");
        }
Beispiel #9
0
        public void Add(ActionSequence sequence)
        {
            var moveActions = sequence.Where(a => a.ActionType == ActionType.Move && a.Formation != null).ToList();

            if (moveActions.Count > 0)
            {
                var action = moveActions.First();
                if (action.IsAnticollision)
                {
                    if (_internalQueue.Any(s => s.Any(a => a.IsAnticollision &&
                                                      a.Formation == action.Formation &&
                                                      (a.Status == ActionStatus.Pending ||
                                                       a.Status == ActionStatus.Executing))))
                    {
                        return;
                    }
                }
                foreach (var seq in _internalQueue)
                {
                    foreach (var act in seq)
                    {
                        if (act.Formation == action.Formation &&
                            act.Interruptable &&
                            (act.Status == ActionStatus.Pending || act.Status == ActionStatus.Executing) &&
                            (act.ActionType == ActionType.Move || act.ActionType == ActionType.Scale ||
                             act.ActionType == ActionType.Rotate)
                            )
                        {
                            act.Abort();
                        }
                    }
                }
            }
            _internalQueue.Add(sequence);

            foreach (var action in sequence)
            {
                action.Status = ActionStatus.Pending;
            }
        }
Beispiel #10
0
        public static bool OccupyFacilities(MyFormation formation, bool breakCurrentAction)
        {
            if (formation.Alive &&
                (!formation.Busy || breakCurrentAction) &&
                formation.AeralPercent < 0.1)
            {
                var targetFacility = formation.FacilityAsTarget == null
                    ? null
                    : Global.World.Facilities.FirstOrDefault(f => f.Id == formation.FacilityAsTarget.Value);

                Facility freeFacility = null;
                if (targetFacility != null && !targetFacility.IsMine)
                {
                    freeFacility = targetFacility;
                }
                else
                {
                    var planningToOccupy = Global.MyFormations.Values
                                           .Where(f => f.FacilityAsTarget.HasValue)
                                           .Select(f => f.FacilityAsTarget.Value).ToList();

                    freeFacility = Global.NotMyFacilities
                                   .Where(f => !f.IsMine && !planningToOccupy.Contains(f.Id))
                                   .OrderBy(f => f.Center.SqrDistance(formation.Center)).FirstOrDefault();
                }
                if (freeFacility != null)
                {
                    formation.FacilityAsTarget = freeFacility.Id;

                    var actionMove = formation.MoveCenterTo(freeFacility.Center);
                    var sequence   = new ActionSequence(actionMove);
                    Global.ActionQueue.Add(sequence);
                    return(true);
                }
            }
            return(false);
        }
Beispiel #11
0
 public void Add(ActionSequence sequence)
 {
     AddRange(sequence);
 }
Beispiel #12
0
        public static MyFormation CreateAirFormation()
        {
            const double eps              = 10D;
            const double deltaShift       = 5.1D;
            const double commonCoordinate = 350D;
            const double nearCoordinate   = 60D;
            const double farCoordinate    = 200D;
            const double factor           = 1.7D;
            const double vehicleSize      = 4D;


            var fighters    = Global.MyFighters;
            var helicopters = Global.MyHelicopters;

            Global.IgnoreCollisionGroupIndexes.Add(fighters.GroupIndex);
            Global.IgnoreCollisionGroupIndexes.Add(helicopters.GroupIndex);

            var isVertical = Math.Abs(fighters.Rect.Left - helicopters.Rect.Left) < eps;

            MyFormation f1;
            MyFormation f2;
            double      f1MoveX;
            double      f1MoveY;
            double      f2MoveX;
            double      f2MoveY;
            double      shiftX;
            double      shiftY;
            double      compactX;
            double      compactY;
            double      angle;

            if (isVertical)
            {
                f1MoveX  = commonCoordinate + deltaShift;
                f1MoveY  = nearCoordinate;
                f2MoveX  = commonCoordinate;
                f2MoveY  = farCoordinate;
                shiftX   = 0;
                shiftY   = (farCoordinate - nearCoordinate) / 2;
                compactX = 0;
                compactY = 3 * vehicleSize;
                angle    = -Math.PI / 4;
            }

            else
            {
                f1MoveX  = nearCoordinate;
                f1MoveY  = commonCoordinate + deltaShift;
                f2MoveX  = farCoordinate;
                f2MoveY  = commonCoordinate;
                shiftX   = (farCoordinate - nearCoordinate) / 2;
                shiftY   = 0;
                compactX = 3 * vehicleSize;
                compactY = 0;
                angle    = Math.PI / 4;
            }
            if (isVertical && fighters.Rect.Top < helicopters.Rect.Top ||
                !isVertical && fighters.Rect.Left < helicopters.Rect.Left)
            {
                f1 = fighters;
                f2 = helicopters;
            }
            else
            {
                f1 = helicopters;
                f2 = fighters;
            }
            // двигаем первую формацию налево или вниз, а потом - масштабируем ее
            var sMove1 = new ActionSequence(
                f1.MoveLeftTopTo(f1MoveX, f1MoveY),
                f1.ScaleLeftTop(factor)
                );

            Global.ActionQueue.Add(sMove1);

            // двигаем вторую формацию налево или вниз, а потом - масштабируем ее
            var sMove2 = new ActionSequence(
                f2.MoveLeftTopTo(f2MoveX, f2MoveY),
                f2.ScaleLeftTop(factor)
                );

            Global.ActionQueue.Add(sMove2);

            // после того, как обе формации отмасштабированы, первая формация движеться наствречу второй
            var aPenetrate1 = f1.ShiftTo(shiftX, shiftY);

            aPenetrate1.StartCondition = () => sMove1.IsFinished && sMove2.IsFinished;
            var sPenetrate1 = new ActionSequence(aPenetrate1);

            Global.ActionQueue.Add(sPenetrate1);

            // а вторая - навстречу первой до полного проникновения
            var aPenetrate2 = f2.ShiftTo(-shiftX, -shiftY);

            aPenetrate2.StartCondition = () => sMove1.IsFinished && sMove2.IsFinished;
            var sPenetrate2 = new ActionSequence(aPenetrate2);

            Global.ActionQueue.Add(sPenetrate2);

            // сплющиваем сбоку бутерброд
            var res = FormationFactory.CreateMyFormation(
                () => Math.Min(f1.Rect.Left, f2.Rect.Left),
                () => Math.Min(f1.Rect.Top, f2.Rect.Top),
                () => Math.Max(f1.Rect.Right, f2.Rect.Right) - compactX,
                () => Math.Max(f1.Rect.Bottom, f2.Rect.Bottom) - compactY);

            Global.IgnoreCollisionGroupIndexes.Add(res.GroupIndex);

            var sShift = new ActionSequence(res.ActionList.ToArray());

            sShift.First().StartCondition = () => sPenetrate2.IsFinished && sPenetrate1.IsFinished;

            sShift.Add(res.Formation.ShiftTo(shiftX, shiftY));
            Global.ActionQueue.Add(sShift);

            //   компактизируем
            res = FormationFactory.CreateMyFormation(
                () => Math.Min(f1.Rect.Left, f2.Rect.Left),
                () => Math.Min(f1.Rect.Top, f2.Rect.Top),
                () => Math.Max(f1.Rect.Right, f2.Rect.Right),
                () => Math.Max(f1.Rect.Bottom, f2.Rect.Bottom));

            var sCompact = new ActionSequence(res.ActionList.ToArray());

            sCompact.First().StartCondition = () => sShift.IsFinished;
            sCompact.Add(res.Formation.ScaleCenter(1.2));
            sCompact.Add(res.Formation.RotateCenter(angle));
            sCompact.Add(res.Formation.ScaleCenter(0.5));
            sCompact.Add(res.Formation.ShiftTo(10, 10));
            Global.ActionQueue.Add(sCompact);

            return(res.Formation);
        }
Beispiel #13
0
        public static void NuclearStrike()
        {
            if (Global.Me.RemainingNuclearStrikeCooldownTicks == 0 &&
                Global.Me.NextNuclearStrikeTickIndex == -1 &&
                Global.World.TickIndex % 30 == 25 &&
                !Global.ActionQueue.HasActionsFor(ActionType.TacticalNuclearStrike))
            {
                VehicleWrapper possibleTarget  = null;
                double         bestDeltaDamage = Math.Min(30 * 100, Global.EnemyVehicles.Values.Sum(i => i.Durability) / 5);

                var sqrNuclearRadius =
                    Global.Game.TacticalNuclearStrikeRadius * Global.Game.TacticalNuclearStrikeRadius;

                const double visionRangeThreshold = 0.7;
                foreach (var enemy in Global.EnemyVehicles.Values)
                {
                    var visors = Global.MyVehicles.Values
                                 .Where(i => i.SqrDistance(enemy) < visionRangeThreshold * i.VisionRange * i.VisionRange)
                                 .ToList();
                    if (visors.Count == 0)
                    {
                        continue;
                    }

                    var allDamaged = Global.AllVehicles.Values
                                     .Where(i => i.SqrDistance(enemy) < sqrNuclearRadius)
                                     .ToList();

                    var enemyDamaged = allDamaged.Where(i => i.PlayerId != Global.Me.Id).ToList();
                    var myDamaged    = allDamaged.Where(i => i.PlayerId == Global.Me.Id).ToList();

                    if (enemyDamaged.Count <= Math.Min(30, Global.EnemyVehicles.Count / 2 - 10))
                    {
                        continue;
                    }

                    var myDamage = myDamaged
                                   .Sum(i => Math.Min(i.Durability,
                                                      Global.Game.MaxTacticalNuclearStrikeDamage *
                                                      (1 - Math.Sqrt(i.SqrDistance(enemy) / sqrNuclearRadius))));
                    var enemyDamage = enemyDamaged
                                      .Sum(i => Math.Min(i.Durability,
                                                         Global.Game.MaxTacticalNuclearStrikeDamage *
                                                         (1 - Math.Sqrt(i.SqrDistance(enemy) / sqrNuclearRadius))));

                    if (enemyDamage - myDamage > bestDeltaDamage)
                    {
                        bestDeltaDamage = enemyDamage - myDamage;
                        possibleTarget  = enemy;
                    }
                }

                if (possibleTarget == null)
                {
                    return;
                }
                var visor = Global.MyVehicles.Values
                            .Where(i => i.SqrDistance(possibleTarget) < visionRangeThreshold * i.VisionRange * i.VisionRange)
                            .OrderBy(i => i.SqrDistance(possibleTarget)).Last();

                var action = visor.TacticalNuclearStrike(possibleTarget);
                action.Interruptable = false;
                var newSequence = new ActionSequence(action);
                Global.ActionQueue.Add(newSequence);
            }
        }
Beispiel #14
0
        public static bool Attack(MyFormation formation)
        {
            if (AirAttack(formation))
            {
                return(true);
            }

            var targetFacility = formation.FacilityAsTarget == null
                ? null
                : Global.World.Facilities.FirstOrDefault(f => f.Id == formation.FacilityAsTarget.Value);

            if (formation.FacilityAsTarget == null)
            {
                OccupyFacilities(formation, true);

                targetFacility = formation.FacilityAsTarget == null
                    ? null
                    : Global.World.Facilities.FirstOrDefault(f => f.Id == formation.FacilityAsTarget.Value);
            }
            if (targetFacility != null)
            {
                if (targetFacility.IsMine)
                {
                    targetFacility             = null;
                    formation.FacilityAsTarget = null;
                }
            }

            double maxAttackDistance = (targetFacility == null)
                ? Global.World.Width / 2
                : Math.Min(100, formation.Center.Distance(targetFacility.Center) / 2);


            var myDurability    = Global.MyVehicles.Values.Sum(v => v.Durability);
            var enemyDurability = Global.EnemyVehicles.Values.Sum(v => v.Durability);

            var betterCoeff   = Math.Max(1, myDurability / (enemyDurability + 1.0));
            var oneShotDanger = new Dictionary <EnemyFormation, double>();

            foreach (var enemy in Global.EnemyFormations)
            {
                var dangerForEnemy = formation.DangerFor(enemy);
                var dangerForMe    = enemy.DangerFor(formation);
                if (enemy.Center.Distance(formation.Center) < maxAttackDistance)
                {
                    oneShotDanger.Add(enemy, (betterCoeff) * dangerForEnemy - dangerForMe);
                }
            }

            EnemyFormation target = null;

            if (oneShotDanger.Count > 0)
            {
                var targetPair = oneShotDanger
                                 .OrderByDescending(kv => kv.Value)
                                 .FirstOrDefault();

                if (targetPair.Value > 0)
                {
                    target = targetPair.Key;
                }
            }

            if (target != null)
            {
                MakeAttackOrder(formation, target, false);
                return(true);
            }

            var runAwayDanger = new Dictionary <EnemyFormation, double>();

            foreach (var enemy in Global.EnemyFormations)
            {
                var dangerForEnemy = formation.DangerFor(enemy);
                var dangerForMe    = enemy.DangerFor(formation);
                if (enemy.Center.Distance(formation.Center) < 150)
                {
                    runAwayDanger.Add(enemy, (dangerForEnemy - dangerForMe) / (formation.Count + 1.0));
                }
            }
            if (runAwayDanger.Count > 0)
            {
                var targetPair = runAwayDanger
                                 .OrderBy(kv => kv.Value)
                                 .FirstOrDefault();
                if (targetPair.Value < -10)
                {
                    var runAwayFromThis = targetPair.Key;
                    var direction       = (formation.MassCenter - runAwayFromThis.MassCenter).Normalized();
                    formation.FacilityAsTarget = null;


                    Global.ActionQueue.AbortOldActionsFor(formation);
                    var actionMove = formation.ShiftTo(direction * 100);
                    actionMove.Priority       = ActionPriority.High;
                    actionMove.StartCondition = () => true;
                    actionMove.Interruptable  = false;
                    var sequence = new ActionSequence(actionMove);
                    Global.ActionQueue.Add(sequence);
                }
            }


            if (targetFacility != null)
            {
                var actionMove = formation.MoveCenterTo(targetFacility.Center);
                var sequence   = new ActionSequence(actionMove);
                Global.ActionQueue.Add(sequence);
            }
            return(false);
        }
Beispiel #15
0
        public static void SetupProductionIfNeed(Facility facility)
        {
            if (facility.Type != FacilityType.VehicleFactory)
            {
                return;
            }

            var myFightersCount = Global.MyFighters.Vehicles.Count;
            var myHelisCount    = Global.MyHelicopters.Vehicles.Count;

            var enemyFightersCount = Global.EnemyFighters.Count();
            var enemyHeliCount     = Global.EnemyHelicopters.Count();

            VehicleType neededType;
            bool        isGroundProducing = (facility.VehicleType == null ||
                                             facility.VehicleType == VehicleType.Tank ||
                                             facility.VehicleType == VehicleType.Ifv ||
                                             facility.VehicleType == VehicleType.Arrv);

//            if (myFightersCount < 0.8 * enemyFightersCount)
//            {
//                neededType = VehicleType.Fighter;
//                if (isGroundProducing)
//                {
//                    CreateProducedFormation();
//                }
//            }
//            else
            if (myHelisCount < 0.8 * enemyHeliCount && enemyFightersCount < 30)
            {
                neededType = VehicleType.Helicopter;
                if (isGroundProducing)
                {
                    CreateProducedFormation();
                }
            }
            else
            {
                if (facility.VehicleType == null ||
                    facility.VehicleType == VehicleType.Fighter ||
                    facility.VehicleType == VehicleType.Helicopter)
                {
                    CreateProducedFormation();
                    facility.InitialTickIndex = 0;
                }
                facility.InitialTickIndex++;
                var tick = (Global.World.TickIndex - facility.InitialTickIndex) % 1200;

                neededType = tick < 1200 - 6 * Math.Min(150, enemyHeliCount)
                    ? VehicleType.Tank
                    : VehicleType.Ifv;
            }

            if (facility.VehicleType != neededType)
            {
                if (!Global.ActionQueue.HasActionsFor(facility))
                {
                    if (Global.MyVehicles.Values.All(v => v.Groups.Length == 0 || !v.IsInside(facility.Rect)))
                    {
                        var sequence = new ActionSequence(facility.SetupProduction(neededType));
                        Global.ActionQueue.Add(sequence);
                    }
                }
            }
        }