示例#1
0
    private void AddNeighboursToList(DijkstraTile previousTile)
    {
        //left
        if (previousTile.tile.x > 1)
        {
            UpdateTileDistance(previousTile.tile.x - 1, previousTile.tile.y, previousTile);
        }

        //right
        if (previousTile.tile.x < map.GetLength(0) - 2)
        {
            UpdateTileDistance(previousTile.tile.x + 1, previousTile.tile.y, previousTile);
        }

        //down
        if (previousTile.tile.y > 1)
        {
            UpdateTileDistance(previousTile.tile.x, previousTile.tile.y - 1, previousTile);
        }

        //top
        if (previousTile.tile.y < map.GetLength(1) - 2)
        {
            UpdateTileDistance(previousTile.tile.x, previousTile.tile.y + 1, previousTile);
        }
    }
    private static List <DijkstraTile> CalculateDistances(List <DijkstraTile> dijkTiles)
    {
        DijkstraTile lastChecked = dijkTiles.FirstOrDefault(d => d.Completed);

        while (dijkTiles.Any(d => d.Completed == false))
        {
            List <DijkstraTile> adjTiles = dijkTiles.Where(d => lastChecked.AdjascentTiles.Any(l => l.Coordinate == d.t.Coordinate && !d.Completed)).ToList();

            foreach (var tile in adjTiles)
            {
                if (tile.Distance > lastChecked.Distance + tile.Cost)
                {
                    tile.Distance = lastChecked.Distance + tile.Cost;
                    tile.Path     = lastChecked.Path.ToList();
                    tile.Path.Add(lastChecked.t);
                }
            }

            lastChecked.Completed = true;
            var uncompletedDijk = dijkTiles.Where(d => !d.Completed).ToList();
            if (uncompletedDijk.Count == 0)
            {
                break;
            }
            var minDistance = uncompletedDijk.Min(a => a.Distance);
            var minVal      = uncompletedDijk.FirstOrDefault(m => m.Distance == minDistance);
            //var minAdj = adjTiles.First(m=>m.distance == adjTiles.Min(a => a.distance));

            lastChecked = minVal;
        }
        return(dijkTiles);
    }
示例#3
0
    public static DijkstraTile[,] generateDijkstraGrid(DijkstraTile[,] grid, Vector2Int gridSize, DijkstraTile target)
    {
        //flood fill out from the end point
        DijkstraTile destination = target;

        destination.setWeight(0);
        grid[destination.getVector2d().x, destination.getVector2d().y].setWeight(0);

        List <DijkstraTile> toVisit = new List <DijkstraTile>();

        toVisit.Add(destination);//check this maybe!!!


        //for each node we need to visit, starting with the pathEnd
        for (int i = 0; i < toVisit.Count; i++)
        {
            List <DijkstraTile> neighbours = straightNeighboursOf(toVisit[i], gridSize);

            //for each neighbour of this node (only straight line neighbours, not diagonals)
            foreach (DijkstraTile neighbour in neighbours)
            {
                //We will only ever visit every node once as we are always visiting nodes in the most efficient order
                if (grid[neighbour.getVector2d().x, neighbour.getVector2d().y].getWeight() == -1)  //if tile has not been visited
                {
                    neighbour.setWeight(toVisit[i].getWeight() + 1);
                    grid[neighbour.getVector2d().x, neighbour.getVector2d().y].setWeight(neighbour.getWeight());
                    toVisit.Add(neighbour);
                }
            }
        }
        return(grid);
    }
示例#4
0
    private void ReconstructPath()
    {
        path.Add(finish.tile);
        DijkstraTile nextTile = finish;

        while (nextTile != start)
        {
            nextTile = nextTile.parent;
            path.Add(nextTile.tile);
        }
    }
示例#5
0
    public override bool CreatePath(Tile[,] map, Tile start, Tile finish)
    {
        unvisitedList = new List <DijkstraTile>();
        path          = new List <Tile>();

        ConvertMap(map);
        this.start = ConvertTile(start, 1, 0);
        this.map[start.x, start.y] = this.start;
        this.finish = ConvertTile(finish, 1, int.MaxValue);
        this.map[finish.x, finish.y] = this.finish;

        return(DijkstraPath());
    }
