示例#1
0
        /*
         * // Para copiar el puzle con el que este trabajando otro resolutor... raro
         * public TankPuzzleSolver(TankPuzzleSolver copyBoard) : this(copyBoard.getPuzle()) {
         *
         * }
         */


        // A ver si esto tiene que estar aquí o puede ser otra cosa (en el propio TankPuzzleManager)
        public List <Operator> Solve(TankPuzzle setup, TankPuzzleSolver.Strategy strategy)
        {
            // Construimos el problema a partir del puzle.
            //Pieza a pieza (el puzle tal cual será el initialSetup -lo mismo debería sacar el array-)



            //Aquí construimos el problema en base al puzle actual (la CONFIGURACIÓN del puzle actual), que no me gusta como es porque es el puzle con unas pocas cosas por encima!!! El dominio de problema no es un objeto
            Problem problem = new Problem(setup, oFunction, rFunction, goalTest); //Me molaría más que el problema no sea el solver, sino el puzle... pero bueno, quizá sea PROBLEM lo que debería llamarse el solver
            //public Problem(Object initialSetup, OperatorsFunction operatorsFunction, ResultFunction resultFunction, GoalTest goalTest)

            // AQUÍ CREARÍAMOS LA ESTRATEGIA, EL TIPO DE BÚSQUEDA, pidiéndole que use búsqueda de coste uniforme por ejemplo. Y lo llamamos

            Search search = null;

            switch (strategy)
            {
            case Strategy.BFS: search = new BreadthFirstSearch(); break;                //por defecto te crea un GraphSearch, no hay que meterle nada

            case Strategy.DFS: search = new DepthFirstSearch(new GraphSearch()); break; // NO ENTIENDO PORQUE ESTE CONSTRUCTOR NO TE HACE NADA POR DEFECTO, Y SOY YO QUE LE ESTOY METIENDO UN GRAPHSEARCH
                // ...
            }
            List <Operator> operators = search.Search(problem);

            metrics = search.GetMetrics();

            return(operators); // Deberíamos devolver también las métricas, seguramente
        }
示例#2
0
        public void Initialize(TankPuzzle puzzle)
        {
            if (puzzle == null)
            {
                throw new ArgumentNullException(nameof(puzzle));
            }

            if (casillas == null)
            {
                casillas = new Casilla[puzzle.rows, puzzle.columns];

                transform.localScale = new Vector3(SCALE_FACTOR_C * casillas.GetLength(1),
                                                   transform.localScale.y, SCALE_FACTOR_R * casillas.GetLength(0));
            }
            else if (casillas.GetLength(0) != puzzle.rows || casillas.GetLength(1) != puzzle.columns)
            {
                DestroyCasillas();
                casillas = new Casilla[puzzle.rows, puzzle.columns];

                transform.localScale = new Vector3(SCALE_FACTOR_C * casillas.GetLength(1),
                                                   transform.localScale.y, SCALE_FACTOR_R * casillas.GetLength(0));
            }

            GenerateCasillas(puzzle);
        }
示例#3
0
            public object GetResult(object setup, Operator op)
            {
                // Lo recibido es un puzle deslizante
                TankPuzzle puzzle = (TankPuzzle)setup;
                // Un puzle deslizante se puede clonar a nivel profundo
                TankPuzzle puzzleClone = puzzle.DeepClone();


                /*if (TankPuzzleSolver.UP.Equals(op))
                 *  if (puzzleClone.CanMoveUp(puzzleClone.TankPosition))
                 *      puzzleClone.MoveUp(puzzleClone.TankPosition);
                 *  else // No puede ocurrir que el operador aplicable no funcione, porque ya se comprobó que era aplicable
                 *      throw new InvalidOperationException("This operator is not working propertly");
                 *
                 * if (TankPuzzleSolver.DOWN.Equals(op))
                 *  if (puzzleClone.CanMoveDown(puzzleClone.TankPosition))
                 *      puzzleClone.MoveDown(puzzleClone.TankPosition);
                 *  else // No puede ocurrir que el operador aplicable no funcione, porque ya se comprobó que era aplicable
                 *      throw new InvalidOperationException("This operator is not working propertly");
                 *
                 * if (TankPuzzleSolver.LEFT.Equals(op))
                 *  if (puzzleClone.CanMoveLeft(puzzleClone.TankPosition))
                 *      puzzleClone.MoveLeft(puzzleClone.TankPosition);
                 *  else // No puede ocurrir que el operador aplicable no funcione, porque ya se comprobó que era aplicable
                 *      throw new InvalidOperationException("This operator is not working propertly");
                 *
                 * if (TankPuzzleSolver.RIGHT.Equals(op))
                 *  if (puzzleClone.CanMoveRight(puzzleClone.TankPosition))
                 *      puzzleClone.MoveRight(puzzleClone.TankPosition);
                 *  else // No puede ocurrir que el operador aplicable no funcione, porque ya se comprobó que era aplicable
                 *      throw new InvalidOperationException("This operator is not working propertly");*/

                // Si el operador no se reconoce o es un NoOp, se devolverá la configuración actual (que sería idéntica a la original, no ha habido cambios)
                return(puzzleClone);
            }
