Exemplo n.º 1
0
    public static TilePath DiscoverPath(Tilemap map, Vector3Int start, Vector3Int end)
    {
        //you will return this path to the user.  It should be the shortest path between
        //the start and end vertices
        TilePath discoveredPath = new TilePath();

        //TileFactory is how you get information on tiles that exist at a particular vector's
        //coordinates
        TileFactory tileFactory = TileFactory.GetInstance();

        //This is the priority queue of paths that you will use in your implementation of
        //Dijkstra's algorithm
        PriortyQueue <TilePath> pathQueue = new PriortyQueue <TilePath>();

        //You can slightly speed up your algorithm by remembering previously visited tiles.
        //This isn't strictly necessary.
        Dictionary <Vector3Int, int> discoveredTiles = new Dictionary <Vector3Int, int>();

        //quick sanity check
        if (map == null || start == null || end == null)
        {
            return(discoveredPath);
        }

        //This is how you get tile information for a particular map location
        //This gets the Unity tile, which contains a coordinate (.Position)
        var startingMapLocation = map.GetTile(start);

        //And this converts the Unity tile into an object model that tracks the
        //cost to visit the tile.
        var startingTile = tileFactory.GetTile(startingMapLocation.name);

        startingTile.Position = start;

        //Any discovered path must start at the origin!
        discoveredPath.AddTileToPath(startingTile);

        //This adds the starting tile to the PQ and we start off from there...
        pathQueue.Enqueue(discoveredPath);
        bool found = false;

        while (found == false && pathQueue.IsEmpty() == false)
        {
            //TODO: Implement Dijkstra's algorithm!

            //This line ensures that we don't get an infinite loop in Unity.
            //You will need to remove it in order for your pathfinding algorithm to work.
            found = true;
        }
        return(discoveredPath);
    }
Exemplo n.º 2
0
    public static TilePath DiscoverPath(Tilemap map, Vector3Int start, Vector3Int end)
    {
        //you will return this path to the user.  It should be the shortest path between
        //the start and end vertices
        TilePath discoveredPath = new TilePath();

        //TileFactory is how you get information on tiles that exist at a particular vector's
        //coordinates
        TileFactory tileFactory = TileFactory.GetInstance();

        //This is the priority queue of paths that you will use in your implementation of
        //Dijkstra's algorithm
        PriortyQueue <TilePath> pathQueue = new PriortyQueue <TilePath>();

        //You can slightly speed up your algorithm by remembering previously visited tiles.
        //This isn't strictly necessary.
        Dictionary <Vector3Int, int> discoveredTiles = new Dictionary <Vector3Int, int>();

        //quick sanity check
        if (map == null || start == null || end == null)
        {
            return(discoveredPath);
        }

        //This is how you get tile information for a particular map location
        //This gets the Unity tile, which contains a coordinate (.Position)
        var startingMapLocation = map.GetTile(start);

        //And this converts the Unity tile into an object model that tracks the
        //cost to visit the tile.
        var startingTile = tileFactory.GetTile(startingMapLocation.name);

        startingTile.Position = start;

        //Any discovered path must start at the origin!
        discoveredPath.AddTileToPath(startingTile);

        //#1 This adds the starting tile to the PQ and we start off from there...
        pathQueue.Enqueue(discoveredPath);
        bool found = false;

        var endingMapLocation = map.GetTile(end);


        var endingTile = tileFactory.GetTile(endingMapLocation.name);

        endingTile.Position = end;
        TilePath pathFound = null;

        //#2 While the priority queue is not empty and while you have not reached your final tile
        while (found == false && pathQueue.IsEmpty() == false)
        {
            /* 1.Add starting location to a priority queue
             * 2.While the priority queue is not empty and while you have not reached your final tile:
             * Pop the top item off of the priority queue
             * If the item contains the final tile in the path, you are done.
             * If not, for each of the tile's neighbors (there should be 4 since we're using square tiles)
             * Create a new path with the additional tile.
             * If that path contains the final tile, you're done.
             * If not, add that path back into the Priority Queue.
             * 3.Return the path discovered in Step #2 back to the caller. */
            //TODO: Implement Dijkstra's algorithm!


            //*Pop the top item off of the priority queue
            TilePath pathToCheck = pathQueue.Dequeue();

            // Tile myTile = item.GetMostRecentTile();

            //*If the item contains the final tile in the path, you are done.

            /* if (pathToCheck.Contains(endingTile))
             * {
             *   pathFound = pathToCheck;
             *   found = true;
             * //  break;
             *
             * }
             */
            if (pathToCheck.GetMostRecentTile().Position == end)
            {
                discoveredPath = pathToCheck;
                found          = true;
            }

            // *If not, for each of the tile's neighbors (there should be 4 since we're using square tiles)
            //*Create a new path with the additional tile.
            else
            {
                Tile recentTile = pathToCheck.GetMostRecentTile();

                //call function getNeighbors -created on 04/13/2020
                List <Tile> neighbors = getNeighbors(map, recentTile, tileFactory);
                //  List<Tile> neighbors = findNeighbors(map, recentTile, tileFactory);


                for (int i = 0; i < neighbors.Count; i++)
                {
                    TilePath newPath      = new TilePath(pathToCheck);
                    Tile     thisneighbor = neighbors[i];
                    newPath.AddTileToPath(thisneighbor);
                    // if (newPath.Contains(endingTile))
                    if (newPath.GetMostRecentTile().Position == end)
                    {
                        discoveredPath = newPath;
                        found          = true;
                        break;
                    }
                    else
                    {
                        pathQueue.Enqueue(newPath);
                    }
                }
            }

            //This line ensures that we don't get an infinite loop in Unity.
            //You will need to remove it in order for your pathfinding algorithm to work.
            // found = true;
        }
        // discoveredPath = pathFound;
        return(discoveredPath);
    }