示例#6
0
 private bool DijkstraPath()
 {
     unvisitedList.Add(start);
     while (unvisitedList.Count > 0)
     {
         DijkstraTile nextTile = GetClosestTile();
         AddNeighboursToList(nextTile);
         unvisitedList.Remove(nextTile);
         nextTile.visited = true;
     }
     if (finish.visited)
     {
         ReconstructPath();
         return(true);
     }
     return(false);
 }
    private static List <DijkstraTile> InitializeDistance(List <Tile> tiles, Tile start, List <Tile> blockedTiles)
    {
        List <DijkstraTile> dijTiles = new List <DijkstraTile>();

        foreach (var tile in tiles)
        {
            if (tile.Coordinate != start.Coordinate)
            {
                var d = new DijkstraTile(tile);
                d.AdjascentTiles = tiles.Where(t =>
                                               (
                                                   (Math.Abs(tile.Coordinate.x - t.Coordinate.x) == 1 && tile.Coordinate.y - t.Coordinate.y == 0) ||
                                                   (Math.Abs(tile.Coordinate.y - t.Coordinate.y) == 1 && tile.Coordinate.x - t.Coordinate.x == 0)
                                               ) &&
                                               !(Math.Abs(tile.Coordinate.x - t.Coordinate.x) == 1 && Math.Abs(tile.Coordinate.y - t.Coordinate.y) == 1)).ToList();

                dijTiles.Add(d);
            }
            else
            {
                var d = new DijkstraTile(tile);
                d.Distance       = 0;
                d.Completed      = true;
                d.AdjascentTiles = tiles.Where(t =>
                                               (
                                                   (Math.Abs(tile.Coordinate.x - t.Coordinate.x) == 1 && tile.Coordinate.y - t.Coordinate.y == 0) ||
                                                   (Math.Abs(tile.Coordinate.y - t.Coordinate.y) == 1 && tile.Coordinate.x - t.Coordinate.x == 0)
                                               ) &&
                                               !(Math.Abs(tile.Coordinate.x - t.Coordinate.x) == 1 && Math.Abs(tile.Coordinate.y - t.Coordinate.y) == 1)).ToList();

                dijTiles.Add(d);
            }
        }
        foreach (var t in blockedTiles)
        {
            var dijk = dijTiles.FirstOrDefault(d => d.t.Coordinate == t.Coordinate);
            if (dijk != null)
            {
                dijk.Cost = 1000;
            }
        }
        return(dijTiles);
    }
    void CreateGrid()
    {
        NodeArray = new DijkstraTile[iGridSizeX, iGridSizeY];                                                                                                   //Declare the array of nodes.
        Vector3 bottomLeft = transform.position - Vector3.right * vGridWorldSize.x / 2 - Vector3.forward * vGridWorldSize.y / 2;                                //Get the real world position of the bottom left of the grid.

        for (int x = 0; x < iGridSizeX; x++)                                                                                                                    //Loop through the array of nodes.
        {
            for (int y = 0; y < iGridSizeY; y++)                                                                                                                //Loop through the array of nodes
            {
                Vector3      worldPoint = bottomLeft + Vector3.right * (x * fNodeDiameter + fNodeRadius) + Vector3.forward * (y * fNodeDiameter + fNodeRadius); //Get the world co ordinates of the bottom left of the graph
                DijkstraTile tile       = new DijkstraTile(new Vector2Int(x, y), worldPoint);

                if (Physics.CheckSphere(worldPoint, fNodeRadius, WallMask))
                {
                    tile.setWeight(int.MaxValue);
                }
                NodeArray[x, y] = tile;//Create a new node in the array.
            }
        }
    }
示例#9
0
    private void UpdateTileDistance(int x, int y, DijkstraTile previousTile)
    {
        DijkstraTile addTile = map[x, y];

        if (addTile.tile.value != TileValue.Floor)
        {
            return;
        }

        int newDistance = previousTile.distanceToStart + addTile.weight;

        if (addTile.distanceToStart > newDistance)
        {
            addTile.distanceToStart = newDistance;
            addTile.parent          = previousTile;
        }
        if (!addTile.visited && !unvisitedList.Contains(addTile))
        {
            unvisitedList.Add(addTile);
        }
    }
示例#10
0
    private static List <DijkstraTile> straightNeighboursOf(DijkstraTile tile, Vector2Int gridSize)
    {
        List <DijkstraTile> neighbours = new List <DijkstraTile>();

        if (tile.getVector2d().x > 0)
        {
            neighbours.Add(new DijkstraTile(new Vector2Int(tile.getVector2d().x - 1, tile.getVector2d().y), Vector3.zero));
        }
        if (tile.getVector2d().y > 0)
        {
            neighbours.Add(new DijkstraTile(new Vector2Int(tile.getVector2d().x, tile.getVector2d().y - 1), Vector3.zero));
        }
        if (tile.getVector2d().x < gridSize.x - 1)
        {
            neighbours.Add(new DijkstraTile(new Vector2Int(tile.getVector2d().x + 1, tile.getVector2d().y), Vector3.zero));
        }
        if (tile.getVector2d().y < gridSize.y - 1)
        {
            neighbours.Add(new DijkstraTile(new Vector2Int(tile.getVector2d().x, tile.getVector2d().y + 1), Vector3.zero));
        }
        return(neighbours);
    }
示例#11
0
    // Update is called once per frame
    void FixedUpdate()
    {
        DijkstraTile currentTile = worldGrid.NodeFromWorldPoint(agentPosition.position);

        if (this.lastValidTile == null)
        {
            this.lastValidTile = currentTile;
        }
        if (currentTile.getFlowFieldVector().Equals(Vector2Int.zero))
        {
            Vector2Int flowVector = this.lastValidTile.getVector2d() - currentTile.getVector2d();
            Vector3    moveDir    = new Vector3(flowVector.x, 0, flowVector.y).normalized;
            rb.AddForce(moveDir * Time.deltaTime * force, ForceMode.Force);
            //transform.position += moveDir * Time.deltaTime;
        }
        else
        {
            this.lastValidTile = currentTile;
            Vector2Int flowVector = currentTile.getFlowFieldVector();
            Vector3    moveDir    = new Vector3(flowVector.x, 0, flowVector.y).normalized;
            rb.AddForce(moveDir * Time.deltaTime * force, ForceMode.Force);
        }
    }