Пример #1
0
 private bool IsValidDestinationCoordinateSetForTetromino(TetrominoBehavior tetromino, ICollection <Coordinates> coordinates)
 {
     foreach (var coordinate in coordinates)
     {
         if (!IsEmptyCoordinate(tetromino, coordinate))
         {
             return(false);
         }
     }
     return(true);
 }
Пример #2
0
 private bool TryUnityCoordinateShiftForValidLocation(TetrominoBehavior tetromino, ICollection <Coordinates> coordinates, Direction direction)
 {
     MoveCoordinatesInDirectionByUnity(coordinates, direction);
     if (IsValidDestinationCoordinateSetForTetromino(tetromino, coordinates))
     {
         return(true);
     }
     else
     {
         //Undo our operation and return failure
         MoveCoordinatesInDirectionByUnity(coordinates, direction.Opposite());
         return(false);
     }
 }
Пример #3
0
    private bool IsEmptyCoordinate(TetrominoBehavior tetromino, Coordinates coordinate)
    {
        if (coordinate.X < 0 || coordinate.X >= Width || coordinate.Y < 0 || coordinate.Y >= Height)
        {
            return(false);
        }
        BlockBehavior targetCoordinate = _blocks[coordinate.X, coordinate.Y];

        if (tetromino.Blocks.Contains(targetCoordinate) || targetCoordinate == null)
        {
            return(true);
        }
        else
        {
            return(false);
        }
    }
Пример #4
0
    /// <summary>
    /// Moves a tetromino, but only if there is not another block or a wall in the way.
    /// </summary>
    public bool TryMoveTetromino(TetrominoBehavior tetromino, Direction direction)
    {
        var blocks = tetromino.Blocks;

        foreach (var block in blocks)
        {
            if (IsWallAdjacent(block, direction))
            {
                return(false);
            }

            // We need to check if the blocks in the way of our block are part of the block group. Because, if they are, it's OK to move the block, since the adjacent block will move too.
            var adjacentBlock = GetBlockAdjacent(block, direction);
            if (adjacentBlock != null && !tetromino.Blocks.Contains(adjacentBlock))
            {
                return(false);
            }
        }

        MoveTetromino(tetromino, direction);

        return(true);
    }
Пример #5
0
    /// <summary>
    /// Rotates a group of blocks if possible
    /// </summary>
    /// <param name="tetromino"></param>
    public void TryRotateBlocksAsGroup(TetrominoBehavior tetromino, float theta)
    {
        theta *= Mathf.Deg2Rad;
        var   blocks      = tetromino.Blocks;
        var   rotatePoint = tetromino.GetRotatePoint();
        float sinTheta    = Mathf.Sin(theta);
        float cosTheta    = Mathf.Cos(theta);
        IDictionary <BlockBehavior, Coordinates> potentialBlockCoordinates = new Dictionary <BlockBehavior, Coordinates>();


        //Find all of our new block locations, should this rotation go through
        foreach (var block in blocks)
        {
            Coordinates originBlock      = CoordinatesForBlock(block);
            Coordinates transformedBlock = Coordinates.subtract(originBlock, rotatePoint);
            Coordinates newBlock         = new Coordinates(0, 0);

            newBlock.X = Mathf.RoundToInt(transformedBlock.X * cosTheta - transformedBlock.Y * sinTheta);
            newBlock.Y = Mathf.RoundToInt(transformedBlock.Y * cosTheta + transformedBlock.X * sinTheta);

            newBlock = Coordinates.add(rotatePoint, newBlock);

            Vector3 netTranslation = new Vector3(newBlock.X - originBlock.X, newBlock.Y - originBlock.Y, 0);

            potentialBlockCoordinates.Add(block, new Coordinates(newBlock.X, newBlock.Y));
        }

        //Make sure that none of these are going on top of existing blocks, or outside the wall
        //This super if block will try a shift in every direction (including none) to find a way to make rotation work
        Direction shift = Direction.None;

        if (TryUnityCoordinateShiftForValidLocation(tetromino, potentialBlockCoordinates.Values, Direction.None))
        {
            shift = Direction.None;
        }
        else if (TryUnityCoordinateShiftForValidLocation(tetromino, potentialBlockCoordinates.Values, Direction.Up))
        {
            shift = Direction.Up;
        }
        else if (TryUnityCoordinateShiftForValidLocation(tetromino, potentialBlockCoordinates.Values, Direction.Down))
        {
            shift = Direction.Down;
        }
        else if (TryUnityCoordinateShiftForValidLocation(tetromino, potentialBlockCoordinates.Values, Direction.Left))
        {
            shift = Direction.Left;
        }
        else if (TryUnityCoordinateShiftForValidLocation(tetromino, potentialBlockCoordinates.Values, Direction.Right))
        {
            shift = Direction.Right;
        }
        else
        {
            //We have to bail, this won't work!
            return;
        }

        tetromino.Translate(shift.UnityVector());

        //Renaming to avoid confusion later.
        var newBlockCoordinates = potentialBlockCoordinates;

        //We are good to go. Clear out the blocks from the field
        foreach (var block in blocks)
        {
            Coordinates originBlock = CoordinatesForBlock(block);
            _blocks[originBlock.X, originBlock.Y] = null;
            block.transform.position = CoordinatesToGameWorldPosition(newBlockCoordinates[block]);
        }

        // We don't record the new locations of the blocks until we've moved all of them. Otherwise, we might overwrite blocks that we just moved.
        foreach (var newCoordinates in newBlockCoordinates)
        {
            _blocks[newCoordinates.Value.X, newCoordinates.Value.Y] = newCoordinates.Key;
        }
    }
Пример #6
0
    /// <summary>
    /// Wrapper around MoveBlocks to represent a change of a tetromino object proper instead of just a set of blocks.
    /// This helps maintain the point of rotation within the tetromino
    /// </summary>
    /// <param name="tetromino"></param>
    /// <param name="direction"></param>
    private void MoveTetromino(TetrominoBehavior tetromino, Direction direction)
    {
        var result = MoveBlocks(tetromino.Blocks, direction);

        tetromino.Translate(result);
    }