Exemplo n.º 3
0
    public static TilePath DiscoverPath(Tilemap map, Vector3Int start, Vector3Int end)
    {
        //you will return this path to the user.  It should be the shortest path between
        //the start and end vertices
        TilePath discoveredPath = new TilePath();

        //TileFactory is how you get information on tiles that exist at a particular vector's
        //coordinates
        TileFactory tileFactory = TileFactory.GetInstance();

        //This is the priority queue of paths that you will use in your implementation of
        //Dijkstra's algorithm
        PriortyQueue <TilePath> pathQueue = new PriortyQueue <TilePath>();

        //You can slightly speed up your algorithm by remembering previously visited tiles.
        //This isn't strictly necessary.
        Dictionary <Vector3Int, int> discoveredTiles = new Dictionary <Vector3Int, int>();

        //quick sanity check
        if (map == null || start == null || end == null)
        {
            return(discoveredPath);
        }

        //This is how you get tile information for a particular map location
        //This gets the Unity tile, which contains a coordinate (.Position)
        var startingMapLocation = map.GetTile(start);

        //And this converts the Unity tile into an object model that tracks the
        //cost to visit the tile.
        var startingTile = tileFactory.GetTile(startingMapLocation.name);

        startingTile.Position = start;

        //Any discovered path must start at the origin!
        discoveredPath.AddTileToPath(startingTile);

        //This adds the starting tile to the PQ and we start off from there...
        pathQueue.Enqueue(discoveredPath);
        bool found = false;

        while (found == false && pathQueue.IsEmpty() == false)
        {
            //TODO: Implement Dijkstra's algorithm!
            var  path_  = new TilePath(pathQueue.Dequeue());
            Tile recent = new Tile(path_.GetMostRecentTile());
            if (recent.Position == end)
            {
                return(path_);
            }
            else
            {
                TilePath tempL     = new TilePath(path_);
                Tile     nextTile  = new Tile(recent);
                TileBase up        = map.GetTile(new Vector3Int(recent.Position.x, recent.Position.y + 1, recent.Position.z));
                Tile     uptemp    = new Tile(tileFactory.GetTile(up.name));
                TileBase down      = map.GetTile(new Vector3Int(recent.Position.x, recent.Position.y - 1, recent.Position.z));
                Tile     downtemp  = new Tile(tileFactory.GetTile(down.name));
                TileBase left      = map.GetTile(new Vector3Int(recent.Position.x - 1, recent.Position.y, recent.Position.z));
                Tile     lefttemp  = new Tile(tileFactory.GetTile(left.name));
                TileBase right     = map.GetTile(new Vector3Int(recent.Position.x + 1, recent.Position.y, recent.Position.z));
                Tile     righttemp = new Tile(tileFactory.GetTile(right.name));



                if (up != null)
                {
                    Tile upT = new Tile();
                    upT.Position = new Vector3Int(recent.Position.x, recent.Position.y + 1, recent.Position.z);
                    upT.Weight   = uptemp.Weight;
                    upT.Name     = uptemp.Name;
                    tempL.AddTileToPath(upT);
                    if (upT.Position == end)
                    {
                        return(tempL);
                    }
                    pathQueue.Enqueue(tempL);
                    tempL = new TilePath(path_);
                }
                if (down != null)
                {
                    Tile downT = new Tile();
                    downT.Position = new Vector3Int(recent.Position.x, recent.Position.y - 1, recent.Position.z);
                    downT.Weight   = downtemp.Weight;
                    downT.Name     = downtemp.Name;
                    tempL.AddTileToPath(downT);
                    if (downT.Position == end)
                    {
                        return(tempL);
                    }
                    pathQueue.Enqueue(tempL);
                    tempL = new TilePath(path_);
                }
                if (left != null)
                {
                    Tile leftT = new Tile();
                    leftT.Position = new Vector3Int(recent.Position.x - 1, recent.Position.y, recent.Position.z);
                    leftT.Weight   = lefttemp.Weight;
                    leftT.Name     = lefttemp.Name;
                    tempL.AddTileToPath(leftT);
                    if (leftT.Position == end)
                    {
                        return(tempL);
                    }
                    pathQueue.Enqueue(tempL);
                    tempL = new TilePath(path_);
                }
                if (right != null)
                {
                    Tile rightT = new Tile();
                    rightT.Position = new Vector3Int(recent.Position.x + 1, recent.Position.y, recent.Position.z);
                    rightT.Weight   = righttemp.Weight;
                    rightT.Name     = righttemp.Name;
                    tempL.AddTileToPath(rightT);
                    if (rightT.Position == end)
                    {
                        return(tempL);
                    }
                    pathQueue.Enqueue(tempL);
                }
            }

            //This line ensures that we don't get an infinite loop in Unity.
            //You will need to remove it in order for your pathfinding algorithm to work.
        }
        return(discoveredPath);
    }
