Ejemplo n.º 1
0
        /// <summary>
        /// Funcion que realiza la búsqueda de los resultados de la arena pokémon
        /// </summary>
        /// <typeparam name="T">Tipo del formato del resultado obtenido</typeparam>
        /// <param name="pkmnNames">Listado de los nombres de pokémon</param>
        /// <param name="mapíngFunc">Función que mapea el resutlado de la búsqueda al formato especificado</param>
        /// <returns></returns>
        private T ArenaSearch <T>(List <string> pkmnNames,
                                  Func <Queue <ISearchable <string> >, double, string, string, T> mapíngFunc)
        {
            if (pkmnNames.Count <= 1)
            {
                throw new OperationFailedException("No hay pokémones suficientes para iniciar el torneo. 🤔",
                                                   OperationErrorStatus.MalformedInput);
            }

            var initialState = _factoryService.CreateViewModel(pkmnNames, true);
            var goalState    = _factoryService.CreateViewModel(pkmnNames);

            var goalStatePkmDict    = goalState.PkmnPositions;
            var initialStatePkmDict = initialState.PkmnPositions;

            foreach (var key in initialStatePkmDict.Keys)
            {
                var distance = initialStatePkmDict[key].Item1 - goalStatePkmDict[key].Item1;

                // Si la distancia, menos 2, es positiva
                // es imposible que ese estado sea un candidato
                // por tanto, la búsqueda no tendrá un resultado
                if (distance - 2 > 0)
                {
                    throw new OperationFailedException("¡Vaya! Parece que los resultados entregados no son posibles, de acuerdo a las reglas del torneo. 🤔",
                                                       OperationErrorStatus.MalformedInput);
                }
            }

            var searchEngine = new AStarSearchEngine <string>(initialState, goalState, (pkCollection) =>
            {
                var pkDict            = (pkCollection as PokemonRankViewModel).PkmnPositions;
                double heuristicValue = 0;
                foreach (var key in pkDict.Keys)
                {
                    // Se obtiene la distancia entre los pokémon
                    var distance = pkDict[key].Item1 - goalStatePkmDict[key].Item1;

                    // Si la distancia, menos 2, es positiva
                    // es imposible que ese estado sea un candidato
                    // por tanto se marca para no ser incluído en la búsqueda
                    if (distance - 2 > 0)
                    {
                        return(double.MinValue);
                    }


                    // Si la distancia es mayor que 0, y el pokémon no puede pelear,
                    // se penaliza el valor de la heurística por 1000
                    // de lo contrario se retorna la distancia obtenida / 2
                    heuristicValue += Math.Abs(distance) != 0 && !pkDict[key].Item2
                    ? 1000
                    : (Math.Abs(distance) / 2.0);
                }
                return(heuristicValue);
            }, false);
            var searchResult = searchEngine.ShortestPathSearch();

            if (searchResult.Count == 0)
            {
                throw new OperationFailedException("¡Vaya! Parece que los resultados entregados no son posibles, de acuerdo a las reglas del torneo. 🤔",
                                                   OperationErrorStatus.MalformedInput);
            }

            return(mapíngFunc(searchResult, searchEngine.ElapsedSearchTime, initialState.Id, goalState.Id));
        }
