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); }
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); }
private void ReconstructPath() { path.Add(finish.tile); DijkstraTile nextTile = finish; while (nextTile != start) { nextTile = nextTile.parent; path.Add(nextTile.tile); } }
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()); }
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. } } }
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); } }
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); }
// 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); } }