Exemplo n.º 4
0
    public static TilePath DiscoverPath(Tilemap map, Vector3Int start, Vector3Int end)
    {
        //you will return this path to the user.  It should be the shortest path between
        //the start and end vertices
        TilePath discoveredPath = new TilePath();

        //TileFactory is how you get information on tiles that exist at a particular vector's
        //coordinates
        TileFactory tileFactory = TileFactory.GetInstance();

        //This is the priority queue of paths that you will use in your implementation of
        //Dijkstra's algorithm
        PriortyQueue <TilePath> pathQueue = new PriortyQueue <TilePath>();

        //You can slightly speed up your algorithm by remembering previously visited tiles.
        //This isn't strictly necessary.
        Dictionary <Vector3Int, int> discoveredTiles = new Dictionary <Vector3Int, int>();

        //quick sanity check
        if (map == null || start == null || end == null)
        {
            return(discoveredPath);
        }

        //This is how you get tile information for a particular map location
        //This gets the Unity tile, which contains a coordinate (.Position)
        var startingMapLocation = map.GetTile(start);

        //And this converts the Unity tile into an object model that tracks the
        //cost to visit the tile.
        var startingTile = tileFactory.GetTile(startingMapLocation.name);

        startingTile.Position = start;

        //Any discovered path must start at the origin!
        discoveredPath.AddTileToPath(startingTile);

        //This adds the starting tile to the PQ and we start off from there...
        pathQueue.Enqueue(discoveredPath);
        bool found = false;

        while (found == false && pathQueue.IsEmpty() == false)
        {
            //Get the next path from the queue
            TilePath Path = new TilePath(pathQueue.GetFirst());
            pathQueue.Dequeue();

            //Get newest added tile to process
            Tile       Tile     = new Tile(Path.GetMostRecentTile());
            Vector3Int Position = new Vector3Int(Tile.Position.x, Tile.Position.y, Tile.Position.z);

            //Add neighbors of newest tile to list for processing
            List <Vector3Int> adjacentTiles = new List <Vector3Int>();
            adjacentTiles.Add(new Vector3Int(Position.x, Position.y + 1, Position.z));
            adjacentTiles.Add(new Vector3Int(Position.x, Position.y - 1, Position.z));
            adjacentTiles.Add(new Vector3Int(Position.x + 1, Position.y, Position.z));
            adjacentTiles.Add(new Vector3Int(Position.x - 1, Position.y, Position.z));

            //For each loop processes each neighboring tile in list
            foreach (Vector3Int tile in adjacentTiles)
            {
                //Creates new path with current path as basis
                TilePath   newPath     = new TilePath(Path);
                Vector3Int newPosition = new Vector3Int(tile.x, tile.y, tile.z);

                //Grabs the data from our tile sprite in our tilemap
                var tileData = map.GetTile(newPosition);
                if (tileData == null)
                {
                    continue;
                }

                //Associates the data with an actual tile
                var newTile = tileFactory.GetTile(tileData.name);
                newTile.Position = newPosition;

                //If at end add tile and finish up
                if (newTile.Position == end)
                {
                    newPath.AddTileToPath(newTile);
                    discoveredPath = newPath;
                    found          = true;
                    break;
                }
                //If tile isn't end but hasnt been visited yet
                else if (discoveredTiles.ContainsKey(newPosition) == false)
                {
                    newPath.AddTileToPath(newTile);
                    pathQueue.Enqueue(newPath);
                    discoveredTiles.Add(newPosition, 1);
                }
            }
        }
        return(discoveredPath);
    }
