static void DrawGrid(SquareGrid field) //Prints the playing field to console. FOR DEBUGGING PURPOSES ONLY; DO NOT USE WHEN TESTING
        {
            field.CopyObstaclesToWalls();
            HashSet <Location> path = field.GetShortestPath();

            for (int y = field.Width; y >= 0; y--)
            {
                for (int x = 0; x <= field.Height; x++)
                {
                    Location here = new Location(x, y);
                    if (here.Equals(field.Start))
                    {
                        Console.Write("S ");
                    }
                    else if (here.Equals(field.Goal))
                    {
                        Console.Write("G ");
                    }
                    else if (Util.ContainsLoc(field.walls, here))
                    {
                        Console.Write("# ");
                    }
                    else if (Util.ContainsLoc(path, here))
                    {
                        Console.Write($"{Util.LocIndex(path, here)} ");
                    }
                    else
                    {
                        Console.Write("* ");
                    }
                }
                Console.WriteLine();
            }
        }
 static void DrawPassable(SquareGrid field) // Prints the playing field to console and highlights which points are passable. See warning above.
 {
     field.CopyObstaclesToWalls();
     for (int y = field.Width; y >= 0; y--)
     {
         for (int x = 0; x <= field.Height; x++)
         {
             Location here = new Location(x, y);
             if (field.Passable(here))
             {
                 Console.Write("$ ");
             }
             else if (Util.ContainsLoc(field.walls, here))
             {
                 Console.Write("# ");
             }
             else
             {
                 Console.Write("* ");
             }
         }
         Console.WriteLine();
     }
 }
