Example #1
0
 private void ExpansionConDiagonales(Baldosa actual)
 {
     for (var i = -1; i <= 1; i++)
     {
         if (actual.Posicion.X + i >= 0 && actual.Posicion.X + i < Mapa.GetLength(0))
         {
             for (var j = -1; j <= 1; j++)
             {
                 if (actual.Posicion.Y + j >= 0 && actual.Posicion.Y + j < Mapa.GetLength(1))
                 {
                     if (Mapa[actual.Posicion.X + i, actual.Posicion.Y + j].Accesible)
                     {
                         if (!(Mapa[actual.Posicion.X + i, actual.Posicion.Y + j].Valor ==
                               (float)TiposBaldosa.Rio && !Nadar))
                         {
                             if (!(Mapa[actual.Posicion.X + i, actual.Posicion.Y + j].Valor ==
                                   (float)TiposBaldosa.Montaña && !Escalar))
                             {
                                 CostesYTratarNodos(actual, i, j);
                             }
                         }
                     }
                 }
             }
         }
     }
 }
Example #2
0
        private void NuevoTablero()
        {
            MainThread.BeginInvokeOnMainThread(() =>
            {
                Grid.Children.Clear();
                _inicio      = null;
                _fin         = null;
                _enEjecucion = false;
                _terminado   = false;

                for (var i = 0; i < _size.Y; i++)
                {
                    for (var j = 0; j < _size.X; j++)
                    {
                        var coordenadas = new Coordenadas(j, _size.Y - (i + 1));
                        var celda       = new Celda()
                        {
                            WidthRequest    = 5.0,
                            HeightRequest   = 5.0,
                            BackgroundColor = (Color)Application.Current.Resources["AltColor"],
                            Coordenadas     = coordenadas,
                            Aspect          = Aspect.AspectFit
                        };

                        celda.Clicked += Baldosa_Clicked;

                        _mapa[coordenadas.X, coordenadas.Y] = new Baldosa(coordenadas, celda);

                        Grid.Children.Add(celda, j, i);
                    }
                }
            });
        }
Example #3
0
        /// <summary>
        /// Calcula con el algoritmo A* el camino entre el inicio y la meta en el mapa proporcionado
        /// </summary>
        /// <param name="inicio">Coordenada de inicio</param>
        /// <param name="meta">Coordenada de llegada</param>
        /// <param name="movimientoDiagonal">Indica si se permite el movimiento lateral</param>
        /// <param name="movimientoOrtogonal"></param>
        /// <param name="mapa">Mapa en el que se ejecuta el algoritmo</param>
        /// <param name="wayPoints">Puntos intermedios por los que hay que pasar en orden</param>
        /// <returns>Objeto Resultado con el camino y el coste.</returns>
        public static AEstrellaResultado CalculoAEstrella(Baldosa inicio, Baldosa meta, bool movimientoDiagonal,
                                                          bool movimientoOrtogonal, Baldosa[,] mapa, params Baldosa[] wayPoints)
        {
            var resultado = new AEstrellaResultado(new List <Baldosa>(), 0);
            var puntos    = new Baldosa[wayPoints.Length + 2];

            var i = 0;

            puntos[i++] = inicio;
            for (; i <= wayPoints.Length; i++)
            {
                puntos[i] = wayPoints[i - 1];
            }

            puntos[i] = meta;

            i = 1;
            for (; i < puntos.Length; i++)
            {
                var aEstrella = new AEstrella(puntos[i - 1], puntos[i], movimientoDiagonal, movimientoOrtogonal,
                                              mapa);
                var parcial = aEstrella.Algoritmo();
                if (parcial.Camino == null)
                {
                    return(new AEstrellaResultado(mapa, null, 0.0));
                }

                resultado.Coste += parcial.Coste;
                resultado.Camino.AddRange(parcial.Camino);
                aEstrella.LimpiarListas(resultado.Camino);
            }

            return(resultado);
        }
Example #4
0
        /// <summary>
        /// Calcula con el algoritmo A* el camino entre el inicio y la meta en el mapa proporcionado
        /// </summary>
        /// <param name="inicio">Coordenada de inicio</param>
        /// <param name="meta">Coordenada de llegada</param>
        /// <param name="movimientoDiagonal">Indica si se permite el movimiento lateral</param>
        /// <param name="movimientoOrtogonal"></param>
        /// <param name="mapa">Mapa en el que se ejecuta el algoritmo</param>
        /// <returns>Objeto Resultado con el camino y el coste.</returns>
        public static AEstrellaResultado CalculoAEstrella(Baldosa inicio, Baldosa meta, bool movimientoDiagonal,
                                                          bool movimientoOrtogonal, Baldosa[,] mapa)
        {
            var aEstrella =
                new AEstrella(inicio, meta, movimientoDiagonal, movimientoOrtogonal, mapa);

            return(aEstrella.Algoritmo());
        }