Exemplo n.º 5
0
    public static TilePath DiscoverPath(Tilemap map, Vector3Int start, Vector3Int end)
    {
        //you will return this path to the user.  It should be the shortest path between
        //the start and end vertices
        TilePath discoveredPath = new TilePath();

        //TileFactory is how you get information on tiles that exist at a particular vector's
        //coordinates
        TileFactory tileFactory = TileFactory.GetInstance();

        //This is the priority queue of paths that you will use in your implementation of
        //Dijkstra's algorithm
        PriortyQueue <TilePath> pathQueue = new PriortyQueue <TilePath>();

        //You can slightly speed up your algorithm by remembering previously visited tiles.
        //This isn't strictly necessary.
        Dictionary <Vector3Int, int> discoveredTiles = new Dictionary <Vector3Int, int>();

        //quick sanity check
        if (map == null || start == null || end == null)
        {
            return(discoveredPath);
        }

        //This is how you get tile information for a particular map location
        //This gets the Unity tile, which contains a coordinate (.Position)
        var startingMapLocation = map.GetTile(start);

        //And this converts the Unity tile into an object model that tracks the
        //cost to visit the tile.
        var startingTile = tileFactory.GetTile(startingMapLocation.name);

        startingTile.Position = start;

        //Any discovered path must start at the origin!
        discoveredPath.AddTileToPath(startingTile);

        //This adds the starting tile to the PQ and we start off from there...
        pathQueue.Enqueue(discoveredPath);
        bool found = false;

        while (found == false && pathQueue.IsEmpty() == false)
        {
            // Pop the top item off of the priority queue
            TilePath current         = new TilePath(pathQueue.Dequeue());
            var      tempTile        = map.GetTile(start);
            var      currentPosition = current.GetMostRecentTile().Position;

            if (currentPosition == end)
            {
                //If the item contains the final tile in the path, you are done.
                found          = true;
                discoveredPath = current;
            }
            else
            {
                // If not, for each of the tile's neighbors (there should be 4 since we're using square tiles)
                Vector3Int   up            = new Vector3Int(currentPosition.x, currentPosition.y + 1, currentPosition.z);
                Vector3Int   down          = new Vector3Int(currentPosition.x, currentPosition.y - 1, currentPosition.z);
                Vector3Int   left          = new Vector3Int(currentPosition.x - 1, currentPosition.y, currentPosition.z);
                Vector3Int   right         = new Vector3Int(currentPosition.x + 1, currentPosition.y, currentPosition.z);
                Vector3Int[] adjacentTiles = new Vector3Int[] { up, down, left, right };

                // Create a new path with the additional tile.
                for (int i = 0; i < adjacentTiles.Length; i++)
                {
                    tempTile = map.GetTile(adjacentTiles[i]);
                    if (tempTile != null)
                    {
                        Tile newTile = new Tile(tileFactory.GetTile(tempTile.name));
                        newTile.Position = adjacentTiles[i];
                        TilePath newPath = new TilePath(current);
                        newPath.AddTileToPath(newTile);

                        if (newTile.Position == end)
                        {
                            // If that path contains the final tile, you're done.
                            found          = true;
                            discoveredPath = newPath;
                        }
                        else
                        {
                            // If not, add that path back into the Priority Queue.
                            pathQueue.Enqueue(newPath);
                        }
                    }
                }
            }
        }
        return(discoveredPath);
    }
    public static TilePath DiscoverPath(Tilemap map, Vector3Int start, Vector3Int end)
    {
        //you will return this path to the user.  It should be the shortest path between
        //the start and end vertices
        TilePath discoveredPath = new TilePath();

        //TileFactory is how you get information on tiles that exist at a particular vector's
        //coordinates
        TileFactory tileFactory = TileFactory.GetInstance();

        //This is the priority queue of paths that you will use in your implementation of
        //Dijkstra's algorithm
        PriortyQueue <TilePath> pathQueue = new PriortyQueue <TilePath>();

        //You can slightly speed up your algorithm by remembering previously visited tiles.
        //This isn't strictly necessary.
        List <Vector3Int> discoveredTiles = new List <Vector3Int>();

        //quick sanity check
        if (map == null || start == null || end == null)
        {
            return(discoveredPath);
        }
        discoveredTiles.Add(start);

        //This is how you get tile information for a particular map location
        //This gets the Unity tile, which contains a coordinate (.Position)
        var startingMapLocation = map.GetTile(start);

        //And this converts the Unity tile into an object model that tracks the
        //cost to visit the tile.
        Tile startingTile = tileFactory.GetTile(startingMapLocation.name);

        startingTile.Position = start;

        // Temporary usage of discoveredPath
        discoveredPath.AddTileToPath(startingTile);

        //This adds the starting tile to the PQ and we start off from there...
        pathQueue.Enqueue(discoveredPath);
        while (pathQueue.IsEmpty() == false)
        {
            TilePath   current    = pathQueue.Dequeue();
            Vector3Int currentPos = current.GetMostRecentTile().Position;
            if (currentPos == end)
            {
                discoveredPath = current;
                break;
            }
            for (int x = 1, y = 0; x + y != 0; y += x, x -= y, y -= Convert.ToInt32(x == -1))
            {
                Vector3Int find = new Vector3Int(currentPos.x + x, currentPos.y + y, currentPos.z);
                if (!discoveredTiles.Contains(find))
                {
                    discoveredTiles.Add(find);
                    TilePath next         = new TilePath(current);
                    var      nextLocation = map.GetTile(find);
                    if (nextLocation == null)
                    {
                        continue;
                    }
                    Tile nextTile = tileFactory.GetTile(nextLocation.name);
                    nextTile.Position = find;
                    next.AddTileToPath(nextTile);
                    pathQueue.Enqueue(next);
                }
            }
        }
        return(discoveredPath);
    }
