Beispiel #1
0
        // Mueve un bloque en el tablero, devolviendo el otro bloque que ahora pasa a ocupar el lugar de este
        // Si no se puede realizar el movimiento, da fallo
        public MovableBlock Move(MovableBlock block, float delay)
        {
            if (block == null)
            {
                throw new ArgumentNullException(nameof(block));
            }
            if (!CanMove(block))
            {
                throw new InvalidOperationException("The required movement is not possible");
            }

            Debug.Log(ToString() + " moves " + block.ToString() + ".");

            // Intercambio de valores entre las dos posiciones de la matriz de bloques?
            MovableBlock otherBlock = manager.Move(block);

            // Ya ha cambiado el puzle, y mi posición lógica (y la del hueco -otherBlock-)... faltan las posiciones físicas en la escena y ubicaciones en la matriz de bloques de ambos

            // Cambio la ubicación en la matriz del bloque auxiliar para que sea la correcta
            blocks[otherBlock.position.GetRow(), otherBlock.position.GetColumn()] = otherBlock;
            // Cambio la ubicación en la matriz del bloque resultante para que sea la correcta
            blocks[block.position.GetRow(), block.position.GetColumn()] = block;

            // Los meto en la lista para que se muevan cuando corresponda...
            blocksInMotion.Enqueue(block);
            blocksInMotion.Enqueue(otherBlock);
            // Debería meter el delay o marcar de alguna manera si el movimiento es de humano o máquina

            return(otherBlock);
        }
Beispiel #2
0
        // Mueve un bloque, según las normas que diga el gestor
        public MovableBlock Move(MovableBlock block)
        {
            if (block == null)
            {
                throw new ArgumentNullException(nameof(block));
            }
            if (!CanMove(block))
            {
                throw new InvalidOperationException("The required movement is not possible");
            }

            Position originPosition = block.position;

            Debug.Log(ToString() + " moves " + block.ToString() + ".");
            var targetPosition = puzzle.MoveByDefault(block.position);

            // Si hemos tenido éxito ha cambiado la matrix lógica del puzle... pero no ha cambiado la posición (lógica), ni la mía ni la del hueco. Toca hacerlo ahora
            block.position = targetPosition;
            MovableBlock targetBlock = board.GetBlock(targetPosition);

            targetBlock.position = originPosition;

            UpdateInfo();

            return(targetBlock);
        }
Beispiel #3
0
        // Devuelve cierto si un bloque se puede mover, si se lo permite el gestor
        public bool CanMove(MovableBlock block)
        {
            if (block == null)
            {
                throw new ArgumentNullException(nameof(block));
            }

            return(puzzle.CanMoveByDefault(block.position));
        }
Beispiel #4
0
        // Devuelve si se puede mover un bloque en el tablero
        public bool CanMove(MovableBlock block)
        {
            if (block == null)
            {
                throw new ArgumentNullException(nameof(block));
            }

            return(manager.CanMove(block));
        }
Beispiel #5
0
        // Intercambia la posición física en la escena con otro bloque
        public void ExchangeTransform(MovableBlock block)
        {
            if (block == null)
            {
                throw new ArgumentNullException(nameof(block));
            }

            // Se usa una variable auxiliar para hacer el intercambio
            Vector3 auxTransformPosition = block.transform.position;

            block.transform.position = transform.position;

            transform.position = auxTransformPosition;
        }
Beispiel #6
0
        // Corrutina para pausar entre movimientos y poder verlos
        IEnumerator BlockInMotion(float delay)
        {
            blockInMotion = true;
            // Animar tal vez las dos piezas...
            yield return(new WaitForSeconds(delay));

            MovableBlock block      = blocksInMotion.Dequeue();
            MovableBlock otherBlock = blocksInMotion.Dequeue();

            // Ya ha cambiando el puzle, la posición lógica y ubicación en la matriz de bloques de ambos bloques
            // Sólo queda intercambiar la parte visual, la posición física de ambos en la escena
            block.ExchangeTransform(otherBlock);

            blockInMotion = false;
        }
Beispiel #7
0
        // Genera todos los bloques de la matriz
        // No se utiliza GetLowerBound ni GetUpperBound porque sabemos que son matrices que siempre empiezan en cero y acaban en positivo
        private void GenerateBlocks(SlidingPuzzle puzzle)
        {
            if (puzzle == null)
            {
                throw new ArgumentNullException(nameof(puzzle));
            }

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

            for (var r = 0u; r < rows; r++)
            {
                for (var c = 0u; c < columns; c++)
                {
                    MovableBlock block = blocks[r, c];
                    if (block == null)
                    {
                        // Crea un ejemplar del prefab de bloque en la posición correcta según su posición en la matriz (podrían hacerse hijos del tablero)
                        // Se asume un tablero en (0f, 0f, 0f) aunque debería tomarse la posición real del tablero como referencia
                        block = Instantiate(blockPrefab,
                                            new Vector3(-((blocks.GetLength(1) / 2.0f) * POSITION_FACTOR_C - (POSITION_FACTOR_C / 2.0f)) + c * POSITION_FACTOR_C,
                                                        0,
                                                        (blocks.GetLength(0) / 2.0f) * POSITION_FACTOR_R - (POSITION_FACTOR_R / 2.0f) - r * POSITION_FACTOR_R),
                                            Quaternion.identity); // En Y, que es la separación del board, estoy poniendo 0 pero la referencia la debería dar el Board

                        blocks[r, c] = block;
                    }
                    // Estuviera o no ya creado el bloque, se inicializa y reposiciona
                    Position position = new Position(r, c);
                    block.position = position;

                    uint value = puzzle.GetValue(position);
                    // El texto que se pone en el bloque es el valor +1, salvo si es el último valor, que no se mandará texto para que sea un bloque no visible
                    if (value == 0)
                    {
                        block.Initialize(this, null);
                    }
                    else
                    {
                        block.Initialize(this, value.ToString());
                    }
                    Debug.Log(ToString() + "generated " + block.ToString() + ".");
                }
            }
        }
Beispiel #8
0
        // Notifica el intento de movimiento al tablero de bloques (si lo hay), cuando se recibe un clic completo de ratón (apretar y soltar)
        // Podría reaccionarse con un sonido si el intento falla, aunque ahora no se hace nada
        // La he puesto pública para que se puedan simular pulsaciones sobre un bloque desde el gestor
        public bool OnMouseUpAsButton()
        {
            if (board == null)
            {
                throw new InvalidOperationException("This object has not been initialized");
            }

            Debug.Log("Trying to move " + ToString() + "...");
            if (board.CanMove(this))
            {
                board.UserInteraction(); // Aviso de que lo he tocado para que se pongan los contadores a cero (por si contenían algo)
                MovableBlock block = board.Move(this, BlockBoard.USER_DELAY);
                Debug.Log(ToString() + " was moved.");

                return(true);
            }

            Debug.Log(ToString() + " cannot be moved.");
            return(false);
        }