Beispiel #3
0
        // Conduct the A* search
        public AStarSearch(SquareGrid graph, Vector3Int start, Vector3Int goal)
        {
            // start is current sprite Vector3Int
            this.start = start;
            // goal is sprite destination eg tile user clicked on
            this.goal = goal;

            // add the cross product of the start to goal and tile to goal vectors
            // Vector3 startToGoalV = Vector3.Cross(start.vector3,goal.vector3);
            // Vector3Int startToGoal = new Vector3Int(startToGoalV);
            // Vector3 neighborToGoalV = Vector3.Cross(neighbor.vector3,goal.vector3);

            // frontier is a List of key-value pairs:
            // Vector3Int, (float) priority
            var frontier = new PriorityQueue <Vector3Int>();

            // Add the starting location to the frontier with a priority of 0
            frontier.Enqueue(start, 0f);

            cameFrom.Add(start, start); // is set to start, None in example
            costSoFar.Add(start, 0f);

            while (frontier.Count > 0f)
            {
                // Get the Vector3Int from the frontier that has the lowest
                // priority, then remove that Vector3Int from the frontier
                Vector3Int current = frontier.Dequeue();

                // If we're at the goal Vector3Int, stop looking.
                if (current.Equals(goal))
                {
                    break;
                }

                // Neighbors will return a List of valid tile Vector3Ints
                // that are next to, diagonal to, above or below current
                foreach (var neighbor in graph.Neighbors(current))
                {
                    // If neighbor is diagonal to current, graph.Cost(current,neighbor)
                    // will return Sqrt(2). Otherwise it will return only the cost of
                    // the neighbor, which depends on its type, as set in the TileType enum.
                    // So if this is a normal floor tile (1) and it's neighbor is an
                    // adjacent (not diagonal) floor tile (1), newCost will be 2,
                    // or if the neighbor is diagonal, 1+Sqrt(2). And that will be the
                    // value assigned to costSoFar[neighbor] below.
                    float newCost = costSoFar[current] + graph.Cost(current, neighbor);

                    // If there's no cost assigned to the neighbor yet, or if the new
                    // cost is lower than the assigned one, add newCost for this neighbor
                    if (!costSoFar.ContainsKey(neighbor) || newCost < costSoFar[neighbor])
                    {
                        // If we're replacing the previous cost, remove it
                        if (costSoFar.ContainsKey(neighbor))
                        {
                            costSoFar.Remove(neighbor);
                            cameFrom.Remove(neighbor);
                        }

                        costSoFar.Add(neighbor, newCost);
                        cameFrom.Add(neighbor, current);
                        float priority = newCost + Heuristic(neighbor, goal);
                        frontier.Enqueue(neighbor, priority);
                    }
                }
            }
        }
        static void Main(string[] args) //I realize there's a lot going on here. Due to time constraints, I can't really clean this up.
        {
            double          californiaLatToMeter = 1.111785102E5;
            double          californiaLonToMeter = 9.226910619E4;
            List <Waypoint> Waypoints            = GrabMission();
            List <Waypoint> Boundaries           = GetBoundaries();

            /*foreach (Waypoint w in Waypoints)
             * {
             *  Console.WriteLine(w);
             * }
             * Console.WriteLine();*/// for debugging
            //DrawPassable(playingField);

            /*Console.WriteLine($"Width: {playingField.Width}; Height: {playingField.Height}");
             * Console.WriteLine($"Start = {playingField.Start}");
             * Console.WriteLine($"Goal = {playingField.Goal}");*/// DO NOT REMOVE OR UNCOMMENT: This part visualizes the grid by printing it out. For use when Length & Width < 30.

            List <ParsedObstacle> ParsedObstacles = ParseObstacles(Waypoints[0].Altitude);
            double             upmost = 0, leftmost = 0, rightmost = 0, downmost = 0;
            SquareGrid         playingField = GenerateField(Waypoints, ParsedObstacles, Boundaries, ref downmost, ref upmost, ref leftmost, ref rightmost);
            HashSet <Location> path = new HashSet <Location>();

            path = playingField.GetShortestPath();
            double count = 0.1;

            foreach (Location p in path)
            {
                if (p != playingField.Goal && p != playingField.Start)
                {
                    double order = playingField.FirstOrder + count;
                    count += 0.1;
                    double latitude  = (p.X + leftmost - 5) / californiaLatToMeter;
                    double longitude = (p.Y + downmost - 5) / californiaLonToMeter;
                    Waypoints.Add(new Waypoint(order, latitude, longitude, (Waypoints[0].Altitude + Waypoints[1].Altitude) / 2));
                }
            }
            Waypoints.Sort();
            for (int i = 2; i <= Waypoints[Waypoints.Count - 1].Order; i++)
            {
                path.Clear();
                int index = Util.GetIndexOfOrder(i, Waypoints);
                //Console.WriteLine(Waypoints[index - 1].Latitude * californiaLatToMeter); // for debugging
                double swrappedlat = (Waypoints[index - 1].Latitude * californiaLatToMeter) - leftmost;
                //Console.WriteLine(Waypoints[index - 1].Longitude * californiaLonToMeter); // for debugging
                double swrappedlon = (Waypoints[index - 1].Longitude * californiaLonToMeter) - downmost;
                playingField.Start = new Location(Convert.ToInt32(swrappedlat) + 5, Convert.ToInt32(swrappedlon) + 5);
                //Console.WriteLine(Waypoints[index].Latitude * californiaLatToMeter); // for debugging
                double gwrappedlat = (Waypoints[index].Latitude * californiaLatToMeter) - leftmost;
                //Console.WriteLine(Waypoints[index].Longitude * californiaLonToMeter); // for debugging
                double gwrappedlon = (Waypoints[index].Longitude * californiaLonToMeter) - downmost;
                playingField.Goal       = new Location(Convert.ToInt32(gwrappedlat) + 5, Convert.ToInt32(gwrappedlon) + 5);
                playingField.FirstOrder = i - 1;
                playingField.Altitude   = Waypoints[i - 1].Altitude;
                path = playingField.GetShortestPath();
                foreach (Location p in path)
                {
                    if (p != playingField.Goal && p != playingField.Start)
                    {
                        double order = playingField.FirstOrder + count;
                        count += 0.1;
                        double latitude  = (p.X + leftmost - 5) / californiaLatToMeter;
                        double longitude = (p.Y + downmost - 5) / californiaLonToMeter;
                        Waypoints.Add(new Waypoint(order, latitude, longitude, (Waypoints[i - 1].Altitude + Waypoints[i].Altitude) / 2));
                    }
                }
            }
            Waypoints.Sort();
            String final  = "";
            int    counts = 1;

            foreach (Waypoint wp in Waypoints)
            {
                final += wp.ToString();
                if (counts != Waypoints.Count)
                {
                    final += ",";
                }
                counts++;
            }
            System.IO.File.WriteAllText(@"C:\Users\Public\Downloads\InteropCode\interop\MissionPointsParsedObstacle.txt", final);
        }
        static SquareGrid GenerateField(List <Waypoint> Waypoints, List <ParsedObstacle> ParsedObstacles, List <Waypoint> Boundaries, ref double downmost, ref double upmost, ref double leftmost, ref double rightmost) //Generates the playing field given all necessary information.
        {
            double californiaLatToMeter = 1.111785102E5;
            double californiaLonToMeter = 9.226910619E4;
            /* To do: Add Maryland conversions */
            double latitudeconversion  = californiaLatToMeter;
            double longitudeconversion = californiaLonToMeter;

            upmost    = Double.MinValue;
            downmost  = Double.MaxValue;
            leftmost  = Double.MaxValue;
            rightmost = Double.MinValue;
            foreach (Waypoint w in Waypoints)
            {
                if (w.Longitude < downmost)
                {
                    downmost = w.Longitude;
                }
                if (w.Latitude < leftmost)
                {
                    leftmost = w.Latitude;
                }
                if (w.Longitude > upmost)
                {
                    upmost = w.Longitude;
                }
                if (w.Latitude > rightmost)
                {
                    rightmost = w.Latitude;
                }
            }
            double deltaHeight = upmost - downmost;
            int    height      = (int)(deltaHeight * longitudeconversion) + 10;
            double deltaWidth  = rightmost - leftmost;
            int    width       = (int)(deltaWidth * latitudeconversion) + 10;

            rightmost *= latitudeconversion;
            leftmost  *= latitudeconversion;
            upmost    *= longitudeconversion;
            downmost  *= longitudeconversion;
            //Console.WriteLine(Waypoints[0].Latitude * latitudeconversion); // for debugging
            double swrappedlat = (Waypoints[0].Latitude * latitudeconversion) - leftmost;
            //Console.WriteLine(Waypoints[0].Longitude * longitudeconversion); // for debugging
            double   swrappedlon = (Waypoints[0].Longitude * longitudeconversion) - downmost;
            Location start       = new Location(Convert.ToInt32(swrappedlat) + 5, Convert.ToInt32(swrappedlon) + 5);
            //Console.WriteLine(Waypoints[1].Latitude * latitudeconversion); // for debugging
            double gwrappedlat = (Waypoints[1].Latitude * latitudeconversion) - leftmost;
            //Console.WriteLine(Waypoints[1].Longitude * longitudeconversion); // for debugging
            double     gwrappedlon  = (Waypoints[1].Longitude * longitudeconversion) - downmost;
            Location   goal         = new Location(Convert.ToInt32(gwrappedlat) + 5, Convert.ToInt32(gwrappedlon) + 5);
            SquareGrid playingField = new SquareGrid(Waypoints[0].Altitude, width, height, start, goal, Waypoints[0].Order);

            foreach (ParsedObstacle po in ParsedObstacles)
            {
                double   wrappedlat = (po.Latitude * latitudeconversion) - leftmost;
                double   wrappedlon = (po.Longitude * longitudeconversion) - downmost;
                Location center     = new Location(Convert.ToInt32(wrappedlat) + 5, Convert.ToInt32(wrappedlon) + 5);
                playingField.obstacles.Add(new Circle(center, po.Radius));
            }
            foreach (Waypoint boundarypoint in Boundaries)
            {
                double wrappedlat = (boundarypoint.Latitude * latitudeconversion) - leftmost;
                double wrappedlon = (boundarypoint.Longitude * longitudeconversion) - downmost;
                playingField.boundaries.Add(new OrderedLocation(boundarypoint.Order, Convert.ToInt32(wrappedlat), Convert.ToInt32(wrappedlon)));
                playingField.boundaries.Sort();
            }
            return(playingField);
        }