| /******************************************************************************************* | |
| * | |
| *   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() | |
| { | |
|     // Initialization | |
|     //-------------------------------------------------------------------------------------- | |
|     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 | |
|         //---------------------------------------------------------------------------------- | |
|         UpdateGame(); | |
|         //---------------------------------------------------------------------------------- | |
|  | |
|         // Draw | |
|         //---------------------------------------------------------------------------------- | |
|         DrawGame(); | |
|         //---------------------------------------------------------------------------------- | |
|     } | |
| #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; | |
|                     } | |
|                 } | |
|             } | |
|         } | |
|     } | |
| } |