private List <long> NextTargetGroup(VehiclesGroup myArmy, World world, Player me)
        {
            var enemyVehicles = VehicleRegistry.EnemyVehicles(me);

            if (!enemyVehicles.Any())
            {
                return(Enumerable
                       .Empty <long>()
                       .ToList());
            }
            if (world.TickIndex - lastClusteringTick > CacheTtl)
            {
                var nextEnemyGroup = NextEnemyGroup(myArmy.Center, enemyVehicles, world.TickIndex)?.ToList();
                cachedTargetGroup = nextEnemyGroup?
                                    .Select(v => v.Id)
                                    .ToList()
                                    ?? new List <long>
                {
                    enemyVehicles
                    .OrderBy(v => v.GetDistanceTo(myArmy.Center))
                    .First()
                    .Id
                };
                lastClusteringTick = world.TickIndex;
                return(cachedTargetGroup);
            }
            return(cachedTargetGroup);
        }
Example #2
0
        private Point2D NextTarget(VehiclesGroup myArmy, World world, Player me, Game game)
        {
            var enemyVehicles = VehicleRegistry.EnemyVehicles(me);

            if (world.TickIndex - lastClusteringTick <= CacheTtl)
            {
                return(cachedTarget);
            }
            var closestUncapturedFacility = VehicleRegistry.GetUncapturedFacilities(world, me, Id)
                                            .OrderBy(f => myArmy.Center.GetDistanceTo(f.ToPoint(game)))
                                            .FirstOrDefault();

            if (closestUncapturedFacility != null)
            {
                VehicleRegistry.SetCaptureTarget(closestUncapturedFacility.Id, Id);
                cachedTarget = closestUncapturedFacility.ToPoint(game);
                return(cachedTarget);
            }

            var nextEnemyGroup = NextEnemyGroup(myArmy.Center, enemyVehicles, world.TickIndex)?.ToList();

            if (nextEnemyGroup != null)
            {
                cachedTargetGroup  = nextEnemyGroup.Select(v => v.Id).ToList();
                cachedTarget       = nextEnemyGroup.GetCenterPoint();
                lastClusteringTick = world.TickIndex;
                return(cachedTarget);
            }

            return(new Point2D(world.Height, world.Width));
        }
        public override VehicleFormationResult PerformAction(World world, Player me, Game game)
        {
            var army = new VehiclesGroup(Id, VehicleIds, VehicleRegistry, CommandManager);

            if (!binded)
            {
                Bind(army);
                return(new VehicleFormationResult(this));
            }

            commands.RemoveAll(c => c.IsStarted() && c.IsFinished(world.TickIndex, VehicleRegistry));


            if (FormationHelper.IsNukeAlert(world.GetOpponentPlayer()) && world.TickIndex - nukePreventionTick > game.BaseTacticalNuclearStrikeCooldown / 2)
            {
                commands.Clear();
                CommandManager.ClearCommandsQueue(Id);
                this.PreventNuke(army, world, game, commands);
                nukePreventionTick = world.TickIndex;
                return(new VehicleFormationResult(this));
            }

            if (commands.Any())
            {
                return(new VehicleFormationResult(this));
            }

            var closestUncapturedFacility = VehicleRegistry.GetUncapturedFacilities(world, me, Id)
                                            .Where(f => f.Type == FacilityType.VehicleFactory)
                                            .OrderBy(f => army.Center.GetDistanceTo(f.ToPoint(game)))
                                            .FirstOrDefault();
            var myGroudForcesCenter = VehicleRegistry.GetVehiclesByIds(
                VehicleRegistry.GetVehicleIdsByFormationId(MagicConstants.GroundFormationGroupId))
                                      .ToList()
                                      .GetCenterPoint();
            var enemyVehicles = VehicleRegistry.EnemyVehicles(me);

            var enemies      = Dbscan.GetEnemiesClusters(enemyVehicles, DbscanRadius, DbscanMinimumClusterSize, world.TickIndex);
            var nearestEnemy = enemies.OrderBy(c => c.GetCenterPoint().GetDistanceTo(army.Center)).FirstOrDefault();

            if (nearestEnemy != null &&
                this.TryNuke(army, VehicleRegistry.GetVehiclesByIds(army.VehicleIds), nearestEnemy, me, game, world, commands))
            {
                return(new VehicleFormationResult(new ShrinkAirVehicleFormation(Id, VehicleIds, CommandManager, VehicleRegistry)));
            }

            if (nearestEnemy != null &&
                army.Center.GetDistanceTo(nearestEnemy.GetCenterPoint()) < game.TankVisionRange * 0.8 &&
                nearestEnemy.Count > 1.2 * VehicleIds.Count)
            {
                army
                .Select(Id)
                .MoveByVector(nearestEnemy.GetCenterPoint().To(army.Center), game.TankSpeed);
                commands.Add(CommandManager.PeekLastCommand(Id));
                return(new VehicleFormationResult(this));
            }
            var nextTarget = closestUncapturedFacility?.ToPoint(game) ?? myGroudForcesCenter;

            if (army.Center.GetDistanceTo(myGroudForcesCenter) < MagicConstants.NewVehiclesJoinRadius)
            {
                army
                .Select(Id)
                .Assign(MagicConstants.GroundFormationGroupId);
                return(new VehicleFormationResult());
            }
            var direction = army.Center.To(nextTarget);

            army
            .Select(Id)
            .MoveByVector(direction.Length() > 20
                                                ? direction.Mul(0.1)
                                                : direction,
                          game.TankSpeed);
#if DEBUG
            RewindClient.Instance.Line(army.Center.X, army.Center.Y, nextTarget.X, nextTarget.Y, Color.Fuchsia);
#endif
            commands.Add(CommandManager.PeekLastCommand(Id));
            return(new VehicleFormationResult(this));
        }