Exemplo n.º 7
0
    public static TilePath DiscoverPath(Tilemap map, Vector3Int start, Vector3Int end)
    {
        //you will return this path to the user.  It should be the shortest path between
        //the start and end vertices
        TilePath discoveredPath = new TilePath();

        //TileFactory is how you get information on tiles that exist at a particular vector's
        //coordinates
        TileFactory tileFactory = TileFactory.GetInstance();

        //This is the priority queue of paths that you will use in your implementation of
        //Dijkstra's algorithm
        PriortyQueue <TilePath> pathQueue = new PriortyQueue <TilePath>();

        //You can slightly speed up your algorithm by remembering previously visited tiles.
        //This isn't strictly necessary.
        Dictionary <Vector3Int, int> discoveredTiles = new Dictionary <Vector3Int, int>();

        //quick sanity check
        if (map == null || start == null || end == null)
        {
            return(discoveredPath);
        }

        //This is how you get tile information for a particular map location
        //This gets the Unity tile, which contains a coordinate (.Position)
        var startingMapLocation = map.GetTile(start);

        //And this converts the Unity tile into an object model that tracks the
        //cost to visit the tile.
        var startingTile = tileFactory.GetTile(startingMapLocation.name);

        startingTile.Position = start;

        //Any discovered path must start at the origin!
        discoveredPath.AddTileToPath(startingTile);

        //This adds the starting tile to the PQ and we start off from there...
        pathQueue.Enqueue(discoveredPath);
        bool found = false;

        int count = -1;

        while (found == false && pathQueue.IsEmpty() == false)
        {
            //TODO: Implement Dijkstra's algorithm!

            //pop item off priority queue
            TilePath newPath = pathQueue.Dequeue();
            //Tile nextTile = newPath.GetMostRecentTile();

            //if item contains the final tile in the path, you are done
            if (newPath.GetMostRecentTile().Position == end)
            {
                discoveredPath = newPath;
                found          = true;
            }
            else
            {
                Tile nextTile = newPath.GetMostRecentTile();
                //discoveredTiles.Add(new Vector3Int(nextTile.Position.x, nextTile.Position.y, nextTile.Position.z), tileFactory.GetTile(nextTile.name));
                List <Tile> neighborTiles = findNeighbors(map, nextTile, tileFactory);
                //the findneighbors helper funciton only gets the above, the other three are the same

                //for each of the neighbors(4 since using squares)
                for (int i = 0; i < neighborTiles.Count; i++)
                {
                    //create a new path with the additional tile
                    TilePath anotherPath = new TilePath(newPath);
                    anotherPath.AddTileToPath(neighborTiles[i]);

                    //for(int j = 0; j < discoveredTiles.Count; j++)
                    //{
                    //    if(neighborTiles[i].Position != discoveredTiles[j] && anotherPath.GetMostRecentTile().Position != end)
                    //    {
                    //        pathQueue.Enqueue(anotherPath);
                    //    }
                    //    else
                    //    {
                    //        discoveredPath = anotherPath;
                    //        found = true;
                    //        break;
                    //    }

                    //}


                    //if that path contains the final tile, done
                    if (anotherPath.GetMostRecentTile().Position == end)
                    {
                        discoveredPath = anotherPath;
                        found          = true;
                        break;
                    }
                    else
                    {
                        //add that back into priority Queue
                        pathQueue.Enqueue(anotherPath);
                    }
                }
            }
            // else; for each of the neighbors(4 since using squares)
            //create a new path with the additional tile
            //if that path contains the final tile, done
            //else add that back into priority Queue
            //return the path discovered back to caller

            //This line ensures that we don't get an infinite loop in Unity.
            //You will need to remove it in order for your pathfinding algorithm to work.
            //found = true;
            //if(pathQueue.Count >10000)
            //{
            //    break;
            //}
        }
        return(discoveredPath);
    }
