Beispiel #1
0
        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());
        }