Ejemplo n.º 2
0
        static void Main(string[] args)
        {
            //var initialState = new DummyPkmnCollection(new List<Tuple<int, string, int>> {
            //    new Tuple<int, string, int>(1, "A", 2),
            //    new Tuple<int, string, int>(2, "B", 2),
            //    new Tuple<int, string, int>(3, "C", 2),
            //    new Tuple<int, string, int>(4, "D", 2),
            //    new Tuple<int, string, int>(5, "E", 2),
            //    new Tuple<int, string, int>(6, "E", 2),
            //    new Tuple<int, string, int>(7, "E", 2),
            //    new Tuple<int, string, int>(8, "E", 2),
            //    new Tuple<int, string, int>(9, "E", 2),
            //    new Tuple<int, string, int>(10, "E", 2),
            //    new Tuple<int, string, int>(11, "A", 2),
            //    new Tuple<int, string, int>(12, "B", 2),
            //    new Tuple<int, string, int>(13, "C", 2),
            //    new Tuple<int, string, int>(14, "D", 2),
            //    new Tuple<int, string, int>(15, "E", 2),
            //    new Tuple<int, string, int>(16, "E", 2),
            //    new Tuple<int, string, int>(17, "E", 2),
            //    new Tuple<int, string, int>(18, "E", 2),
            //    new Tuple<int, string, int>(19, "E", 2),
            //    new Tuple<int, string, int>(20, "E", 2),
            //    new Tuple<int, string, int>(21, "A", 2),
            //    new Tuple<int, string, int>(22, "B", 2),
            //    new Tuple<int, string, int>(23, "C", 2),
            //    new Tuple<int, string, int>(24, "D", 2),
            //    new Tuple<int, string, int>(25, "E", 2),
            //    new Tuple<int, string, int>(26, "E", 2),
            //    new Tuple<int, string, int>(27, "E", 2),
            //    new Tuple<int, string, int>(28, "E", 2),
            //    new Tuple<int, string, int>(29, "E", 2),
            //    new Tuple<int, string, int>(30, "E", 2)
            //}, 0, "");

            //var goalState = new DummyPkmnCollection(new List<Tuple<int, string, int>> {
            //    new Tuple<int, string, int>(1, "A", 2),
            //    new Tuple<int, string, int>(2, "B", 2),
            //    new Tuple<int, string, int>(3, "C", 2),
            //    new Tuple<int, string, int>(5, "E", 2),
            //    new Tuple<int, string, int>(4, "D", 2),
            //    new Tuple<int, string, int>(7, "E", 2),
            //    new Tuple<int, string, int>(6, "E", 2),
            //    new Tuple<int, string, int>(9, "E", 2),
            //    new Tuple<int, string, int>(8, "E", 2),
            //    new Tuple<int, string, int>(10, "E", 2),
            //    new Tuple<int, string, int>(11, "A", 2),
            //    new Tuple<int, string, int>(12, "B", 2),
            //    new Tuple<int, string, int>(13, "C", 2),
            //    new Tuple<int, string, int>(14, "D", 2),
            //    new Tuple<int, string, int>(15, "E", 2),
            //    new Tuple<int, string, int>(17, "E", 2),
            //    new Tuple<int, string, int>(16, "E", 2),
            //    new Tuple<int, string, int>(18, "E", 2),
            //    new Tuple<int, string, int>(19, "E", 2),
            //    new Tuple<int, string, int>(20, "E", 2),
            //    new Tuple<int, string, int>(21, "A", 2),
            //    new Tuple<int, string, int>(22, "B", 2),
            //    new Tuple<int, string, int>(23, "C", 2),
            //    new Tuple<int, string, int>(25, "E", 2),
            //    new Tuple<int, string, int>(24, "D", 2),
            //    new Tuple<int, string, int>(26, "E", 2),
            //    new Tuple<int, string, int>(27, "E", 2),
            //    new Tuple<int, string, int>(28, "E", 2),
            //    new Tuple<int, string, int>(29, "E", 2),
            //    new Tuple<int, string, int>(30, "E", 2)
            //}, 0, "");

            //var initialState = new DummyPkmnCollection(new List<Tuple<int, string, int>> {
            //    new Tuple<int, string, int>(1, "Bullbasasur", 2),
            //    new Tuple<int, string, int>(4, "Charmander", 2),
            //    new Tuple<int, string, int>(7, "Squirtle", 2),
            //    new Tuple<int, string, int>(10, "Caterpie", 2),
            //    new Tuple<int, string, int>(16, "Pidgey", 2),
            //}, 0, "");

            //var goalState = new DummyPkmnCollection(new List<Tuple<int, string, int>> {
            //    new Tuple<int, string, int>(7, "Squirtle", 2),
            //    new Tuple<int, string, int>(1, "Bullbasasur", 2),
            //    new Tuple<int, string, int>(4, "Charmander", 2),
            //    new Tuple<int, string, int>(10, "Caterpie", 2),
            //    new Tuple<int, string, int>(16, "Pidgey", 2),
            //}, 0, "");


            var initialState = new DummyPkmnCollection(new List <Tuple <int, string, int> > {
                new Tuple <int, string, int>(1, "Bullbasasur", 2),
                new Tuple <int, string, int>(4, "Charmander", 2),
            }, 0, "");

            var goalState = new DummyPkmnCollection(new List <Tuple <int, string, int> > {
                new Tuple <int, string, int>(4, "Charmander", 2),
                new Tuple <int, string, int>(1, "Bullbasasur", 2),
            }, 0, "");

            var goalStatePkmDict = goalState.PkmnPositions;

            var searchEngine = new AStarSearchEngine <string>(initialState, goalState, (pkCollection) =>
            {
                var pkDict = (pkCollection as DummyPkmnCollection).PkmnPositions;
                var score  = 0;
                foreach (var key in pkDict.Keys)
                {
                    score += Math.Abs(pkDict[key] - goalStatePkmDict[key]);
                }
                return(score / 2);
            }, false);
            var results = searchEngine.ShortestPathSearch();

            if (results != null && results.Count > 0)
            {
                Console.WriteLine($"Movement count: {results.Count - 1}");
                Console.WriteLine();
                while (results.Count > 0)
                {
                    Console.WriteLine($"Step: {results.Count - 1}: {results.Dequeue().Id}");
                }
                Console.WriteLine();
                Console.WriteLine($"total extensions: {searchEngine.ExtensionsCount}");
                Console.WriteLine($"total elapsed time: {searchEngine.ElapsedSearchTime}ms");
            }
            else
            {
                Console.WriteLine($"total extensions: {searchEngine.ExtensionsCount}");
                Console.WriteLine($"The search yielded no results");
            }


            Console.ReadKey();
        }