Example #1
0
 /// <summary>
 /// Create a new tetromino
 /// </summary>
 public Tetromino(TetrominoType type)
 {
     this.Type            = type;
     this.MinoTiles       = (Vector2Int[])TetrominoTiles(type).Clone();
     CurrentRotationState = Rotation.Up;
     CurrentSpinReward    = SpinReward.None;
 }
Example #2
0
    /// <summary>
    /// Rotate the tetromino in the given direction and return whether the rotation was successful.
    /// Tries to apply SRS kicks. Fails if no kick was possible or the tetromino is locked.
    /// </summary>
    public bool Rotate(Rotation dir)
    {
        bool rotatedSuccessfully = false;

        if (!Locked)
        {
            Locked = true;
            Vector2Int[] newMinoTiles     = new Vector2Int[MinoTiles.Length];
            Rotation     newRotationState = CurrentRotationState + dir;
            for (int i = 0; i < MinoTiles.Length; i++)
            {
                newMinoTiles[i] = MinoTiles[i].Rotated(dir);
            }
            Dictionary <Rotation, Vector2Int[]> offsets;
            switch (Type)
            {
            case TetrominoType.I:
                offsets = RotationOffsets_I;
                break;

            case TetrominoType.O:
                offsets = RotationOffsets_O;
                break;

            default:
                offsets = RotationOffsets;
                break;
            }

            int        kickTranslationCount = offsets[CurrentRotationState].Length;
            Vector2Int kickTranslation      = Vector2Int.Zero;
            for (int i = 0; i < kickTranslationCount; i++)
            {
                kickTranslation = offsets[CurrentRotationState][i] - offsets[newRotationState][i];
                if (rotatedSuccessfully = IsValidMovement(kickTranslation, newMinoTiles))
                {
                    this.Position += kickTranslation;
                    break;
                }
            }

            if (rotatedSuccessfully)
            {
                CurrentRotationState = newRotationState;
                for (int i = 0; i < MinoTiles.Length; i++)
                {
                    MinoTiles[i] = newMinoTiles[i];
                }
                this.CurrentSpinReward = CheckForSpinReward(kickTranslation);
            }
            Locked = false;
        }
        return(rotatedSuccessfully);
    }
Example #3
0
 /// <summary>
 /// Translate the tetromino by the given vector and return whether the translation was successful.
 /// Fails if tetromino is currently locked.
 /// </summary>
 public bool Translate(Vector2Int vec)
 {
     if (!Locked)
     {
         Locked = true;
         if (IsValidMovement(vec, MinoTiles))
         {
             this.Position         += vec;
             this.CurrentSpinReward = SpinReward.None;
             Locked = false;
             return(true);
         }
         Locked = false;
     }
     return(false);
 }
Example #4
0
    /// <summary>
    /// Award points for clearing line, spins, combos, etc.
    /// </summary>
    private void AwaredScore(int lineClears, SpinReward spinBonus)
    {
        int score;

        if (spinBonus == SpinReward.Regular)
        {
            score = 400 + lineClears * 400;
        }
        else
        {
            switch (lineClears)
            {
            case 1:
                score = 100;
                break;

            case 2:
                score = 300;
                break;

            case 3:
                score = 500;
                break;

            case 4:
                score = 800;
                break;

            default:
                score = 0;
                break;
            }
            if (spinBonus == SpinReward.Mini)
            {
                score += 100;
            }
        }
        // Back to back gives + 50%
        if (spinBonus == SpinReward.Regular || lineClears == 4)
        {
            if (BackToBack)
            {
                score += score / 2;
            }
            BackToBack = true;
        }
        else
        {
            BackToBack = false;
        }
        // Combo points
        if (lineClears > 0)
        {
            score += Combo * 50;
            Combo++;
        }
        else
        {
            Combo = 0;
        }
        // Check for a perfect clear
        if (Board.IsEmpty())
        {
            switch (lineClears)
            {
            case 1:
                score += 800;
                break;

            case 2:
                score += 1000;
                break;

            case 3:
                score += 1800;
                break;

            case 4:
                score += 2000;
                break;
            }
        }
        this.Score += score;
        EmitSignal(nameof(ScoreUpdateSignal));
    }