Exemplo n.º 8
0
    public static TilePath DiscoverPath(Tilemap map, Tilemap objects, Vector3Int start, Vector3Int end)
    {
        //you will return this path to the user.  It should be the shortest path between
        //the start and end vertices
        TilePath discoveredPath = new TilePath();

        //TileFactory is how you get information on tiles that exist at a particular vector's
        //coordinates
        TileFactory tileFactory = TileFactory.GetInstance();

        //This is the priority queue of paths that you will use in your implementation of
        //Dijkstra's algorithm
        PriortyQueue <TilePath> pathQueue = new PriortyQueue <TilePath>();

        //You can slightly speed up your algorithm by remembering previously visited tiles.
        //This isn't strictly necessary.
        Dictionary <Vector3Int, int> discoveredTiles = new Dictionary <Vector3Int, int>();

        if (objects == null)
        {
            Debug.Log("Objects layer is null");
        }

        //quick sanity check
        if (map == null || objects == null || start == null || end == null)
        {
            return(discoveredPath);
        }

        //This is how you get tile information for a particular map location
        //This gets the Unity tile, which contains a coordinate (.Position)
        var startingMapLocation = map.GetTile(start);
        var startingMapObsticle = objects.GetTile(start);
        //And this converts the Unity tile into an object model that tracks the
        //cost to visit the tile.
        var startingTile = tileFactory.GetTile(startingMapLocation.name);

        if (startingMapObsticle != null)
        {
            var startingObject = tileFactory.GetTile(startingMapObsticle.name);
            startingTile.Position = start;
            startingTile.Weight   = startingTile.Weight + startingObject.Weight;
        }
        else
        {
            int startingObjWeight = 0;
            startingTile.Position = start;
            startingTile.Weight   = startingTile.Weight + startingObjWeight;
            Debug.Log(startingTile.Weight);
        }

        //Any discovered path must start at the origin!
        discoveredPath.AddTileToPath(startingTile);

        //This adds the starting tile to the PQ and we start off from there...
        pathQueue.Enqueue(discoveredPath);
        bool found = false;

        int count = 0;

        while (found == false && pathQueue.IsEmpty() == false)
        {
            //TODO: Implement Dijkstra's algorithm!

            // Dequeue Top,
            TilePath current_path = new TilePath(pathQueue.GetFirst());
            pathQueue.Dequeue();
            Tile       current_tile     = new Tile(current_path.GetMostRecentTile());
            Vector3Int current_position = new Vector3Int(current_tile.Position.x, current_tile.Position.y, current_tile.Position.z);

            List <Vector3Int> adjacent_tiles = new List <Vector3Int>();
            adjacent_tiles.Add(new Vector3Int(current_position.x, current_position.y + 1, current_position.z));
            adjacent_tiles.Add(new Vector3Int(current_position.x, current_position.y - 1, current_position.z));
            adjacent_tiles.Add(new Vector3Int(current_position.x + 1, current_position.y, current_position.z));
            adjacent_tiles.Add(new Vector3Int(current_position.x - 1, current_position.y, current_position.z));
            for (int i = 0; i < adjacent_tiles.Count; i++)
            {
                TilePath   new_path          = new TilePath(current_path);
                Vector3Int neighbor_position = new Vector3Int(adjacent_tiles[i].x, adjacent_tiles[i].y, adjacent_tiles[i].z);
                //Get Neighbor node and set equal to visited_node
                int objectWeight          = 0;
                var visited_node_location = map.GetTile(neighbor_position);
                var visited_node_object   = objects.GetTile(neighbor_position);
                if (visited_node_location == null)
                {
                    continue;
                }
                if (visited_node_object != null)
                {
                    var visited_object = tileFactory.GetTile(visited_node_object.name);
                    objectWeight = visited_object.Weight;
                    if (objectWeight == -1)
                    {
                        continue;
                    }
                }
                var visited_node = tileFactory.GetTile(visited_node_location.name);
                if (visited_node.Weight == -1)
                {
                    continue;
                }
                visited_node.Position = neighbor_position;
                visited_node.Weight   = visited_node.Weight + objectWeight;
                if (visited_node.Position == end)
                {
                    new_path.AddTileToPath(visited_node);
                    discoveredPath = new_path;
                    found          = true;
                    break;
                }
                else if (discoveredTiles.ContainsKey(neighbor_position) == false)
                {
                    new_path.AddTileToPath(visited_node);
                    pathQueue.Enqueue(new_path);
                    discoveredTiles.Add(neighbor_position, 1);
                    count++;
                }
            }
        }
        Debug.Log(discoveredPath.Weight);
        return(discoveredPath);
    }
