/*******************************************************************************************
							 | 
						|
								*
							 | 
						|
								*   raylib - sample game: tetris
							 | 
						|
								*
							 | 
						|
								*   Sample game Marc Palau and Ramon Santamaria
							 | 
						|
								*
							 | 
						|
								*   This game has been created using raylib v1.3 (www.raylib.com)
							 | 
						|
								*   raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
							 | 
						|
								*
							 | 
						|
								*   Copyright (c) 2015 Ramon Santamaria (@raysan5)
							 | 
						|
								*
							 | 
						|
								********************************************************************************************/
							 | 
						|
								
							 | 
						|
								#include "raylib.h"
							 | 
						|
								
							 | 
						|
								#include <stdio.h>
							 | 
						|
								#include <stdlib.h>
							 | 
						|
								#include <time.h>
							 | 
						|
								#include <math.h>
							 | 
						|
								
							 | 
						|
								#if defined(PLATFORM_WEB)
							 | 
						|
								    #include <emscripten/emscripten.h>
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								//----------------------------------------------------------------------------------
							 | 
						|
								// Some Defines
							 | 
						|
								//----------------------------------------------------------------------------------
							 | 
						|
								#define SQUARE_SIZE             20
							 | 
						|
								
							 | 
						|
								#define GRID_HORIZONTAL_SIZE    12
							 | 
						|
								#define GRID_VERTICAL_SIZE      20
							 | 
						|
								
							 | 
						|
								#define LATERAL_SPEED           10
							 | 
						|
								#define TURNING_SPEED           12
							 | 
						|
								#define FAST_FALL_AWAIT_COUNTER 30
							 | 
						|
								
							 | 
						|
								#define FADING_TIME             33
							 | 
						|
								
							 | 
						|
								//----------------------------------------------------------------------------------
							 | 
						|
								// Types and Structures Definition
							 | 
						|
								//----------------------------------------------------------------------------------
							 | 
						|
								typedef enum GridSquare { EMPTY, MOVING, FULL, BLOCK, FADING } GridSquare;
							 | 
						|
								
							 | 
						|
								//------------------------------------------------------------------------------------
							 | 
						|
								// Global Variables Declaration
							 | 
						|
								//------------------------------------------------------------------------------------
							 | 
						|
								static int screenWidth = 800;
							 | 
						|
								static int screenHeight = 450;
							 | 
						|
								
							 | 
						|
								static bool gameOver = false;
							 | 
						|
								static bool pause = false;
							 | 
						|
								
							 | 
						|
								// Matrices
							 | 
						|
								static GridSquare grid [GRID_HORIZONTAL_SIZE][GRID_VERTICAL_SIZE];
							 | 
						|
								static GridSquare piece [4][4];
							 | 
						|
								static GridSquare incomingPiece [4][4];
							 | 
						|
								
							 | 
						|
								// Theese variables keep track of the active piece position
							 | 
						|
								static int piecePositionX = 0;
							 | 
						|
								static int piecePositionY = 0;
							 | 
						|
								
							 | 
						|
								// Game parameters
							 | 
						|
								static Color fadingColor;
							 | 
						|
								//static int fallingSpeed;           // In frames
							 | 
						|
								
							 | 
						|
								static bool beginPlay = true;      // This var is only true at the begining of the game, used for the first matrix creations
							 | 
						|
								static bool pieceActive = false;
							 | 
						|
								static bool detection = false;
							 | 
						|
								static bool lineToDelete = false;
							 | 
						|
								
							 | 
						|
								// Statistics
							 | 
						|
								static int level = 1;
							 | 
						|
								static int lines = 0;
							 | 
						|
								
							 | 
						|
								// Counters
							 | 
						|
								static int gravityMovementCounter = 0;
							 | 
						|
								static int lateralMovementCounter = 0;
							 | 
						|
								static int turnMovementCounter = 0;
							 | 
						|
								static int fastFallMovementCounter = 0;
							 | 
						|
								
							 | 
						|
								static int fadeLineCounter = 0;
							 | 
						|
								
							 | 
						|
								// Based on level
							 | 
						|
								static int gravitySpeed = 30;
							 | 
						|
								
							 | 
						|
								//------------------------------------------------------------------------------------
							 | 
						|
								// Module Functions Declaration (local)
							 | 
						|
								//------------------------------------------------------------------------------------
							 | 
						|
								static void InitGame(void);         // Initialize game
							 | 
						|
								static void UpdateGame(void);       // Update game (one frame)
							 | 
						|
								static void DrawGame(void);         // Draw game (one frame)
							 | 
						|
								static void UnloadGame(void);       // Unload game
							 | 
						|
								static void UpdateDrawFrame(void);  // Update and Draw (one frame)
							 | 
						|
								
							 | 
						|
								// Additional module functions
							 | 
						|
								static bool Createpiece();
							 | 
						|
								static void GetRandompiece();
							 | 
						|
								static void ResolveFallingMovement();
							 | 
						|
								static bool ResolveLateralMovement();
							 | 
						|
								static bool ResolveTurnMovement();
							 | 
						|
								static void CheckDetection();
							 | 
						|
								static void CheckCompletition();
							 | 
						|
								static void DeleteCompleteLines();
							 | 
						|
								
							 | 
						|
								//------------------------------------------------------------------------------------
							 | 
						|
								// Program main entry point
							 | 
						|
								//------------------------------------------------------------------------------------
							 | 
						|
								int main(void)
							 | 
						|
								{
							 | 
						|
								    // Initialization (Note windowTitle is unused on Android)
							 | 
						|
								    //---------------------------------------------------------
							 | 
						|
								    InitWindow(screenWidth, screenHeight, "sample game: tetris");
							 | 
						|
								
							 | 
						|
								    InitGame();
							 | 
						|
								
							 | 
						|
								#if defined(PLATFORM_WEB)
							 | 
						|
								    emscripten_set_main_loop(UpdateDrawFrame, 0, 1);
							 | 
						|
								#else
							 | 
						|
								
							 | 
						|
								    SetTargetFPS(60);
							 | 
						|
								    //--------------------------------------------------------------------------------------
							 | 
						|
								    
							 | 
						|
								    // Main game loop
							 | 
						|
								    while (!WindowShouldClose())    // Detect window close button or ESC key
							 | 
						|
								    {
							 | 
						|
								        // Update and Draw
							 | 
						|
								        //----------------------------------------------------------------------------------
							 | 
						|
								        UpdateDrawFrame();
							 | 
						|
								        //----------------------------------------------------------------------------------
							 | 
						|
								    }
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								    // De-Initialization
							 | 
						|
								    //--------------------------------------------------------------------------------------
							 | 
						|
								    UnloadGame();         // Unload loaded data (textures, sounds, models...)
							 | 
						|
								    
							 | 
						|
								    CloseWindow();        // Close window and OpenGL context
							 | 
						|
								    //--------------------------------------------------------------------------------------
							 | 
						|
								
							 | 
						|
								    return 0;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								//--------------------------------------------------------------------------------------
							 | 
						|
								// Game Module Functions Definition
							 | 
						|
								//--------------------------------------------------------------------------------------
							 | 
						|
								
							 | 
						|
								// Initialize game variables
							 | 
						|
								void InitGame(void)
							 | 
						|
								{
							 | 
						|
								    // Initialize game statistics
							 | 
						|
								    level = 1;
							 | 
						|
								    lines = 0;
							 | 
						|
								
							 | 
						|
								    fadingColor = GRAY;
							 | 
						|
								
							 | 
						|
								    piecePositionX = 0;
							 | 
						|
								    piecePositionY = 0;
							 | 
						|
								
							 | 
						|
								    pause = false;
							 | 
						|
								
							 | 
						|
								    beginPlay = true;
							 | 
						|
								    pieceActive = false;
							 | 
						|
								    detection = false;
							 | 
						|
								    lineToDelete = false;
							 | 
						|
								
							 | 
						|
								    // Counters
							 | 
						|
								    gravityMovementCounter = 0;
							 | 
						|
								    lateralMovementCounter = 0;
							 | 
						|
								    turnMovementCounter = 0;
							 | 
						|
								    fastFallMovementCounter = 0;
							 | 
						|
								
							 | 
						|
								    fadeLineCounter = 0;
							 | 
						|
								    gravitySpeed = 30;
							 | 
						|
								
							 | 
						|
								    // Initialize grid matrices
							 | 
						|
								    for (int i = 0; i < GRID_HORIZONTAL_SIZE; i++)
							 | 
						|
								    {
							 | 
						|
								        for (int j = 0; j < GRID_VERTICAL_SIZE; j++)
							 | 
						|
								        {
							 | 
						|
								            if ((j == GRID_VERTICAL_SIZE - 1) || (i == 0) || (i == GRID_HORIZONTAL_SIZE - 1)) grid[i][j] = BLOCK;
							 | 
						|
								            else grid[i][j] = EMPTY;
							 | 
						|
								        }
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    // Initialize incoming piece matrices
							 | 
						|
								    for (int i = 0; i < 4; i++)
							 | 
						|
								    {
							 | 
						|
								        for (int j = 0; j< 4; j++)
							 | 
						|
								        {
							 | 
						|
								            incomingPiece[i][j] = EMPTY;
							 | 
						|
								        }
							 | 
						|
								    }
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								// Update game (one frame)
							 | 
						|
								void UpdateGame(void)
							 | 
						|
								{
							 | 
						|
								    if (!gameOver)
							 | 
						|
								    {
							 | 
						|
								        if (IsKeyPressed('P')) pause = !pause;
							 | 
						|
								
							 | 
						|
								        if (!pause)
							 | 
						|
								        {
							 | 
						|
								            if (!lineToDelete)
							 | 
						|
								            {
							 | 
						|
								                if (!pieceActive)
							 | 
						|
								                {
							 | 
						|
								                    // Get another piece
							 | 
						|
								                    pieceActive = Createpiece();
							 | 
						|
								
							 | 
						|
								                    // We leave a little time before starting the fast falling down
							 | 
						|
								                    fastFallMovementCounter = 0;
							 | 
						|
								                }
							 | 
						|
								                else    // Piece falling
							 | 
						|
								                {
							 | 
						|
								                    // Counters update
							 | 
						|
								                    fastFallMovementCounter++;
							 | 
						|
								                    gravityMovementCounter++;
							 | 
						|
								                    lateralMovementCounter++;
							 | 
						|
								                    turnMovementCounter++;
							 | 
						|
								
							 | 
						|
								                    // We make sure to move if we've pressed the key this frame
							 | 
						|
								                    if (IsKeyPressed(KEY_LEFT) || IsKeyPressed(KEY_RIGHT)) lateralMovementCounter = LATERAL_SPEED;
							 | 
						|
								                    if (IsKeyPressed(KEY_UP)) turnMovementCounter = TURNING_SPEED;
							 | 
						|
								
							 | 
						|
								                    // Fall down
							 | 
						|
								                    if (IsKeyDown(KEY_DOWN) && (fastFallMovementCounter >= FAST_FALL_AWAIT_COUNTER))
							 | 
						|
								                    {
							 | 
						|
								                        // We make sure the piece is going to fall this frame
							 | 
						|
								                        gravityMovementCounter += gravitySpeed;
							 | 
						|
								                    }
							 | 
						|
								                    
							 | 
						|
								                    if (gravityMovementCounter >= gravitySpeed)
							 | 
						|
								                    {
							 | 
						|
								                        // Basic falling movement
							 | 
						|
								                        CheckDetection(&detection);
							 | 
						|
								
							 | 
						|
								                        // Check if the piece has collided with another piece or with the boundings
							 | 
						|
								                        ResolveFallingMovement(&detection, &pieceActive);
							 | 
						|
								
							 | 
						|
								                        // Check if we fullfilled a line and if so, erase the line and pull down the the lines above
							 | 
						|
								                        CheckCompletition(&lineToDelete);
							 | 
						|
								
							 | 
						|
								                        gravityMovementCounter = 0;
							 | 
						|
								                    }
							 | 
						|
								                    
							 | 
						|
								                    // Move laterally at player's will
							 | 
						|
								                    if (lateralMovementCounter >= LATERAL_SPEED)
							 | 
						|
								                    {
							 | 
						|
								                        // Update the lateral movement and if success, reset the lateral counter
							 | 
						|
								                        if (!ResolveLateralMovement()) lateralMovementCounter = 0;
							 | 
						|
								                    }
							 | 
						|
								                    
							 | 
						|
								                    // Turn the piece at player's will
							 | 
						|
								                    if (turnMovementCounter >= TURNING_SPEED)
							 | 
						|
								                    {
							 | 
						|
								                        // Update the turning movement and reset the turning counter
							 | 
						|
								                        if (ResolveTurnMovement()) turnMovementCounter = 0;
							 | 
						|
								                    }
							 | 
						|
								                }
							 | 
						|
								
							 | 
						|
								                // Game over logic
							 | 
						|
								                for (int j = 0; j < 2; j++)
							 | 
						|
								                {
							 | 
						|
								                    for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++)
							 | 
						|
								                    {
							 | 
						|
								                        if (grid[i][j] == FULL)
							 | 
						|
								                        {
							 | 
						|
								                            gameOver = true;
							 | 
						|
								                        }
							 | 
						|
								                    }
							 | 
						|
								                }
							 | 
						|
								            }
							 | 
						|
								            else
							 | 
						|
								            {
							 | 
						|
								                // Animation when deleting lines
							 | 
						|
								                fadeLineCounter++;
							 | 
						|
								
							 | 
						|
								                if (fadeLineCounter%8 < 4) fadingColor = MAROON;
							 | 
						|
								                else fadingColor = GRAY;
							 | 
						|
								
							 | 
						|
								                if (fadeLineCounter >= FADING_TIME)
							 | 
						|
								                {
							 | 
						|
								                    DeleteCompleteLines();
							 | 
						|
								                    fadeLineCounter = 0;
							 | 
						|
								                    lineToDelete = false;
							 | 
						|
								                    
							 | 
						|
								                    lines++;
							 | 
						|
								                }
							 | 
						|
								            }
							 | 
						|
								        }
							 | 
						|
								    }
							 | 
						|
								    else
							 | 
						|
								    {
							 | 
						|
								        if (IsKeyPressed(KEY_ENTER))
							 | 
						|
								        {
							 | 
						|
								            InitGame();
							 | 
						|
								            gameOver = false;
							 | 
						|
								        }
							 | 
						|
								    }
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								// Draw game (one frame)
							 | 
						|
								void DrawGame(void)
							 | 
						|
								{
							 | 
						|
								    BeginDrawing();
							 | 
						|
								
							 | 
						|
								        ClearBackground(RAYWHITE);
							 | 
						|
								
							 | 
						|
								        if (!gameOver)
							 | 
						|
								        {
							 | 
						|
								            // Draw gameplay area
							 | 
						|
								            Vector2 offset;
							 | 
						|
								            offset.x = screenWidth/2 - (GRID_HORIZONTAL_SIZE*SQUARE_SIZE/2) - 50;
							 | 
						|
								            offset.y = screenHeight/2 - ((GRID_VERTICAL_SIZE - 1)*SQUARE_SIZE/2) + SQUARE_SIZE*2;
							 | 
						|
								
							 | 
						|
								            offset.y -= 50;     // NOTE: Harcoded position!
							 | 
						|
								
							 | 
						|
								            int controller = offset.x;
							 | 
						|
								
							 | 
						|
								            for (int j = 0; j < GRID_VERTICAL_SIZE; j++)
							 | 
						|
								            {
							 | 
						|
								                for (int i = 0; i < GRID_HORIZONTAL_SIZE; i++)
							 | 
						|
								                {
							 | 
						|
								                    // Draw each square of the grid
							 | 
						|
								                    if (grid[i][j] == EMPTY)
							 | 
						|
								                    {
							 | 
						|
								                        DrawLine(offset.x, offset.y, offset.x + SQUARE_SIZE, offset.y, LIGHTGRAY );
							 | 
						|
								                        DrawLine(offset.x, offset.y, offset.x, offset.y + SQUARE_SIZE, LIGHTGRAY );
							 | 
						|
								                        DrawLine(offset.x + SQUARE_SIZE, offset.y, offset.x + SQUARE_SIZE, offset.y + SQUARE_SIZE, LIGHTGRAY );
							 | 
						|
								                        DrawLine(offset.x, offset.y + SQUARE_SIZE, offset.x + SQUARE_SIZE, offset.y + SQUARE_SIZE, LIGHTGRAY );
							 | 
						|
								                        offset.x += SQUARE_SIZE;
							 | 
						|
								                    }
							 | 
						|
								                    else if (grid[i][j] == FULL)
							 | 
						|
								                    {
							 | 
						|
								                        DrawRectangle(offset.x, offset.y, SQUARE_SIZE, SQUARE_SIZE, GRAY);
							 | 
						|
								                        offset.x += SQUARE_SIZE;
							 | 
						|
								                    }
							 | 
						|
								                    else if (grid[i][j] == MOVING)
							 | 
						|
								                    {
							 | 
						|
								                        DrawRectangle(offset.x, offset.y, SQUARE_SIZE, SQUARE_SIZE, DARKGRAY);
							 | 
						|
								                        offset.x += SQUARE_SIZE;
							 | 
						|
								                    }
							 | 
						|
								                    else if (grid[i][j] == BLOCK)
							 | 
						|
								                    {
							 | 
						|
								                        DrawRectangle(offset.x, offset.y, SQUARE_SIZE, SQUARE_SIZE, LIGHTGRAY);
							 | 
						|
								                        offset.x += SQUARE_SIZE;
							 | 
						|
								                    }
							 | 
						|
								                    else if (grid[i][j] == FADING)
							 | 
						|
								                    {
							 | 
						|
								                        DrawRectangle(offset.x, offset.y, SQUARE_SIZE, SQUARE_SIZE, fadingColor);
							 | 
						|
								                        offset.x += SQUARE_SIZE;
							 | 
						|
								                    }
							 | 
						|
								                }
							 | 
						|
								
							 | 
						|
								                offset.x = controller;
							 | 
						|
								                offset.y += SQUARE_SIZE;
							 | 
						|
								            }
							 | 
						|
								            
							 | 
						|
								            // Draw incoming piece (hardcoded)
							 | 
						|
								            offset.x = 500;
							 | 
						|
								            offset.y = 45;
							 | 
						|
								
							 | 
						|
								            int controler = offset.x;
							 | 
						|
								            
							 | 
						|
								            for (int j = 0; j < 4; j++)
							 | 
						|
								            {
							 | 
						|
								                for (int i = 0; i < 4; i++)
							 | 
						|
								                {
							 | 
						|
								                    if (incomingPiece[i][j] == EMPTY)
							 | 
						|
								                    {
							 | 
						|
								                        DrawLine(offset.x, offset.y, offset.x + SQUARE_SIZE, offset.y, LIGHTGRAY );
							 | 
						|
								                        DrawLine(offset.x, offset.y, offset.x, offset.y + SQUARE_SIZE, LIGHTGRAY );
							 | 
						|
								                        DrawLine(offset.x + SQUARE_SIZE, offset.y, offset.x + SQUARE_SIZE, offset.y + SQUARE_SIZE, LIGHTGRAY );
							 | 
						|
								                        DrawLine(offset.x, offset.y + SQUARE_SIZE, offset.x + SQUARE_SIZE, offset.y + SQUARE_SIZE, LIGHTGRAY );
							 | 
						|
								                        offset.x += SQUARE_SIZE;
							 | 
						|
								                    }
							 | 
						|
								                    else if (incomingPiece[i][j] == MOVING)
							 | 
						|
								                    {
							 | 
						|
								                        DrawRectangle(offset.x, offset.y, SQUARE_SIZE, SQUARE_SIZE, GRAY);
							 | 
						|
								                        offset.x += SQUARE_SIZE;
							 | 
						|
								                    }
							 | 
						|
								                }
							 | 
						|
								
							 | 
						|
								                offset.x = controler;
							 | 
						|
								                offset.y += SQUARE_SIZE;
							 | 
						|
								            }
							 | 
						|
								            
							 | 
						|
								            DrawText("INCOMING:", offset.x, offset.y - 100, 10, GRAY);
							 | 
						|
								            DrawText(FormatText("LINES:      %04i", lines), offset.x, offset.y + 20, 10, GRAY);
							 | 
						|
								            
							 | 
						|
								            if (pause) DrawText("GAME PAUSED", screenWidth/2 - MeasureText("GAME PAUSED", 40)/2, screenHeight/2 - 40, 40, GRAY);
							 | 
						|
								        }
							 | 
						|
								        else DrawText("PRESS [ENTER] TO PLAY AGAIN", GetScreenWidth()/2 - MeasureText("PRESS [ENTER] TO PLAY AGAIN", 20)/2, GetScreenHeight()/2 - 50, 20, GRAY);
							 | 
						|
								
							 | 
						|
								    EndDrawing();
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								// Unload game variables
							 | 
						|
								void UnloadGame(void)
							 | 
						|
								{
							 | 
						|
								    // TODO: Unload all dynamic loaded data (textures, sounds, models...)
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								// Update and Draw (one frame)
							 | 
						|
								void UpdateDrawFrame(void)
							 | 
						|
								{
							 | 
						|
								    UpdateGame();
							 | 
						|
								    DrawGame();
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								//--------------------------------------------------------------------------------------
							 | 
						|
								// Additional module functions
							 | 
						|
								//--------------------------------------------------------------------------------------
							 | 
						|
								static bool Createpiece()
							 | 
						|
								{
							 | 
						|
								    piecePositionX = (int)((GRID_HORIZONTAL_SIZE - 4)/2);
							 | 
						|
								    piecePositionY = 0;
							 | 
						|
								
							 | 
						|
								    // If the game is starting and you are going to create the first piece, we create an extra one
							 | 
						|
								    if (beginPlay)
							 | 
						|
								    {
							 | 
						|
								        GetRandompiece();
							 | 
						|
								        beginPlay = false;
							 | 
						|
								    }
							 | 
						|
								    
							 | 
						|
								    // We assign the incoming piece to the actual piece
							 | 
						|
								    for (int i = 0; i < 4; i++)
							 | 
						|
								    {
							 | 
						|
								        for (int j = 0; j< 4; j++)
							 | 
						|
								        {
							 | 
						|
								            piece[i][j] = incomingPiece[i][j];
							 | 
						|
								        }
							 | 
						|
								    }
							 | 
						|
								    
							 | 
						|
								    // We assign a random piece to the incoming one
							 | 
						|
								    GetRandompiece();
							 | 
						|
								
							 | 
						|
								    // Assign the piece to the grid
							 | 
						|
								    for (int i = piecePositionX; i < piecePositionX + 4; i++)
							 | 
						|
								    {
							 | 
						|
								        for (int j = 0; j < 4; j++)
							 | 
						|
								        {
							 | 
						|
								            if (piece[i - (int)piecePositionX][j] == MOVING) grid[i][j] = MOVING;
							 | 
						|
								        }
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    return true;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								static void GetRandompiece()
							 | 
						|
								{
							 | 
						|
								    srand(time(NULL));
							 | 
						|
								    int random = rand() % 7;
							 | 
						|
								
							 | 
						|
								    for (int i = 0; i < 4; i++)
							 | 
						|
								    {
							 | 
						|
								        for (int j = 0; j < 4; j++)
							 | 
						|
								        {
							 | 
						|
								            incomingPiece[i][j] = EMPTY;
							 | 
						|
								        }
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    switch(random)
							 | 
						|
								    {
							 | 
						|
								        case 0:    {    incomingPiece[1][1] = MOVING;   incomingPiece[2][1] = MOVING;    incomingPiece[1][2] = MOVING;    incomingPiece[2][2] = MOVING;    }    break;    //Cube
							 | 
						|
								        case 1:    {    incomingPiece[1][0] = MOVING;    incomingPiece[1][1] = MOVING;    incomingPiece[1][2] = MOVING;    incomingPiece[2][2] = MOVING;    }    break;    //L
							 | 
						|
								        case 2:    {    incomingPiece[1][2] = MOVING;    incomingPiece[2][0] = MOVING;    incomingPiece[2][1] = MOVING;    incomingPiece[2][2] = MOVING;    }    break;    //L inversa
							 | 
						|
								        case 3:    {    incomingPiece[0][1] = MOVING;    incomingPiece[1][1] = MOVING;    incomingPiece[2][1] = MOVING;    incomingPiece[3][1] = MOVING;    }    break;    //Recta
							 | 
						|
								        case 4:    {    incomingPiece[1][0] = MOVING;    incomingPiece[1][1] = MOVING;    incomingPiece[1][2] = MOVING;    incomingPiece[2][1] = MOVING;    }    break;    //Creu tallada
							 | 
						|
								        case 5: {    incomingPiece[1][1] = MOVING;    incomingPiece[2][1] = MOVING;     incomingPiece[2][2] = MOVING;    incomingPiece[3][2] = MOVING;    }    break;    //S
							 | 
						|
								        case 6: {    incomingPiece[1][2] = MOVING;    incomingPiece[2][2] = MOVING;     incomingPiece[2][1] = MOVING;    incomingPiece[3][1] = MOVING;    }    break;    //S inversa
							 | 
						|
								    }
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								static void ResolveFallingMovement(bool *detection, bool *pieceActive)
							 | 
						|
								{
							 | 
						|
								    // If we finished moving this piece, we stop it
							 | 
						|
								    if (*detection)
							 | 
						|
								    {
							 | 
						|
								        for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
							 | 
						|
								        {
							 | 
						|
								            for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++)
							 | 
						|
								            {
							 | 
						|
								                if (grid[i][j] == MOVING)
							 | 
						|
								                {
							 | 
						|
								                    grid[i][j] = FULL;
							 | 
						|
								                    *detection = false;
							 | 
						|
								                    *pieceActive = false;
							 | 
						|
								                }
							 | 
						|
								            }
							 | 
						|
								        }
							 | 
						|
								    }
							 | 
						|
								    // We move down the piece
							 | 
						|
								    else
							 | 
						|
								    {
							 | 
						|
								        for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
							 | 
						|
								        {
							 | 
						|
								            for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++)
							 | 
						|
								            {
							 | 
						|
								                if (grid[i][j] == MOVING)
							 | 
						|
								                {
							 | 
						|
								                    grid[i][j+1] = MOVING;
							 | 
						|
								                    grid[i][j] = EMPTY;
							 | 
						|
								                }
							 | 
						|
								            }
							 | 
						|
								        }
							 | 
						|
								        piecePositionY++;
							 | 
						|
								    }
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								static bool ResolveLateralMovement()
							 | 
						|
								{
							 | 
						|
								    bool collision = false;
							 | 
						|
								
							 | 
						|
								    // Move left
							 | 
						|
								    if (IsKeyDown(KEY_LEFT))
							 | 
						|
								    {
							 | 
						|
								        // Check if is possible to move to left
							 | 
						|
								        for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
							 | 
						|
								        {
							 | 
						|
								            for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++)
							 | 
						|
								            {
							 | 
						|
								                if (grid[i][j] == MOVING)
							 | 
						|
								                {
							 | 
						|
								                    // Check if we are touching the left wall or we have a full square at the left
							 | 
						|
								                    if ((i-1 == 0) || (grid[i-1][j] == FULL)) collision = true;
							 | 
						|
								                }
							 | 
						|
								            }
							 | 
						|
								        }
							 | 
						|
								        // If able, move left
							 | 
						|
								        if (!collision)
							 | 
						|
								        {
							 | 
						|
								            for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
							 | 
						|
								            {
							 | 
						|
								                for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++)             // We check the matrix from left to right
							 | 
						|
								                {
							 | 
						|
								                    // Move everything to the left
							 | 
						|
								                    if (grid[i][j] == MOVING)
							 | 
						|
								                    {
							 | 
						|
								                        grid[i-1][j] = MOVING;
							 | 
						|
								                        grid[i][j] = EMPTY;
							 | 
						|
								                    }
							 | 
						|
								                }
							 | 
						|
								            }
							 | 
						|
								
							 | 
						|
								            piecePositionX--;
							 | 
						|
								        }
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    // Move right
							 | 
						|
								    else if (IsKeyDown(KEY_RIGHT))
							 | 
						|
								    {
							 | 
						|
								        // Check if is possible to move to right
							 | 
						|
								        for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
							 | 
						|
								        {
							 | 
						|
								            for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++)
							 | 
						|
								            {
							 | 
						|
								                if (grid[i][j] == MOVING)
							 | 
						|
								                {
							 | 
						|
								                    // Check if we are touching the right wall or we have a full square at the right
							 | 
						|
								                    if ((i+1 == GRID_HORIZONTAL_SIZE - 1) || (grid[i+1][j] == FULL))
							 | 
						|
								                    {
							 | 
						|
								                        collision = true;
							 | 
						|
								
							 | 
						|
								                    }
							 | 
						|
								                }
							 | 
						|
								            }
							 | 
						|
								        }
							 | 
						|
								        // If able move right
							 | 
						|
								        if (!collision)
							 | 
						|
								        {
							 | 
						|
								            for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
							 | 
						|
								            {
							 | 
						|
								                for (int i = GRID_HORIZONTAL_SIZE - 1; i >= 1; i--)             // We check the matrix from right to left
							 | 
						|
								                {
							 | 
						|
								                    // Move everything to the right
							 | 
						|
								                    if (grid[i][j] == MOVING)
							 | 
						|
								                    {
							 | 
						|
								                        grid[i+1][j] = MOVING;
							 | 
						|
								                        grid[i][j] = EMPTY;
							 | 
						|
								                    }
							 | 
						|
								                }
							 | 
						|
								            }
							 | 
						|
								
							 | 
						|
								            piecePositionX++;
							 | 
						|
								        }
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    return collision;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								static bool ResolveTurnMovement()
							 | 
						|
								{
							 | 
						|
								    // Input for turning the piece
							 | 
						|
								    if (IsKeyDown(KEY_UP))
							 | 
						|
								    {
							 | 
						|
								        int aux;
							 | 
						|
								        bool checker = false;
							 | 
						|
								
							 | 
						|
								        // Check all turning possibilities
							 | 
						|
								        if ((grid[piecePositionX + 3][piecePositionY] == MOVING) &&
							 | 
						|
								            (grid[piecePositionX][piecePositionY] != EMPTY) &&
							 | 
						|
								            (grid[piecePositionX][piecePositionY] != MOVING))
							 | 
						|
								        {    
							 | 
						|
								            checker = true;
							 | 
						|
								        }
							 | 
						|
								        if ((grid[piecePositionX + 3][piecePositionY + 3] == MOVING) &&
							 | 
						|
								            (grid[piecePositionX + 3][piecePositionY] != EMPTY) &&
							 | 
						|
								            (grid[piecePositionX + 3][piecePositionY] != MOVING))
							 | 
						|
								        {    
							 | 
						|
								            checker = true;
							 | 
						|
								        }
							 | 
						|
								        if ((grid[piecePositionX][piecePositionY + 3] == MOVING) &&
							 | 
						|
								            (grid[piecePositionX + 3][piecePositionY + 3] != EMPTY) &&
							 | 
						|
								            (grid[piecePositionX + 3][piecePositionY + 3] != MOVING))
							 | 
						|
								        {    
							 | 
						|
								            checker = true;
							 | 
						|
								        }
							 | 
						|
								        if ((grid[piecePositionX][piecePositionY] == MOVING) &&
							 | 
						|
								            (grid[piecePositionX][piecePositionY + 3] != EMPTY) &&
							 | 
						|
								            (grid[piecePositionX][piecePositionY + 3] != MOVING))
							 | 
						|
								        {    
							 | 
						|
								            checker = true;
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								        if ((grid[piecePositionX + 1][piecePositionY] == MOVING) &&
							 | 
						|
								            (grid[piecePositionX][piecePositionY + 2] != EMPTY) &&
							 | 
						|
								            (grid[piecePositionX][piecePositionY + 2] != MOVING))
							 | 
						|
								        {    
							 | 
						|
								            checker = true;
							 | 
						|
								        }
							 | 
						|
								        if ((grid[piecePositionX + 3][piecePositionY + 1] == MOVING) &&
							 | 
						|
								            (grid[piecePositionX + 1][piecePositionY] != EMPTY) &&
							 | 
						|
								            (grid[piecePositionX + 1][piecePositionY] != MOVING))
							 | 
						|
								        {    
							 | 
						|
								            checker = true;
							 | 
						|
								        }
							 | 
						|
								        if ((grid[piecePositionX + 2][piecePositionY + 3] == MOVING) &&
							 | 
						|
								            (grid[piecePositionX + 3][piecePositionY + 1] != EMPTY) &&
							 | 
						|
								            (grid[piecePositionX + 3][piecePositionY + 1] != MOVING))
							 | 
						|
								        {    
							 | 
						|
								            checker = true;
							 | 
						|
								        }
							 | 
						|
								        if ((grid[piecePositionX][piecePositionY + 2] == MOVING) &&
							 | 
						|
								            (grid[piecePositionX + 2][piecePositionY + 3] != EMPTY) &&
							 | 
						|
								            (grid[piecePositionX + 2][piecePositionY + 3] != MOVING))
							 | 
						|
								        {    
							 | 
						|
								            checker = true;
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								        if ((grid[piecePositionX + 2][piecePositionY] == MOVING) &&
							 | 
						|
								            (grid[piecePositionX][piecePositionY + 1] != EMPTY) &&
							 | 
						|
								            (grid[piecePositionX][piecePositionY + 1] != MOVING))
							 | 
						|
								        {    
							 | 
						|
								            checker = true;
							 | 
						|
								        }
							 | 
						|
								        if ((grid[piecePositionX + 3][piecePositionY + 2] == MOVING) &&
							 | 
						|
								            (grid[piecePositionX + 2][piecePositionY] != EMPTY) &&
							 | 
						|
								            (grid[piecePositionX + 2][piecePositionY] != MOVING))
							 | 
						|
								        {    
							 | 
						|
								            checker = true;
							 | 
						|
								        }
							 | 
						|
								        if ((grid[piecePositionX + 1][piecePositionY + 3] == MOVING) &&
							 | 
						|
								            (grid[piecePositionX + 3][piecePositionY + 2] != EMPTY) &&
							 | 
						|
								            (grid[piecePositionX + 3][piecePositionY + 2] != MOVING))
							 | 
						|
								        {    
							 | 
						|
								            checker = true;
							 | 
						|
								        }
							 | 
						|
								        if ((grid[piecePositionX][piecePositionY + 1] == MOVING) &&
							 | 
						|
								            (grid[piecePositionX + 1][piecePositionY + 3] != EMPTY) &&
							 | 
						|
								            (grid[piecePositionX + 1][piecePositionY + 3] != MOVING))
							 | 
						|
								        {    
							 | 
						|
								            checker = true;
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        if ((grid[piecePositionX + 1][piecePositionY + 1] == MOVING) &&
							 | 
						|
								            (grid[piecePositionX + 1][piecePositionY + 2] != EMPTY) &&
							 | 
						|
								            (grid[piecePositionX + 1][piecePositionY + 2] != MOVING))
							 | 
						|
								        {    
							 | 
						|
								            checker = true;
							 | 
						|
								        }
							 | 
						|
								        
							 | 
						|
								        if ((grid[piecePositionX + 2][piecePositionY + 1] == MOVING) &&
							 | 
						|
								            (grid[piecePositionX + 1][piecePositionY + 1] != EMPTY) &&
							 | 
						|
								            (grid[piecePositionX + 1][piecePositionY + 1] != MOVING))
							 | 
						|
								        {    
							 | 
						|
								            checker = true;
							 | 
						|
								        }
							 | 
						|
								        if ((grid[piecePositionX + 2][piecePositionY + 2] == MOVING) &&
							 | 
						|
								            (grid[piecePositionX + 2][piecePositionY + 1] != EMPTY) &&
							 | 
						|
								            (grid[piecePositionX + 2][piecePositionY + 1] != MOVING))
							 | 
						|
								        {    
							 | 
						|
								            checker = true;
							 | 
						|
								        }
							 | 
						|
								        if ((grid[piecePositionX + 1][piecePositionY + 2] == MOVING) &&
							 | 
						|
								            (grid[piecePositionX + 2][piecePositionY + 2] != EMPTY) &&
							 | 
						|
								            (grid[piecePositionX + 2][piecePositionY + 2] != MOVING))
							 | 
						|
								        {    
							 | 
						|
								            checker = true;
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        if (!checker)
							 | 
						|
								        {
							 | 
						|
								            aux = piece[0][0];
							 | 
						|
								            piece[0][0] = piece[3][0];
							 | 
						|
								            piece[3][0] = piece[3][3];
							 | 
						|
								            piece[3][3] = piece[0][3];
							 | 
						|
								            piece[0][3] = aux;
							 | 
						|
								
							 | 
						|
								            aux = piece[1][0];
							 | 
						|
								            piece[1][0] = piece[3][1];
							 | 
						|
								            piece[3][1] = piece[2][3];
							 | 
						|
								            piece[2][3] = piece[0][2];
							 | 
						|
								            piece[0][2] = aux;
							 | 
						|
								
							 | 
						|
								            aux = piece[2][0];
							 | 
						|
								            piece[2][0] = piece[3][2];
							 | 
						|
								            piece[3][2] = piece[1][3];
							 | 
						|
								            piece[1][3] = piece[0][1];
							 | 
						|
								            piece[0][1] = aux;
							 | 
						|
								
							 | 
						|
								            aux = piece[1][1];
							 | 
						|
								            piece[1][1] = piece[2][1];
							 | 
						|
								            piece[2][1] = piece[2][2];
							 | 
						|
								            piece[2][2] = piece[1][2];
							 | 
						|
								            piece[1][2] = aux;
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
							 | 
						|
								        {
							 | 
						|
								            for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++)
							 | 
						|
								            {
							 | 
						|
								                if (grid[i][j] == MOVING)
							 | 
						|
								                {
							 | 
						|
								                    grid[i][j] = EMPTY;
							 | 
						|
								                }
							 | 
						|
								            }
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        for (int i = piecePositionX; i < piecePositionX + 4; i++)
							 | 
						|
								        {
							 | 
						|
								            for (int j = piecePositionY; j < piecePositionY + 4; j++)
							 | 
						|
								            {
							 | 
						|
								                if (piece[i - piecePositionX][j - piecePositionY] == MOVING)
							 | 
						|
								                {
							 | 
						|
								                    grid[i][j] = MOVING;
							 | 
						|
								                }
							 | 
						|
								            }
							 | 
						|
								        }
							 | 
						|
								        return true;
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    return false;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								static void CheckDetection(bool *detection)
							 | 
						|
								{
							 | 
						|
								    for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
							 | 
						|
								    {
							 | 
						|
								        for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++)
							 | 
						|
								        {
							 | 
						|
								            if ((grid[i][j] == MOVING) && ((grid[i][j+1] == FULL) || (grid[i][j+1] == BLOCK))) *detection = true;
							 | 
						|
								        }
							 | 
						|
								    }
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								static void CheckCompletition(bool *lineToDelete)
							 | 
						|
								{
							 | 
						|
								    int calculator;
							 | 
						|
								
							 | 
						|
								    for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
							 | 
						|
								    {
							 | 
						|
								        calculator = 0;
							 | 
						|
								        for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++)
							 | 
						|
								        {
							 | 
						|
								            // Count each square of the line
							 | 
						|
								            if (grid[i][j] == FULL)
							 | 
						|
								            {
							 | 
						|
								                calculator++;
							 | 
						|
								            }
							 | 
						|
								
							 | 
						|
								            // Check if we completed the whole line
							 | 
						|
								            if (calculator == GRID_HORIZONTAL_SIZE - 2)
							 | 
						|
								            {
							 | 
						|
								                *lineToDelete = true;
							 | 
						|
								                calculator = 0;
							 | 
						|
								                // points++;
							 | 
						|
								
							 | 
						|
								                // Mark the completed line
							 | 
						|
								                for (int z = 1; z < GRID_HORIZONTAL_SIZE - 1; z++)
							 | 
						|
								                {
							 | 
						|
								                    grid[z][j] = FADING;
							 | 
						|
								                }
							 | 
						|
								            }
							 | 
						|
								        }
							 | 
						|
								    }
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								static void DeleteCompleteLines()
							 | 
						|
								{
							 | 
						|
								    // erase the completed line
							 | 
						|
								    for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
							 | 
						|
								    {
							 | 
						|
								        while (grid[1][j] == FADING)
							 | 
						|
								        {
							 | 
						|
								            for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++)
							 | 
						|
								            {
							 | 
						|
								                grid[i][j] = EMPTY;
							 | 
						|
								            }
							 | 
						|
								            for (int j2 = j-1; j2 >= 0; j2--)
							 | 
						|
								            {
							 | 
						|
								                for (int i2 = 1; i2 < GRID_HORIZONTAL_SIZE - 1; i2++)
							 | 
						|
								                {
							 | 
						|
								                    if (grid[i2][j2] == FULL)
							 | 
						|
								                    {
							 | 
						|
								                        grid[i2][j2+1] = FULL;
							 | 
						|
								                        grid[i2][j2] = EMPTY;
							 | 
						|
								                    }
							 | 
						|
								                    else if (grid[i2][j2] == FADING)
							 | 
						|
								                    {
							 | 
						|
								                        grid[i2][j2+1] = FADING;
							 | 
						|
								                        grid[i2][j2] = EMPTY;
							 | 
						|
								                    }
							 | 
						|
								                }
							 | 
						|
								            }
							 | 
						|
								        }
							 | 
						|
								    }
							 | 
						|
								}
							 |