Example #5
0
        /// <summary>
        /// Pasa el nodo a la lista abierta
        /// </summary>
        /// <param name="actual">Punto donde está el algoritmo</param>
        /// <param name="i">Incremento de la coordenada X</param>
        /// <param name="j">Incremento de la coordenada Y</param>
        /// <param name="coste">Coste del paso</param>
        private void NodoAAbierta(Baldosa actual, int i, int j, double coste)
        {
            Mapa[actual.Posicion.X + i, actual.Posicion.Y + j].Abierto = true;
            Mapa[actual.Posicion.X + i, actual.Posicion.Y + j].G       = Mapa[actual.Posicion.X, actual.Posicion.Y].G + coste;
            Mapa[actual.Posicion.X + i, actual.Posicion.Y + j].H       =
                Calculo.Distancia(Mapa[actual.Posicion.X + i, actual.Posicion.Y + j], Meta);
            Mapa[actual.Posicion.X + i, actual.Posicion.Y + j].Padre = Mapa[actual.Posicion.X, actual.Posicion.Y];

            Abierta.Enqueue(Mapa[actual.Posicion.X + i, actual.Posicion.Y + j],
                            Mapa[actual.Posicion.X + i, actual.Posicion.Y + j].F);
        }
Example #6
0
 /// <summary>
 /// Reorienta el enlace del nodo
 /// </summary>
 /// <param name="actual">Punto donde está el algoritmo</param>
 /// <param name="i">Incremento de la coordenada X</param>
 /// <param name="j">Incremento de la coordenada Y</param>
 /// <param name="coste">Coste del paso</param>
 private void ReorientacionEnlaces(Baldosa actual, int i, int j, double coste)
 {
     if (Mapa[actual.Posicion.X + i, actual.Posicion.Y + j].G >
         Mapa[actual.Posicion.X, actual.Posicion.Y].G + coste) // Si el coste es menor
     {
         Mapa[actual.Posicion.X + i, actual.Posicion.Y + j].G =
             Mapa[actual.Posicion.X, actual.Posicion.Y].G + coste;
         Mapa[actual.Posicion.X + i, actual.Posicion.Y + j].Padre = Mapa[actual.Posicion.X, actual.Posicion.Y];
         Abierta.UpdatePriority(Mapa[actual.Posicion.X + i, actual.Posicion.Y + j],
                                Mapa[actual.Posicion.X + i, actual.Posicion.Y + j].F);
     }
 }
Example #7
0
 internal AEstrella(Baldosa inicio, Baldosa meta, bool movimientoDiagonal, bool movimientoOrtogonal,
                    Baldosa[,] mapa)
 {
     Inicio              = inicio;
     Meta                = meta;
     Mapa                = mapa;
     Abierta             = new FastPriorityQueue <Baldosa>(mapa.Length);
     Nadar               = true;
     Escalar             = true;
     MovimientoDiagonal  = movimientoDiagonal;
     MovimientoOrtogonal = movimientoOrtogonal;
 }
Example #8
0
        /// <summary>
        /// Genera el camino resultado
        /// </summary>
        /// <param name="resultadoAlgoritmo">Punto donde acabael algoritmo</param>
        /// <param name="resultado">Objeto resultado</param>
        protected static void TratarCaminoResultado(Baldosa resultadoAlgoritmo, AEstrellaResultado resultado)
        {
            Baldosa actual = resultadoAlgoritmo;

            while (actual != null)
            {
                resultado.Camino.Add(actual);
                actual = actual.Padre;
            }

            resultado.Camino.Reverse();
        }
Example #9
0
        private void CostesYTratarNodos(Baldosa actual, int i, int j)
        {
            // Calculamos los costes de acceder
            double coste = Calculo.Distancia(Mapa[actual.Posicion.X, actual.Posicion.Y],
                                             Mapa[actual.Posicion.X + i, actual.Posicion.Y + j]);

            if (Mapa[actual.Posicion.X + i, actual.Posicion.Y + j].Abierto == true) // Actualizamos la lista abierta
            {
                ReorientacionEnlaces(actual, i, j, coste);
            }
            else if (Mapa[actual.Posicion.X + i, actual.Posicion.Y + j].Abierto == null) // Agregamos a la lista abierta
            {
                NodoAAbierta(actual, i, j, coste);
            }
        }
