public override SearchDetails GetPathTick() { if (NodoActual == null) { if (!_Listaabierta.Any()) { return(GetSearchDetails()); } // Take the current node off the open list to be examined NodoActual = _Listaabierta.OrderBy(x => x.F).ThenBy(x => x.H).First(); // Move it to the closed list so it doesn't get examined again _Listaabierta.Remove(NodoActual); Cerrado.Add(NodoActual); Cuadricula.SetCell(NodoActual.Coord, Enums.CellType.Closed); _vecinos.AddRange(GetVECINO(NodoActual)); } if (_vecinos.Any()) { Cuadricula.SetCell(NodoActual.Coord, Enums.CellType.Current); var thisNeighbour = _vecinos.First(); _vecinos.Remove(thisNeighbour); // If the neighbour is the destination if (CoordsMatch(thisNeighbour, Destination)) { // Construct the path by tracing back through the closed list until there are no more parent id references Path = new List <Coord> { thisNeighbour }; int?parentId = NodoActual.Id; while (parentId.HasValue) { var nextNode = Closed.First(x => x.Id == parentId); Path.Add(nextNode.Coord); parentId = nextNode.ParentId; } // Reorder the path to be from origin to destination and return Path.Reverse(); return(GetSearchDetails()); } // Get the cost of the current node plus the extra step weight and heuristic var hFromHere = GetH(thisNeighbour, Destination); var cellWeight = Grid.GetCell(thisNeighbour.X, thisNeighbour.Y).Weight; var neighbourCost = NodoActual.G + cellWeight + hFromHere; // Check if the node is on the open list already and if it has a higher cost path var openListItem = _Listaabierta.FirstOrDefault(x => x.Id == GetExistingNode(true, thisNeighbour)); if (openListItem != null && openListItem.F > neighbourCost) { // Repoint the openlist node to use this lower cost path openListItem.F = neighbourCost; openListItem.ParentId = NodoActual.Id; } // Check if the node is on the closed list already and if it has a higher cost path var closedListItem = Closed.FirstOrDefault(x => x.Id == GetExistingNode(false, thisNeighbour)); if (closedListItem != null && closedListItem.F > neighbourCost) { // Repoint the closedlist node to use this lower cost path closedListItem.F = neighbourCost; closedListItem.ParentId = NodoActual.Id; } // If the neighbour node isn't on the open or closed list, add it if (openListItem != null || closedListItem != null) { return(GetSearchDetails()); } _Listaabierta.Add(new Nodo(Id++, NodoActual.Id, thisNeighbour, NodoActual.G + cellWeight, hFromHere)); Grid.SetCell(thisNeighbour.X, thisNeighbour.Y, Enums.CellType.Open); } else { Grid.SetCell(NodoActual.Coord, Enums.CellType.Closed); NodoActual = null; return(GetPathTick()); } return(GetSearchDetails()); }
private int?GetExistingNode(bool checkOpenList, Coord coordToCheck) { return(checkOpenList ? _Listaabierta.FirstOrDefault(x => CoordsMatch(x.Coord, coordToCheck))?.Id : Closed.FirstOrDefault(x => CoordsMatch(x.Coord, coordToCheck))?.Id); }