Exemplo n.º 9
0
    public static TilePath DiscoverPath(Tilemap map, Vector3Int start, Vector3Int end)
    {
        //you will return this path to the user.  It should be the shortest path between
        //the start and end vertices
        TilePath discoveredPath = new TilePath();

        //TileFactory is how you get information on tiles that exist at a particular vector's
        //coordinates
        TileFactory tileFactory = TileFactory.GetInstance();

        //This is the priority queue of paths that you will use in your implementation of
        //Dijkstra's algorithm
        PriortyQueue <TilePath> pathQueue = new PriortyQueue <TilePath>();

        //You can slightly speed up your algorithm by remembering previously visited tiles.
        //This isn't strictly necessary.
        Dictionary <Vector3Int, int> discoveredTiles = new Dictionary <Vector3Int, int>();

        //quick sanity check
        if (map == null || start == null || end == null)
        {
            return(discoveredPath);
        }

        //This is how you get tile information for a particular map location
        //This gets the Unity tile, which contains a coordinate (.Position)
        var startingMapLocation = map.GetTile(start);
        //var endingMapLocation = map.GetTile(end);

        //And this converts the Unity tile into an object model that tracks the
        //cost to visit the tile.
        var startingTile = tileFactory.GetTile(startingMapLocation.name);

        startingTile.Position = start;

        //var endingTile = tileFactory.GetTile(endingMapLocation.name);
        //endingTile.Position = end;

        //Any discovered path must start at the origin!
        discoveredPath.AddTileToPath(startingTile);

        //This adds the starting tile to the PQ and we start off from there...
        pathQueue.Enqueue(discoveredPath);
        bool found = false;

        while (found == false && pathQueue.IsEmpty() == false)
        {
            //TODO: Implement Dijkstra's algorithm!
            TilePath current_path = new TilePath(pathQueue.Dequeue());

            Vector3Int position = current_path.GetMostRecentTile().Position;

            if (position == end) // If currentLocation == End location
            {
                discoveredPath = current_path;
                break;
            }

            Vector3Int next_down  = position;
            Vector3Int next_up    = position;
            Vector3Int next_right = position;
            Vector3Int next_left  = position;
            next_down.y  -= 1;
            next_up.y    += 1;
            next_right.x += 1;
            next_left.x  -= 1;

            Vector3Int[] next_poses = new Vector3Int[4];
            next_poses[0] = next_down;
            next_poses[1] = next_up;
            next_poses[2] = next_right;
            next_poses[3] = next_left;

            for (int i = 0; i < 4; i++)
            {
                // Get the tile and set to position of X
                var next_position = map.GetTile(next_poses[i]);
                if (next_position != null) // check if fallen off edge of map
                {
                    var new_tile = tileFactory.GetTile(next_position.name);
                    new_tile.Position = next_poses[i];

                    // Now we make a brand new path based on our current one.(bullet 1)
                    TilePath new_path = new TilePath(current_path); // Done

                    // Add new_tile to new_path
                    new_path.AddTileToPath(new_tile); // todo

                    // does it contain end tile?
                    if (next_poses[i] == end)
                    {
                        found          = true;
                        discoveredPath = new_path;
                        break;
                    }
                    else
                    {
                        pathQueue.Enqueue(new_path);
                    }
                }
            }

            //This line ensures that we don't get an infinite loop in Unity.
            //You will need to remove it in order for your pathfinding algorithm to work.
            //found = true;
        }

        return(discoveredPath);
    }