private static string GoToNearestZone(int droneIndex)
        {
            var drone = GameOfDronesManager.Player.PlayerDrones[droneIndex];
            var zones = GameOfDronesManager.Zones
                        .Where(zone => zone.OwnerId != GameOfDronesManager.PlayerId)
                        .Select(zone => new
            {
                zone.Center.X,
                zone.Center.Y,
                zone.OwnerId,
                DistanceToCurrentDrone =
                    Trigonometry.GetDistance(
                        new Point(zone.Center.X, zone.Center.Y),
                        new Point(drone.Location.X, drone.Location.Y))
            });
            var nearestZone = zones
                              .OrderBy(zone => zone.DistanceToCurrentDrone)
                              .FirstOrDefault();

            if (nearestZone == null)
            {
                return($"{drone.Location.X} {drone.Location.Y}");
            }
            return($"{nearestZone.X} {nearestZone.Y}");
        }
        public static void Act(int droneIndex)
        {
            var opponentDrones = OpponentDrone.GetOpponentDrones();

            var unoccupiedZones = GameOfDronesManager.Zones.Where(zone => zone.OwnerId == -1);
            var heldZones       = GameOfDronesManager.Zones.Where(zone => zone.OwnerId == GameOfDronesManager.PlayerId)
                                  .Select(zone => new
            {
                zone,
                OpponentCount = GameOfDronesManager.Participants
                                .Select(participant => participant.Drones
                                        .Count(drone =>
                                               Trigonometry.GetDistance(
                                                   new Point(drone.Location.X, drone.Location.Y),
                                                   new Point(zone.Center.X, zone.Center.Y))
                                               <= GameOfDronesManager.ZoneRadius))
                                .OrderByDescending(count => count)
                                .First()
            });

            // Find empty zones and send as many as is feasible (while keeping all currently held zones occupied).
            var untargetedZones = GameOfDronesManager.Zones.ToList();

            foreach (var targetZone in opponentDrones.Select(drone => drone.TargetZone))
            {
                untargetedZones.RemoveAll(zone => zone.Id == targetZone.Id);
            }

            // Assign player drones to target nearest unassigned zone.
            Actions.Commit(GoToNearestAvailableZone(droneIndex, untargetedZones));
        }
        private static string GoToNearestAvailableZone(
            int droneIndex,
            IEnumerable <Zone> availableZones)
        {
            var drone             = GameOfDronesManager.Player.PlayerDrones[droneIndex];
            var zonesWithDistance = availableZones
                                    .Where(zone => zone.OwnerId != GameOfDronesManager.PlayerId)
                                    .Select(zone => new
            {
                zone.Center.X,
                zone.Center.Y,
                zone.OwnerId,
                DistanceToCurrentDrone =
                    Trigonometry.GetDistance(
                        new Point(zone.Center.X, zone.Center.Y),
                        new Point(drone.Location.X, drone.Location.Y))
            });
            var nearestZone = zonesWithDistance.OrderBy(zone => zone.DistanceToCurrentDrone).FirstOrDefault();

            if (nearestZone == null)
            {
                return(GoToNearestZone(droneIndex));
            }
            drone.Target = $"{nearestZone.X} {nearestZone.Y}";
            return(drone.Target);
        }
Beispiel #4
0
 public IEnumerable <Drone> GetOccupyingDrones()
 {
     return(GameOfDronesManager.Participants
            .SelectMany(participant => participant.Drones
                        .Where(drone =>
                               Trigonometry.GetDistance(
                                   new Point(drone.Location.X, drone.Location.Y),
                                   new Point(Center.X, Center.Y)) <
                               GameOfDronesManager.ZoneRadius)));
 }
        public Distance GetDistanceFromFlatSurface(Lander lander)
        {
            if (_landingZone == null)
            {
                SetLandingZone();
            }
            var side = Side.Above;

            if (lander.Situation.X < _landingZone.LeftX)
            {
                side = Side.Left;
            }
            if (lander.Situation.X > _landingZone.RightX)
            {
                side = Side.Right;
            }
            var horizontalDistance = 0.0;
            var fullDistance       = 0.0;

            if (side == Side.Left)
            {
                horizontalDistance = _landingZone.LeftX - lander.Situation.X;
                fullDistance       = Trigonometry.GetDistance(
                    new Point(_landingZone.LeftX, _landingZone.LeftY),
                    new Point(lander.Situation.X, lander.Situation.Y));
            }

            if (side == Side.Right)
            {
                horizontalDistance = _landingZone.RightX - lander.Situation.X;
                fullDistance       = Trigonometry.GetDistance(
                    new Point(_landingZone.RightX, _landingZone.RightY),
                    new Point(lander.Situation.X, lander.Situation.Y));
            }

            if (side == Side.Above)
            {
                fullDistance = Trigonometry.GetDistance(
                    new Point(lander.Situation.X,  // We are above, so we do not need to move to the left or right.
                              _landingZone.LeftY), // Y is the same everywhere in the landing zone.
                    new Point(lander.Situation.X,
                              lander.Situation.Y));
            }

            return(new Distance
            {
                HorizontalDistance = horizontalDistance,
                VerticalDistance =
                    lander.Situation.Y - _landingZone.LeftY, // Y is the same everywhere in the landing zone.
                FullDistance = fullDistance
            });
        }
 public Distance GetDistanceFromFlatSurfaceCenter(Lander lander)
 {
     if (_landingZone == null)
     {
         SetLandingZone();
     }
     return(new Distance
     {
         HorizontalDistance = Math.Abs(lander.Situation.X - _centerLandingZoneX),
         VerticalDistance = Math.Abs(lander.Situation.Y - _landingZone.LeftY),
         FullDistance =
             Trigonometry.GetDistance(
                 new Point(_centerLandingZoneX, _landingZone.LeftY),
                 new Point(lander.Situation.X, lander.Situation.Y))
     });
 }