Example #10
0
        /// <summary>
        /// Ejecución del algoritmo
        /// </summary>
        /// <returns>Punto del mapa al que se llega</returns>
        private Baldosa CalculoAlgoritmo()
        {
            Baldosa resultado = null;
            var     salir     = false;

            while (!salir)
            {
                if (Abierta.Count == 0)
                {
                    salir = true;
                }
                else
                {
                    var actual = Abierta.Dequeue();

                    //Cerramos el nodo
                    actual.Abierto = false;
                    MainThread.BeginInvokeOnMainThread(() => { actual.Celda.BackgroundColor = Color.Teal; });

                    if (actual.Posicion.Equals(Meta.Posicion))
                    {
                        resultado = Mapa[Meta.Posicion.X, Meta.Posicion.Y];
                        salir     = true;
                    }
                    else
                    {
                        // Expansion del punto actual
                        if (MovimientoDiagonal && MovimientoOrtogonal)
                        {
                            ExpansionConDiagonales(actual);
                        }
                        else
                        {
                            if (MovimientoOrtogonal)
                            {
                                ExpansionOrtogonal(actual);
                            }
                            if (MovimientoDiagonal)
                            {
                                ExpansionDiagonal(actual);
                            }
                        }
                    }
                }
            }

            return(resultado);
        }
Example #11
0
        /// <summary>
        /// Trata y genera la solución del algoritmo
        /// </summary>
        /// <param name="resultadoAlgoritmo">Punto del mapa al que se llega</param>
        /// <returns>Objeto con el camino y el coste asociado</returns>
        protected AEstrellaResultado ProcesarResultado(Baldosa resultadoAlgoritmo)
        {
            AEstrellaResultado resultado;

            if (resultadoAlgoritmo == null)
            {
                resultado = new AEstrellaResultado(Mapa, null, 0.0);
            }
            else
            {
                resultado = new AEstrellaResultado(Mapa, new List <Baldosa>(), resultadoAlgoritmo.F);
                TratarCaminoResultado(resultadoAlgoritmo, resultado);
            }

            return(resultado);
        }
Example #12
0
        private void ExpansionOrtogonal(Baldosa actual)
        {
            for (var i = -1; i <= 1; i += 2)
            {
                if (actual.Posicion.X + i >= 0 && actual.Posicion.X + i < Mapa.GetLength(0))
                {
                    if (Mapa[actual.Posicion.X + i, actual.Posicion.Y].Accesible)
                    {
                        CostesYTratarNodos(actual, i, 0);
                    }
                }

                if (actual.Posicion.Y + i >= 0 && actual.Posicion.Y + i < Mapa.GetLength(1))
                {
                    if (Mapa[actual.Posicion.X, actual.Posicion.Y + i].Accesible)
                    {
                        CostesYTratarNodos(actual, 0, i);
                    }
                }
            }
        }
Example #13
0
        private void ExpansionDiagonal(Baldosa actual)
        {
            for (int i = -1; i <= 1; i += 2)
            {
                if ((actual.Posicion.X + i >= 0 && actual.Posicion.X + i < Mapa.GetLength(0)) &&
                    (actual.Posicion.Y + i >= 0 && actual.Posicion.Y + i < Mapa.GetLength(1)))
                {
                    if (Mapa[actual.Posicion.X + i, actual.Posicion.Y + i].Accesible)
                    {
                        CostesYTratarNodos(actual, 0 + i, 0 + i);
                    }
                }

                if ((actual.Posicion.X + i >= 0 && actual.Posicion.X + i < Mapa.GetLength(0)) &&
                    (actual.Posicion.Y - i >= 0 && actual.Posicion.Y - i < Mapa.GetLength(1)))
                {
                    if (Mapa[actual.Posicion.X + i, actual.Posicion.Y - i].Accesible)
                    {
                        CostesYTratarNodos(actual, 0 + i, 0 - i);
                    }
                }
            }
        }
