public IEnumerable <Tile> Navigate(Tile from, Tile to) { var closed = new List <Tile>(); var open = new List <Tile>() { from }; var path = new Dictionary <Tile, Tile>(); var gScore = new Dictionary <Tile, double>(); gScore[from] = 0; var fScore = new Dictionary <Tile, double>(); fScore[from] = heuristicAlgorithm.Calculate(from, to); while (open.Any()) { var current = open .OrderBy(c => fScore[c]) .First(); if (current == to) { return(ReconstructPath(path, current)); } open.Remove(current); closed.Add(current); foreach (Tile neighbor in neighborProvider.GetNeighbors(current)) { if (closed.Contains(neighbor) || blockedProvider.IsBlocked(neighbor)) { continue; } var tentativeG = gScore[current] + distanceAlgorithm.Calculate(current, neighbor); if (!open.Contains(neighbor)) { open.Add(neighbor); } else if (tentativeG >= gScore[neighbor]) { continue; } path[neighbor] = current; gScore[neighbor] = tentativeG; fScore[neighbor] = gScore[neighbor] + heuristicAlgorithm.Calculate(neighbor, to); } } return(null); }
public IEnumerable <Tile> Navigate(Tile from, Tile to, int maxAttempts = int.MaxValue) { var closed = new HashSet <Tile>(); var open = new HashSet <Tile>() { from }; var path = new Dictionary <Tile, Tile>(); from.FScore = heuristicAlgorithm.Calculate(from, to); int noOfAttempts = 0; Tile highScore = from; Tile last = from; while (open.Count != 0) { var current = last; if (last != highScore) { current = open .OrderBy(c => c.FScore) .First(); } last = null; if (++noOfAttempts > maxAttempts) { return(ReconstructPath(path, highScore)); } if (current.Equals(to)) { return(ReconstructPath(path, current)); } open.Remove(current); closed.Add(current); foreach (Tile neighbor in neighborProvider.GetNeighbors(current)) { if (closed.Contains(neighbor) || blockedProvider.IsBlocked(neighbor)) { continue; } var tentativeG = current.GScore + distanceAlgorithm.Calculate(current, neighbor); if (!open.Add(neighbor) && tentativeG >= neighbor.GScore) { continue; } path[neighbor] = current; neighbor.GScore = tentativeG; neighbor.FScore = neighbor.GScore + heuristicAlgorithm.Calculate(neighbor, to); if (neighbor.FScore <= highScore.FScore) { highScore = neighbor; last = neighbor; } } } return(null); }