Beispiel #7
0
 public static IEnumerable <OpponentDrone> GetOpponentDrones()
 {
     return(GameOfDronesManager.Participants
            .Where(participant => !participant.IsPlayer)
            .Select(participant => new
     {
         Drones = participant.Drones.Select(drone =>
         {
             var targetZone = TargetZoneGuesser.Guess(drone);
             return new OpponentDrone(drone.Id)
             {
                 TargetZone = targetZone,
                 TargetDistance = Trigonometry.GetDistance(
                     new Point(drone.Location.X, drone.Location.Y),
                     new Point(targetZone.Center.X, targetZone.Center.Y)),
                 OpponentId = participant.Id
             };
         })
     })
            .SelectMany(drone => drone.Drones));
 }
Beispiel #8
0
        /// <summary>Returns the node that need to be followed in order to reach the destination. Currently only works
        /// on a Grid, without costs associated with the movements.</summary>
        // This method is actually faster than the one above, even though it should not be. Might have to looks at some
        // of the algorithm to improve performance.
        public List <GridNodeAStar> GetAStarNodesWithList(string originId, string targetId)
        {
            var origin = GetNode(originId);
            var target = GetNode(targetId);

            var openSet   = new List <GridNodeAStar>();
            var closedSet = new HashSet <GridNodeAStar>();

            var aStarOrigin = new GridNodeAStar(origin, origin, target);

            openSet.Add(aStarOrigin);

            while (openSet.Any())
            {
                var currentNode = openSet[0];
                for (var i = 1; i < openSet.Count; i++)
                {
                    if (openSet[i].FCost < currentNode.FCost || openSet[i].FCost == currentNode.FCost && openSet[i].HCost < currentNode.HCost)
                    {
                        currentNode = openSet[i];
                    }
                }

                openSet.Remove(currentNode);
                closedSet.Add(currentNode);

                if (currentNode.Id == target.Id)
                {
                    // Found the target node. Retracing steps.
                    var path         = new List <GridNodeAStar>();
                    var pathPosition = currentNode;
                    while (pathPosition.Id != origin.Id)
                    {
                        path.Add(pathPosition);
                        pathPosition = pathPosition.Parent;
                    }

                    path.Reverse();
                    return(path);
                }

                foreach (var neighbour in GetNeighbours(currentNode).Select(node => new GridNodeAStar(node, origin, target)))
                {
                    if (closedSet.FirstOrDefault(node => node.Id == neighbour.Id) != null)
                    {
                        continue;
                    }

                    var newMovementCostToNeighbour = currentNode.GCost + Trigonometry.GetGridDistance(
                        new Point(currentNode.X, currentNode.Y),
                        new Point(neighbour.X, neighbour.Y));

                    var neighbourInOpenSet = openSet.FirstOrDefault(node => node.Id == neighbour.Id);
                    if (neighbourInOpenSet == null)
                    {
                        // Neighbour has not been analyzed yet, so we are generating the costs and adding to open set.
                        neighbour.GCost = newMovementCostToNeighbour;
                        neighbour.HCost = Trigonometry.GetGridDistance(
                            new Point(neighbour.X, neighbour.Y),
                            new Point(target.X, target.Y));
                        neighbour.Parent = currentNode;
                        openSet.Add(neighbour);
                    }
                    if (neighbourInOpenSet != null && newMovementCostToNeighbour > neighbourInOpenSet.GCost)
                    {
                        // Neighbour already exists in open set, but the new movement cost is cheaper, so we're updating it.
                        neighbourInOpenSet.GCost = newMovementCostToNeighbour;
                        neighbourInOpenSet.HCost = Trigonometry.GetDistance(
                            new Point(neighbourInOpenSet.X, neighbourInOpenSet.Y),
                            new Point(target.X, target.Y));
                        neighbourInOpenSet.Parent = currentNode;
                    }
                }
            }

            return(new List <GridNodeAStar>());
        }