Example #14
0
        private async Task AsignarTipoBaldosa(Celda celda)
        {
            switch (TipoBaldosa.SelectedIndex)
            {
            case 0:     // Inicio
                if (_fin != null && celda.Coordenadas.Equals(_fin.Celda.Coordenadas))
                {
                    MainThread.BeginInvokeOnMainThread(() => { _fin.Celda.Source = ""; });
                    _fin = null;
                }

                if (_inicio != null)
                {
                    MainThread.BeginInvokeOnMainThread(() => { _inicio.Celda.Source = ""; });
                }

                MainThread.BeginInvokeOnMainThread(() => { celda.Source = "Inicio"; });

                _inicio = _mapa[celda.Coordenadas.X, celda.Coordenadas.Y];
                _mapa[celda.Coordenadas.X, celda.Coordenadas.Y].Accesible = true;
                _mapa[celda.Coordenadas.X, celda.Coordenadas.Y].Valor     = 0;

                break;

            case 1:     // Fin
                if (_inicio != null && celda.Coordenadas.Equals(_inicio.Celda.Coordenadas))
                {
                    MainThread.BeginInvokeOnMainThread(() => { _inicio.Celda.Source = ""; });
                    _inicio = null;
                }

                if (_fin != null)
                {
                    MainThread.BeginInvokeOnMainThread(() => { _fin.Celda.Source = ""; });
                }

                MainThread.BeginInvokeOnMainThread(() => { celda.Source = "Fin"; });

                _fin = _mapa[celda.Coordenadas.X, celda.Coordenadas.Y];
                _mapa[celda.Coordenadas.X, celda.Coordenadas.Y].Accesible = true;
                _mapa[celda.Coordenadas.X, celda.Coordenadas.Y].Valor     = 0;

                break;

            case 2:     // Perro - No accesible
                if (_inicio != null && celda.Coordenadas.Equals(_inicio.Celda.Coordenadas))
                {
                    MainThread.BeginInvokeOnMainThread(() => { _inicio.Celda.Source = ""; });
                    _inicio = null;
                }
                else if (_fin != null && celda.Coordenadas.Equals(_fin.Celda.Coordenadas))
                {
                    MainThread.BeginInvokeOnMainThread(() => { _fin.Celda.Source = ""; });
                    _fin = null;
                }

                if (_mapa[celda.Coordenadas.X, celda.Coordenadas.Y].Accesible)
                {
                    MainThread.BeginInvokeOnMainThread(() => { celda.Source = "Perro"; });
                    _mapa[celda.Coordenadas.X, celda.Coordenadas.Y].Accesible = false;
                }
                else
                {
                    MainThread.BeginInvokeOnMainThread(() => { celda.Source = ""; });
                    _mapa[celda.Coordenadas.X, celda.Coordenadas.Y].Accesible = true;
                }

                _mapa[celda.Coordenadas.X, celda.Coordenadas.Y].Valor = 0;

                break;

            case 3:     // Montaña
                if (_inicio != null && celda.Coordenadas.Equals(_inicio.Celda.Coordenadas))
                {
                    MainThread.BeginInvokeOnMainThread(() => { _inicio.Celda.Source = ""; });
                    _inicio = null;
                }
                else if (_fin != null && celda.Coordenadas.Equals(_fin.Celda.Coordenadas))
                {
                    MainThread.BeginInvokeOnMainThread(() => { _fin.Celda.Source = ""; });
                    _fin = null;
                }

                if (_mapa[celda.Coordenadas.X, celda.Coordenadas.Y].Valor == (double)TiposBaldosa.Montaña)
                {
                    MainThread.BeginInvokeOnMainThread(() => { celda.Source = ""; });
                    _mapa[celda.Coordenadas.X, celda.Coordenadas.Y].Valor = 0;
                }
                else
                {
                    MainThread.BeginInvokeOnMainThread(() => { celda.Source = "Montana"; });
                    _mapa[celda.Coordenadas.X, celda.Coordenadas.Y].Valor = (double)TiposBaldosa.Montaña;
                }

                _mapa[celda.Coordenadas.X, celda.Coordenadas.Y].Accesible = true;

                break;

            case 4:     // Río
                if (_inicio != null && celda.Coordenadas.Equals(_inicio.Celda.Coordenadas))
                {
                    MainThread.BeginInvokeOnMainThread(() => { _inicio.Celda.Source = ""; });
                    _inicio = null;
                }
                else if (_fin != null && celda.Coordenadas.Equals(_fin.Celda.Coordenadas))
                {
                    MainThread.BeginInvokeOnMainThread(() => { _fin.Celda.Source = ""; });
                    _fin = null;
                }

                if (_mapa[celda.Coordenadas.X, celda.Coordenadas.Y].Valor == (double)TiposBaldosa.Rio)
                {
                    MainThread.BeginInvokeOnMainThread(() => { celda.Source = ""; });
                    _mapa[celda.Coordenadas.X, celda.Coordenadas.Y].Valor = 0;
                }
                else
                {
                    MainThread.BeginInvokeOnMainThread(() => { celda.Source = "Rio"; });
                    _mapa[celda.Coordenadas.X, celda.Coordenadas.Y].Valor = (double)TiposBaldosa.Rio;
                }

                _mapa[celda.Coordenadas.X, celda.Coordenadas.Y].Accesible = true;

                break;

            default:
                await DisplayAlert("Error",
                                   "Tipo no implementado, perdone las molestias",
                                   "OK");

                break;
            }
        }
Example #15
0
 public static double Distancia(Baldosa a, Baldosa b)
 {
     return(Math.Sqrt(Math.Pow(a.Posicion.X - b.Posicion.X, 2) + Math.Pow(a.Posicion.Y - b.Posicion.Y, 2)));
 }