private List <WeightedTile> GetWalkableTiles(WeightedTile currentTile, WeightedTile targetTile, List <Tile> allTiles) { var possibleTiles = new List <WeightedTile> { new WeightedTile { Position = new Position(currentTile.Position.X, currentTile.Position.Y - 1), Parent = currentTile, CostFromStartToThis = currentTile.CostFromStartToThis + 1 }, new WeightedTile { Position = new Position(currentTile.Position.X, currentTile.Position.Y + 1), Parent = currentTile, CostFromStartToThis = currentTile.CostFromStartToThis + 1 }, new WeightedTile { Position = new Position(currentTile.Position.X - 1, currentTile.Position.Y), Parent = currentTile, CostFromStartToThis = currentTile.CostFromStartToThis + 1 }, new WeightedTile { Position = new Position(currentTile.Position.X + 1, currentTile.Position.Y), Parent = currentTile, CostFromStartToThis = currentTile.CostFromStartToThis + 1 }, }; possibleTiles.ForEach(tile => tile.SetDistance(targetTile.Position)); // keep only empty tiles (tile with such position is not in allTiles) or walkableTiles return(possibleTiles.Where(weightedTile => { var tileAtPos = allTiles.FirstOrDefault(tile => tile.Position.Equals(weightedTile.Position)); return weightedTile.Position.X < endOfDungeonBoundary.MaxX && weightedTile.Position.Y < endOfDungeonBoundary.MaxY && weightedTile.Position.X > endOfDungeonBoundary.MinX && weightedTile.Position.Y > endOfDungeonBoundary.MinY && (tileAtPos.IsEmpty() || tileAtPos.IsWalkable()); }).ToList()); }
void SpawnStartAndFinish() { startPos = dimensions / 2; rotatedStartTile = GameObject.Instantiate(startTile); int rotation = Random.Range(0, 4); for (int i = 0; i < rotation; i++) { rotatedStartTile.Rotate(); } rotatedStartTile.transform.SetParent(transform); rotatedStartTile.gameObject.SetActive(false); rotatedStartTile.name = startTile.name + " " + rotatedStartTile.rotation; WeightedTile weightedStartTile = new WeightedTile(); weightedStartTile.tile = rotatedStartTile; weightedStartTile.weight = 1; List <WeightedTile> startTileList = new List <WeightedTile>(); startTileList.Add(weightedStartTile); wave[startPos.x, startPos.y] = new WaveElement(startTileList); Collapse(startPos); endPos = new Vector2Int(Random.Range(0, dimensions.x), Random.Range(0, dimensions.y)); while (Vector2Int.Distance(startPos, endPos) < Mathf.Max(dimensions.x, dimensions.y) / 4) { endPos = new Vector2Int(Random.Range(0, dimensions.x), Random.Range(0, dimensions.y)); } wave[endPos.x, endPos.y].RemoveTilesNotOfType(Tile.TileType.road); }
public IEnumerable <Tile> FindPath(Tile startTile, Tile finishTile, IEnumerable <Tile> tiles) { var start = new WeightedTile(startTile); var finish = new WeightedTile(finishTile); var allTiles = tiles.ToList(); start.SetDistance(finish.Position); var activeWeightedTiles = new List <WeightedTile>(); activeWeightedTiles.Add(start); var visitedWeightedTiles = new List <WeightedTile>(); while (activeWeightedTiles.Any()) { var checkTile = activeWeightedTiles.OrderBy(t => t.CostDistance).First(); if (checkTile.Position.Equals(finish.Position)) { var lastTile = checkTile; var path = new List <WeightedTile>(); while (lastTile != null) { path.Add(lastTile); lastTile = lastTile.Parent; } return(path.Select(weightedTile => new Tile(TileType.Floor, weightedTile.Position)).ToList()); } visitedWeightedTiles.Add(checkTile); activeWeightedTiles.Remove(checkTile); var walkableTiles = GetWalkableTiles(checkTile, finish, allTiles); foreach (var walkableTile in walkableTiles) { if (visitedWeightedTiles.Any(t => t.Position.Equals(walkableTile.Position))) { continue; } if (activeWeightedTiles.Any(t => t.Position.Equals(walkableTile.Position))) { var existingTile = activeWeightedTiles.First(t => t.Position.Equals(walkableTile.Position)); if (existingTile.CostDistance > checkTile.CostDistance) { activeWeightedTiles.Remove(existingTile); activeWeightedTiles.Add(walkableTile); } } else { activeWeightedTiles.Add(walkableTile); } } } Console.Out.WriteLine($"[!] Couldn't find a path!"); return(new List <Tile>()); }
public Vector2[] Navigate(Vector2 start, Vector2 end) { var startTile = new WeightedTile() { Position = start }; var closedList = new List <WeightedTile>(); var openList = new List <WeightedTile>() { startTile }; while (openList.Any()) { var quickestTile = openList.OrderBy(t => t.Weight).First(); if (quickestTile.Position == end) // We're done! Found the path. { return(FindPath(startTile, quickestTile)); } openList.Remove(quickestTile); closedList.Add(quickestTile); foreach (var neighbor in _searchableDirections.Select(d => d.ToVector2()) .Select(d => quickestTile.Position + d) .Where(d => IsTraversable(d))) { if (closedList.Any(c => c.Position == neighbor)) { continue; } var movementCost = Mathf.RoundToInt( Mathf2.DistanceTo(neighbor, startTile.Position) + quickestTile.MovementCost); var existingNeighbor = openList.FirstOrDefault(o => o.Position == neighbor); if (existingNeighbor == null) { openList.Add(new WeightedTile() { MovementCost = movementCost, Heuristic = Mathf.RoundToInt(Mathf2.DistanceTo(neighbor, end)), Parent = quickestTile, Position = neighbor }); } else if (existingNeighbor.MovementCost > movementCost) { existingNeighbor.MovementCost = movementCost; existingNeighbor.Parent = quickestTile; } } } return(new Vector2[0]); }
Vector2[] FindPath(WeightedTile start, WeightedTile end) { var currentNode = end; var path = new List<WeightedTile> (); while (currentNode.Position != start.Position) { currentNode = currentNode.Parent; path.Add (currentNode); } path.Insert (0, end); return path.Select (wt => wt.Position).Reverse().ToArray(); }
Vector2[] FindPath(WeightedTile start, WeightedTile end) { var currentNode = end; var path = new List <WeightedTile> (); while (currentNode.Position != start.Position) { currentNode = currentNode.Parent; path.Add(currentNode); } path.Insert(0, end); return(path.Select(wt => wt.Position).Reverse().ToArray()); }
public Vector2[] Navigate(Vector2 start, Vector2 end) { var startTile = new WeightedTile() { Position = start }; var closedList = new List<WeightedTile>(); var openList = new List<WeightedTile>() { startTile }; while(openList.Any()) { var quickestTile = openList.OrderBy(t => t.Weight).First(); if(quickestTile.Position == end) { // We're done! Found the path. return FindPath(startTile, quickestTile); } openList.Remove(quickestTile); closedList.Add(quickestTile); foreach(var neighbor in _searchableDirections.Select (d => d.ToVector2()) .Select (d => quickestTile.Position + d) .Where (d => IsTraversable(d))) { if(closedList.Any(c => c.Position == neighbor)) { continue; } var movementCost = Mathf.RoundToInt( Mathf2.DistanceTo(neighbor, startTile.Position) + quickestTile.MovementCost); var existingNeighbor = openList.FirstOrDefault(o => o.Position == neighbor); if(existingNeighbor == null) { openList.Add(new WeightedTile() { MovementCost = movementCost, Heuristic = Mathf.RoundToInt(Mathf2.DistanceTo(neighbor, end)), Parent = quickestTile, Position = neighbor }); } else if(existingNeighbor.MovementCost > movementCost) { existingNeighbor.MovementCost = movementCost; existingNeighbor.Parent = quickestTile; } } } return new Vector2[0]; }