示例#4
0
        // Inicializa o reinicia el gestor
        private void Initialize(uint rows, uint columns)
        {
            if (tablero == null)
            {
                throw new InvalidOperationException("The board reference is null");
            }
            if (tank == null)
            {
                throw new InvalidOperationException("The board reference is null");
            }
            if (timeNumber == null)
            {
                throw new InvalidOperationException("The timeNumber reference is null");
            }
            if (stepsNumber == null)
            {
                throw new InvalidOperationException("The stepsNumber reference is null");
            }
            if (rowsInput == null)
            {
                throw new InvalidOperationException("The rowsInputText reference is null");
            }
            if (columnsInput == null)
            {
                throw new InvalidOperationException("The columnsInputText reference is null");
            }

            this.rows         = rows;
            this.columns      = columns;
            rowsInput.text    = rows.ToString();
            columnsInput.text = columns.ToString();

            // Se crea el puzle internamente (matriz logica)
            puzzle = new TankPuzzle(rows, columns);

            // Se inicializa todo el tablero de casillas (representacion visual a partir de la matriz logica)
            tablero.Initialize(puzzle);

            // Se crea el tanque
            tank.Initialize();

            // se crea el grafo a partir de la matriz logica
            CreateGraph();

            flag.transform.position = IniPosFlag;

            // GUI
            CleanInfo();
            UpdateInfo();
        }
示例#5
0
        // restablece las casillas del tablero a sus parametros iniciales, asi como la matriz logica
        public void ResetTablero(TankPuzzle puzzle)
        {
            var rows    = casillas.GetLength(0);
            var columns = casillas.GetLength(1);

            for (var r = 0u; r < rows; r++)
            {
                for (var c = 0u; c < columns; c++)
                {
                    puzzle.SetType((int)r, (int)c, casillas[r, c].getInitialType());
                    casillas[r, c].Reset();
                }
            }
            puzzle.TankPosition = puzzle.InitialTankPosition;
        }
示例#6
0
            // SUSTITUÍ EL LINKEDHASHSET DE JAVA POR HASHSET SOLAMENTE... SE ME HACE RARO QUE SE DEVUELVA UN HASHSET, LO NORMAL SERÍA UNA LIST, Y POR DENTRO IMPLEMENTAR CON ARRAYLIST O ALGO
            public HashSet <Operator> Operators(object setup)
            {
                // Lo que entra es un problema, un TankPuzzle
                TankPuzzle puzzle = (TankPuzzle)setup;

                HashSet <Operator> operators = new HashSet <Operator>();

                // Esto se lee: Puedo mover el hueco hacia arriba, o puedo mover la pieza de arriba del hueco

                /*if (puzzle.CanMoveUp(puzzle.TankPosition))
                 *  operators.Add(TankPuzzleSolver.UP);
                 * if (puzzle.CanMoveDown(puzzle.TankPosition))
                 *  operators.Add(TankPuzzleSolver.DOWN);
                 * if (puzzle.CanMoveLeft(puzzle.TankPosition))
                 *  operators.Add(TankPuzzleSolver.LEFT);
                 * if (puzzle.CanMoveRight(puzzle.TankPosition))
                 *  operators.Add(TankPuzzleSolver.RIGHT);*/

                return(operators);
            }
示例#7
0
        // genera las casillas del tipo que le indique puzzle (matriz logica de tipos)
        private void GenerateCasillas(TankPuzzle puzzle)
        {
            if (puzzle == null)
            {
                throw new ArgumentNullException(nameof(puzzle));
            }

            var rows    = casillas.GetLength(0);
            var columns = casillas.GetLength(1);

            bool tankInitialized = false;

            for (int r = 0; r < rows; r++)
            {
                for (int c = 0; c < columns; c++)
                {
                    Casilla casilla = casillas[r, c];
                    if (casilla == null)
                    {
                        casilla = Instantiate(casillaPrefab, new Vector3(-((casillas.GetLength(1) / 2.0f) * POSITION_FACTOR_C - (POSITION_FACTOR_C / 2.0f)) + c * POSITION_FACTOR_C, 0,
                                                                         (casillas.GetLength(0) / 2.0f) * POSITION_FACTOR_R - (POSITION_FACTOR_R / 2.0f) - r * POSITION_FACTOR_R),
                                              Quaternion.identity);

                        casillas[r, c] = casilla;
                    }

                    casilla.position = new Position((uint)r, (uint)c);
                    casilla.Initialize(this, (uint)puzzle.GetType(r, c));

                    if (!tankInitialized && puzzle.GetType(r, c) == 0)
                    {
                        GameManager.instance.setTankPosition(casilla.transform.position);
                        puzzle.InitialTankPosition = casilla.position;
                        puzzle.TankPosition        = puzzle.InitialTankPosition;
                        tankInitialized            = true;
                    }
                }
            }
        }
示例#8
0
        // Devuelve la posición que se ve afectada por este operador (la que se movería si lo aplicásemos)
        public Position GetOperatedPosition(TankPuzzle puzzle, Operator op)
        {
            // Fallar si no es aplicable con throw new InvalidOperationException("This operator is not working propertly");

            if (TankPuzzleSolver.UP.Equals(op))
            {
                return(puzzle.TankPosition.Up());
            }
            if (TankPuzzleSolver.DOWN.Equals(op))
            {
                return(puzzle.TankPosition.Down());
            }
            if (TankPuzzleSolver.LEFT.Equals(op))
            {
                return(puzzle.TankPosition.Left());
            }
            if (TankPuzzleSolver.RIGHT.Equals(op))
            {
                return(puzzle.TankPosition.Right());
            }

            // Si el operador no se entiendo o es NoOp vamos a devolver el propio hueco, por ejemplo
            return(puzzle.TankPosition);
        }
示例#9
0
        TankPuzzle goal = new TankPuzzle(); // El Tank puzle por defecto es el inicial

        // Yo haría que preguntase por el TankPuzle... no por el TankPuzleSolver
        public bool IsGoalSetup(object setup)
        {
            TankPuzzle puzzle = (TankPuzzle)setup;

            return(puzzle.Equals(goal));
        }