public override DetallesBusqueda MarcarRuta() { // Check the next node on the stack to see if it is the destination NodoActual = _stack.Peek(); if (CoordsMatch(NodoActual.Coord, Destino)) { // All the items on the stack will be the path so add them and reverse the order ruta = new List <Coord>(); foreach (var item in _stack) { ruta.Add(item.Coord); } ruta.Reverse(); return(detallesBusqueda()); } // Get all the neighbours that haven't been visited var neighbours = GetNeighbours(NodoActual).Where(x => !AlreadyVisited(new Coord(x.X, x.Y))).ToArray(); if (neighbours.Any()) { foreach (var neighbour in neighbours) { Cuadrilla.SetCell(neighbour.X, neighbour.Y, Enums.CellType.Abierto); } // Take this neighbour and add it the stack var next = neighbours.First(); var newNode = new Node(Id++, null, next.X, next.Y, 0, 0); _stack.Push(newNode); Cuadrilla.SetCell(newNode.Coord.X, newNode.Coord.Y, Enums.CellType.Actual); } else { // Remove this unused node from the stack and add it to the closed list var abandonedCell = _stack.Pop(); Cuadrilla.SetCell(abandonedCell.Coord.X, abandonedCell.Coord.Y, Enums.CellType.Cerrado); Cerrada.Add(abandonedCell); } return(detallesBusqueda()); }
public override DetallesBusqueda MarcarRuta() { if (NodoActual == null) { if (!_ListaAbierta.Any()) { return(detallesBusqueda()); } // utilizar el nodo actual de la lista abierta para examinarlo NodoActual = _ListaAbierta.OrderBy(x => x.F).ThenBy(x => x.H).First(); // mover a la lista cerrada para no ser examinado de nuevo _ListaAbierta.Remove(NodoActual); Cerrada.Add(NodoActual); Cuadrilla.SetCell(NodoActual.Coord, Enums.CellType.Cerrado); _Vecinos.AddRange(GetNeighbours(NodoActual)); } if (_Vecinos.Any()) { Cuadrilla.SetCell(NodoActual.Coord, Enums.CellType.Actual); var vecinoDestino = _Vecinos.First(); _Vecinos.Remove(vecinoDestino); // si el vecino es el destino if (CoordsMatch(vecinoDestino, Destino)) { // construir ruta en base a lista cerrada si se llego al destino ruta = new List <Coord> { vecinoDestino }; int?Idpariente = NodoActual.Id; while (Idpariente.HasValue) { var NodoSiguiente = Cerrada.First(x => x.Id == Idpariente); ruta.Add(NodoSiguiente.Coord); Idpariente = NodoSiguiente.ParentId; } // reordenar la ruta desde el origen al destino ruta.Reverse(); return(detallesBusqueda()); } // costo del nodo actual + el valor del paso anterior y heuristica var Hn = GetH(vecinoDestino, Destino); var CostoCelda = Cuadrilla.GetCell(vecinoDestino.X, vecinoDestino.Y).Valor; var CostoVecino = NodoActual.G + CostoCelda + Hn; // el nodo con menor valor en la lista abierta var ItemListaAbierta = _ListaAbierta.FirstOrDefault(x => x.Id == GetExistingNode(true, vecinoDestino)); if (ItemListaAbierta != null && ItemListaAbierta.F > CostoVecino) { // utilizo el nodo con menor costo en la lista para crear ruta ItemListaAbierta.F = CostoVecino; ItemListaAbierta.ParentId = NodoActual.Id; } var itemListaCerrada = Cerrada.FirstOrDefault(x => x.Id == GetExistingNode(false, vecinoDestino)); if (itemListaCerrada != null && itemListaCerrada.F > CostoVecino) { //menor costo en lista cerrada itemListaCerrada.F = CostoVecino; itemListaCerrada.ParentId = NodoActual.Id; } if (ItemListaAbierta != null || itemListaCerrada != null) { return(detallesBusqueda()); } _ListaAbierta.Add(new Node(Id++, NodoActual.Id, vecinoDestino, NodoActual.G + CostoCelda, Hn)); Cuadrilla.SetCell(vecinoDestino.X, vecinoDestino.Y, Enums.CellType.Abierto); } else { Cuadrilla.SetCell(NodoActual.Coord, Enums.CellType.Cerrado); NodoActual = null; return(MarcarRuta()); } return(detallesBusqueda()); }