예제 #1
0
        /// <summary>
        /// Find the coords that are above, below, left, and right of the current cell, assuming they are valid
        /// </summary>
        /// <param name="current"></param>
        /// <returns>The valid coords around the current cell</returns>
        protected virtual IEnumerable <Coord> GetNeighbours(Node current)
        {
            var neighbours = new List <Cell>
            {
                Cuadrilla.GetCell(current.Coord.X - 1, current.Coord.Y),
                Cuadrilla.GetCell(current.Coord.X + 1, current.Coord.Y),
                Cuadrilla.GetCell(current.Coord.X, current.Coord.Y - 1),
                Cuadrilla.GetCell(current.Coord.X, current.Coord.Y + 1)
            };

            return(neighbours.Where(x => x.Tipo != Enums.CellType.Invalido && x.Tipo != Enums.CellType.Solido).Select(x => x.Coord).ToArray());
        }
예제 #2
0
        /// <summary>
        /// Get the cost of the path between A and B
        /// </summary>
        /// <returns>Cost of the path or 0 if no path has been found</returns>
        protected int GetPathCost()
        {
            if (Ruta == null)
            {
                return(0);
            }

            var cost = 0;

            foreach (var step in Ruta)
            {
                cost += Cuadrilla.GetCell(step.X, step.Y).Weight;
            }

            return(cost);
        }
예제 #3
0
        public void Dibujar()
        {
            _cellWidth  = _pb.Width / Horizontales;
            _cellHeight = _pb.Height / Verticales;

            var image = new Bitmap(_pb.Width, _pb.Height);

            using (var g = Graphics.FromImage(image))
            {
                var background = new Rectangle(0, 0, image.Width, image.Height);
                g.FillRectangle(new SolidBrush(Color.White), background);

                for (var x = 0; x < Horizontales; x++)
                {
                    for (var y = 0; y < Verticales; y++)
                    {
                        var cell = Cuadrilla.GetCell(x, y);
                        switch (cell.Tipo)
                        {
                        case CellType.Vacio:
                            switch (cell.Valor)
                            {
                            case 2: g.FillRectangle(Brushes.White, GetRectangle(x, y)); break;

                            case 3: g.FillRectangle(Brushes.White, GetRectangle(x, y)); break;
                            }
                            break;

                        case CellType.Solido:
                            g.FillRectangle(Brushes.Black, GetRectangle(x, y));
                            break;

                        case CellType.Camino:
                            g.FillRectangle(Brushes.Red, GetRectangle(x, y));
                            break;

                        case CellType.Abierto:
                            g.FillRectangle(Brushes.LightSkyBlue, GetRectangle(x, y));
                            break;

                        case CellType.Cerrado:
                            g.FillRectangle(Brushes.LightSeaGreen, GetRectangle(x, y));
                            break;

                        case CellType.Actual:
                            g.FillRectangle(Brushes.Red, GetRectangle(x, y));
                            break;

                        case CellType.A:
                            g.DrawString("->", GetFont(), Brushes.Red, GetPoint(x, y));
                            break;

                        case CellType.B:
                            g.DrawString("->", GetFont(), Brushes.Red, GetPoint(x, y));
                            break;

                        default:
                            throw new ArgumentOutOfRangeException("Unknown cell type: " + cell);
                        }

                        g.DrawRectangle(Pens.Black, GetRectangle(x, y));
                    }
                }

                _pb.Image = image;
            }
        }
예제 #4
0
        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());
        }