Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

791 linhas
26 KiB

  1. /*******************************************************************************************
  2. *
  3. * raylib - sample game: tetris
  4. *
  5. * Sample game Marc Palau and Ramon Santamaria
  6. *
  7. * This game has been created using raylib v1.3 (www.raylib.com)
  8. * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
  9. *
  10. * Copyright (c) 2015 Ramon Santamaria (@raysan5)
  11. *
  12. ********************************************************************************************/
  13. #include "raylib.h"
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <time.h>
  17. #include <math.h>
  18. #if defined(PLATFORM_WEB)
  19. #include <emscripten/emscripten.h>
  20. #endif
  21. //----------------------------------------------------------------------------------
  22. // Some Defines
  23. //----------------------------------------------------------------------------------
  24. #define SQUARE_SIZE 20
  25. #define GRID_HORIZONTAL_SIZE 12
  26. #define GRID_VERTICAL_SIZE 20
  27. #define LATERAL_SPEED 10
  28. #define TURNING_SPEED 12
  29. #define FAST_FALL_AWAIT_COUNTER 30
  30. #define FADING_TIME 33
  31. //----------------------------------------------------------------------------------
  32. // Types and Structures Definition
  33. //----------------------------------------------------------------------------------
  34. typedef enum GridSquare { EMPTY, MOVING, FULL, BLOCK, FADING } GridSquare;
  35. //------------------------------------------------------------------------------------
  36. // Global Variables Declaration
  37. //------------------------------------------------------------------------------------
  38. static const int screenWidth = 800;
  39. static const int screenHeight = 450;
  40. static bool gameOver = false;
  41. static bool pause = false;
  42. // Matrices
  43. static GridSquare grid [GRID_HORIZONTAL_SIZE][GRID_VERTICAL_SIZE];
  44. static GridSquare piece [4][4];
  45. static GridSquare incomingPiece [4][4];
  46. // Theese variables keep track of the active piece position
  47. static int piecePositionX = 0;
  48. static int piecePositionY = 0;
  49. // Game parameters
  50. static Color fadingColor;
  51. //static int fallingSpeed; // In frames
  52. static bool beginPlay = true; // This var is only true at the begining of the game, used for the first matrix creations
  53. static bool pieceActive = false;
  54. static bool detection = false;
  55. static bool lineToDelete = false;
  56. // Statistics
  57. static int level = 1;
  58. static int lines = 0;
  59. // Counters
  60. static int gravityMovementCounter = 0;
  61. static int lateralMovementCounter = 0;
  62. static int turnMovementCounter = 0;
  63. static int fastFallMovementCounter = 0;
  64. static int fadeLineCounter = 0;
  65. // Based on level
  66. static int gravitySpeed = 30;
  67. //------------------------------------------------------------------------------------
  68. // Module Functions Declaration (local)
  69. //------------------------------------------------------------------------------------
  70. static void InitGame(void); // Initialize game
  71. static void UpdateGame(void); // Update game (one frame)
  72. static void DrawGame(void); // Draw game (one frame)
  73. static void UnloadGame(void); // Unload game
  74. static void UpdateDrawFrame(void); // Update and Draw (one frame)
  75. // Additional module functions
  76. static bool Createpiece();
  77. static void GetRandompiece();
  78. static void ResolveFallingMovement();
  79. static bool ResolveLateralMovement();
  80. static bool ResolveTurnMovement();
  81. static void CheckDetection();
  82. static void CheckCompletion();
  83. static void DeleteCompleteLines();
  84. //------------------------------------------------------------------------------------
  85. // Program main entry point
  86. //------------------------------------------------------------------------------------
  87. int main(void)
  88. {
  89. // Initialization (Note windowTitle is unused on Android)
  90. //---------------------------------------------------------
  91. InitWindow(screenWidth, screenHeight, "sample game: tetris");
  92. InitGame();
  93. #if defined(PLATFORM_WEB)
  94. emscripten_set_main_loop(UpdateDrawFrame, 0, 1);
  95. #else
  96. SetTargetFPS(60);
  97. //--------------------------------------------------------------------------------------
  98. // Main game loop
  99. while (!WindowShouldClose()) // Detect window close button or ESC key
  100. {
  101. // Update and Draw
  102. //----------------------------------------------------------------------------------
  103. UpdateDrawFrame();
  104. //----------------------------------------------------------------------------------
  105. }
  106. #endif
  107. // De-Initialization
  108. //--------------------------------------------------------------------------------------
  109. UnloadGame(); // Unload loaded data (textures, sounds, models...)
  110. CloseWindow(); // Close window and OpenGL context
  111. //--------------------------------------------------------------------------------------
  112. return 0;
  113. }
  114. //--------------------------------------------------------------------------------------
  115. // Game Module Functions Definition
  116. //--------------------------------------------------------------------------------------
  117. // Initialize game variables
  118. void InitGame(void)
  119. {
  120. // Initialize game statistics
  121. level = 1;
  122. lines = 0;
  123. fadingColor = GRAY;
  124. piecePositionX = 0;
  125. piecePositionY = 0;
  126. pause = false;
  127. beginPlay = true;
  128. pieceActive = false;
  129. detection = false;
  130. lineToDelete = false;
  131. // Counters
  132. gravityMovementCounter = 0;
  133. lateralMovementCounter = 0;
  134. turnMovementCounter = 0;
  135. fastFallMovementCounter = 0;
  136. fadeLineCounter = 0;
  137. gravitySpeed = 30;
  138. // Initialize grid matrices
  139. for (int i = 0; i < GRID_HORIZONTAL_SIZE; i++)
  140. {
  141. for (int j = 0; j < GRID_VERTICAL_SIZE; j++)
  142. {
  143. if ((j == GRID_VERTICAL_SIZE - 1) || (i == 0) || (i == GRID_HORIZONTAL_SIZE - 1)) grid[i][j] = BLOCK;
  144. else grid[i][j] = EMPTY;
  145. }
  146. }
  147. // Initialize incoming piece matrices
  148. for (int i = 0; i < 4; i++)
  149. {
  150. for (int j = 0; j< 4; j++)
  151. {
  152. incomingPiece[i][j] = EMPTY;
  153. }
  154. }
  155. }
  156. // Update game (one frame)
  157. void UpdateGame(void)
  158. {
  159. if (!gameOver)
  160. {
  161. if (IsKeyPressed('P')) pause = !pause;
  162. if (!pause)
  163. {
  164. if (!lineToDelete)
  165. {
  166. if (!pieceActive)
  167. {
  168. // Get another piece
  169. pieceActive = Createpiece();
  170. // We leave a little time before starting the fast falling down
  171. fastFallMovementCounter = 0;
  172. }
  173. else // Piece falling
  174. {
  175. // Counters update
  176. fastFallMovementCounter++;
  177. gravityMovementCounter++;
  178. lateralMovementCounter++;
  179. turnMovementCounter++;
  180. // We make sure to move if we've pressed the key this frame
  181. if (IsKeyPressed(KEY_LEFT) || IsKeyPressed(KEY_RIGHT)) lateralMovementCounter = LATERAL_SPEED;
  182. if (IsKeyPressed(KEY_UP)) turnMovementCounter = TURNING_SPEED;
  183. // Fall down
  184. if (IsKeyDown(KEY_DOWN) && (fastFallMovementCounter >= FAST_FALL_AWAIT_COUNTER))
  185. {
  186. // We make sure the piece is going to fall this frame
  187. gravityMovementCounter += gravitySpeed;
  188. }
  189. if (gravityMovementCounter >= gravitySpeed)
  190. {
  191. // Basic falling movement
  192. CheckDetection(&detection);
  193. // Check if the piece has collided with another piece or with the boundings
  194. ResolveFallingMovement(&detection, &pieceActive);
  195. // Check if we fullfilled a line and if so, erase the line and pull down the the lines above
  196. CheckCompletion(&lineToDelete);
  197. gravityMovementCounter = 0;
  198. }
  199. // Move laterally at player's will
  200. if (lateralMovementCounter >= LATERAL_SPEED)
  201. {
  202. // Update the lateral movement and if success, reset the lateral counter
  203. if (!ResolveLateralMovement()) lateralMovementCounter = 0;
  204. }
  205. // Turn the piece at player's will
  206. if (turnMovementCounter >= TURNING_SPEED)
  207. {
  208. // Update the turning movement and reset the turning counter
  209. if (ResolveTurnMovement()) turnMovementCounter = 0;
  210. }
  211. }
  212. // Game over logic
  213. for (int j = 0; j < 2; j++)
  214. {
  215. for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++)
  216. {
  217. if (grid[i][j] == FULL)
  218. {
  219. gameOver = true;
  220. }
  221. }
  222. }
  223. }
  224. else
  225. {
  226. // Animation when deleting lines
  227. fadeLineCounter++;
  228. if (fadeLineCounter%8 < 4) fadingColor = MAROON;
  229. else fadingColor = GRAY;
  230. if (fadeLineCounter >= FADING_TIME)
  231. {
  232. DeleteCompleteLines();
  233. fadeLineCounter = 0;
  234. lineToDelete = false;
  235. lines++;
  236. }
  237. }
  238. }
  239. }
  240. else
  241. {
  242. if (IsKeyPressed(KEY_ENTER))
  243. {
  244. InitGame();
  245. gameOver = false;
  246. }
  247. }
  248. }
  249. // Draw game (one frame)
  250. void DrawGame(void)
  251. {
  252. BeginDrawing();
  253. ClearBackground(RAYWHITE);
  254. if (!gameOver)
  255. {
  256. // Draw gameplay area
  257. Vector2 offset;
  258. offset.x = screenWidth/2 - (GRID_HORIZONTAL_SIZE*SQUARE_SIZE/2) - 50;
  259. offset.y = screenHeight/2 - ((GRID_VERTICAL_SIZE - 1)*SQUARE_SIZE/2) + SQUARE_SIZE*2;
  260. offset.y -= 50; // NOTE: Harcoded position!
  261. int controller = offset.x;
  262. for (int j = 0; j < GRID_VERTICAL_SIZE; j++)
  263. {
  264. for (int i = 0; i < GRID_HORIZONTAL_SIZE; i++)
  265. {
  266. // Draw each square of the grid
  267. if (grid[i][j] == EMPTY)
  268. {
  269. DrawLine(offset.x, offset.y, offset.x + SQUARE_SIZE, offset.y, LIGHTGRAY );
  270. DrawLine(offset.x, offset.y, offset.x, offset.y + SQUARE_SIZE, LIGHTGRAY );
  271. DrawLine(offset.x + SQUARE_SIZE, offset.y, offset.x + SQUARE_SIZE, offset.y + SQUARE_SIZE, LIGHTGRAY );
  272. DrawLine(offset.x, offset.y + SQUARE_SIZE, offset.x + SQUARE_SIZE, offset.y + SQUARE_SIZE, LIGHTGRAY );
  273. offset.x += SQUARE_SIZE;
  274. }
  275. else if (grid[i][j] == FULL)
  276. {
  277. DrawRectangle(offset.x, offset.y, SQUARE_SIZE, SQUARE_SIZE, GRAY);
  278. offset.x += SQUARE_SIZE;
  279. }
  280. else if (grid[i][j] == MOVING)
  281. {
  282. DrawRectangle(offset.x, offset.y, SQUARE_SIZE, SQUARE_SIZE, DARKGRAY);
  283. offset.x += SQUARE_SIZE;
  284. }
  285. else if (grid[i][j] == BLOCK)
  286. {
  287. DrawRectangle(offset.x, offset.y, SQUARE_SIZE, SQUARE_SIZE, LIGHTGRAY);
  288. offset.x += SQUARE_SIZE;
  289. }
  290. else if (grid[i][j] == FADING)
  291. {
  292. DrawRectangle(offset.x, offset.y, SQUARE_SIZE, SQUARE_SIZE, fadingColor);
  293. offset.x += SQUARE_SIZE;
  294. }
  295. }
  296. offset.x = controller;
  297. offset.y += SQUARE_SIZE;
  298. }
  299. // Draw incoming piece (hardcoded)
  300. offset.x = 500;
  301. offset.y = 45;
  302. int controler = offset.x;
  303. for (int j = 0; j < 4; j++)
  304. {
  305. for (int i = 0; i < 4; i++)
  306. {
  307. if (incomingPiece[i][j] == EMPTY)
  308. {
  309. DrawLine(offset.x, offset.y, offset.x + SQUARE_SIZE, offset.y, LIGHTGRAY );
  310. DrawLine(offset.x, offset.y, offset.x, offset.y + SQUARE_SIZE, LIGHTGRAY );
  311. DrawLine(offset.x + SQUARE_SIZE, offset.y, offset.x + SQUARE_SIZE, offset.y + SQUARE_SIZE, LIGHTGRAY );
  312. DrawLine(offset.x, offset.y + SQUARE_SIZE, offset.x + SQUARE_SIZE, offset.y + SQUARE_SIZE, LIGHTGRAY );
  313. offset.x += SQUARE_SIZE;
  314. }
  315. else if (incomingPiece[i][j] == MOVING)
  316. {
  317. DrawRectangle(offset.x, offset.y, SQUARE_SIZE, SQUARE_SIZE, GRAY);
  318. offset.x += SQUARE_SIZE;
  319. }
  320. }
  321. offset.x = controler;
  322. offset.y += SQUARE_SIZE;
  323. }
  324. DrawText("INCOMING:", offset.x, offset.y - 100, 10, GRAY);
  325. DrawText(TextFormat("LINES: %04i", lines), offset.x, offset.y + 20, 10, GRAY);
  326. if (pause) DrawText("GAME PAUSED", screenWidth/2 - MeasureText("GAME PAUSED", 40)/2, screenHeight/2 - 40, 40, GRAY);
  327. }
  328. else DrawText("PRESS [ENTER] TO PLAY AGAIN", GetScreenWidth()/2 - MeasureText("PRESS [ENTER] TO PLAY AGAIN", 20)/2, GetScreenHeight()/2 - 50, 20, GRAY);
  329. EndDrawing();
  330. }
  331. // Unload game variables
  332. void UnloadGame(void)
  333. {
  334. // TODO: Unload all dynamic loaded data (textures, sounds, models...)
  335. }
  336. // Update and Draw (one frame)
  337. void UpdateDrawFrame(void)
  338. {
  339. UpdateGame();
  340. DrawGame();
  341. }
  342. //--------------------------------------------------------------------------------------
  343. // Additional module functions
  344. //--------------------------------------------------------------------------------------
  345. static bool Createpiece()
  346. {
  347. piecePositionX = (int)((GRID_HORIZONTAL_SIZE - 4)/2);
  348. piecePositionY = 0;
  349. // If the game is starting and you are going to create the first piece, we create an extra one
  350. if (beginPlay)
  351. {
  352. GetRandompiece();
  353. beginPlay = false;
  354. }
  355. // We assign the incoming piece to the actual piece
  356. for (int i = 0; i < 4; i++)
  357. {
  358. for (int j = 0; j< 4; j++)
  359. {
  360. piece[i][j] = incomingPiece[i][j];
  361. }
  362. }
  363. // We assign a random piece to the incoming one
  364. GetRandompiece();
  365. // Assign the piece to the grid
  366. for (int i = piecePositionX; i < piecePositionX + 4; i++)
  367. {
  368. for (int j = 0; j < 4; j++)
  369. {
  370. if (piece[i - (int)piecePositionX][j] == MOVING) grid[i][j] = MOVING;
  371. }
  372. }
  373. return true;
  374. }
  375. static void GetRandompiece()
  376. {
  377. int random = GetRandomValue(0, 6);
  378. for (int i = 0; i < 4; i++)
  379. {
  380. for (int j = 0; j < 4; j++)
  381. {
  382. incomingPiece[i][j] = EMPTY;
  383. }
  384. }
  385. switch (random)
  386. {
  387. case 0: { incomingPiece[1][1] = MOVING; incomingPiece[2][1] = MOVING; incomingPiece[1][2] = MOVING; incomingPiece[2][2] = MOVING; } break; //Cube
  388. case 1: { incomingPiece[1][0] = MOVING; incomingPiece[1][1] = MOVING; incomingPiece[1][2] = MOVING; incomingPiece[2][2] = MOVING; } break; //L
  389. case 2: { incomingPiece[1][2] = MOVING; incomingPiece[2][0] = MOVING; incomingPiece[2][1] = MOVING; incomingPiece[2][2] = MOVING; } break; //L inversa
  390. case 3: { incomingPiece[0][1] = MOVING; incomingPiece[1][1] = MOVING; incomingPiece[2][1] = MOVING; incomingPiece[3][1] = MOVING; } break; //Recta
  391. case 4: { incomingPiece[1][0] = MOVING; incomingPiece[1][1] = MOVING; incomingPiece[1][2] = MOVING; incomingPiece[2][1] = MOVING; } break; //Creu tallada
  392. case 5: { incomingPiece[1][1] = MOVING; incomingPiece[2][1] = MOVING; incomingPiece[2][2] = MOVING; incomingPiece[3][2] = MOVING; } break; //S
  393. case 6: { incomingPiece[1][2] = MOVING; incomingPiece[2][2] = MOVING; incomingPiece[2][1] = MOVING; incomingPiece[3][1] = MOVING; } break; //S inversa
  394. }
  395. }
  396. static void ResolveFallingMovement(bool *detection, bool *pieceActive)
  397. {
  398. // If we finished moving this piece, we stop it
  399. if (*detection)
  400. {
  401. for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
  402. {
  403. for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++)
  404. {
  405. if (grid[i][j] == MOVING)
  406. {
  407. grid[i][j] = FULL;
  408. *detection = false;
  409. *pieceActive = false;
  410. }
  411. }
  412. }
  413. }
  414. else // We move down the piece
  415. {
  416. for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
  417. {
  418. for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++)
  419. {
  420. if (grid[i][j] == MOVING)
  421. {
  422. grid[i][j+1] = MOVING;
  423. grid[i][j] = EMPTY;
  424. }
  425. }
  426. }
  427. piecePositionY++;
  428. }
  429. }
  430. static bool ResolveLateralMovement()
  431. {
  432. bool collision = false;
  433. // Piece movement
  434. if (IsKeyDown(KEY_LEFT)) // Move left
  435. {
  436. // Check if is possible to move to left
  437. for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
  438. {
  439. for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++)
  440. {
  441. if (grid[i][j] == MOVING)
  442. {
  443. // Check if we are touching the left wall or we have a full square at the left
  444. if ((i-1 == 0) || (grid[i-1][j] == FULL)) collision = true;
  445. }
  446. }
  447. }
  448. // If able, move left
  449. if (!collision)
  450. {
  451. for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
  452. {
  453. for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++) // We check the matrix from left to right
  454. {
  455. // Move everything to the left
  456. if (grid[i][j] == MOVING)
  457. {
  458. grid[i-1][j] = MOVING;
  459. grid[i][j] = EMPTY;
  460. }
  461. }
  462. }
  463. piecePositionX--;
  464. }
  465. }
  466. else if (IsKeyDown(KEY_RIGHT)) // Move right
  467. {
  468. // Check if is possible to move to right
  469. for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
  470. {
  471. for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++)
  472. {
  473. if (grid[i][j] == MOVING)
  474. {
  475. // Check if we are touching the right wall or we have a full square at the right
  476. if ((i+1 == GRID_HORIZONTAL_SIZE - 1) || (grid[i+1][j] == FULL))
  477. {
  478. collision = true;
  479. }
  480. }
  481. }
  482. }
  483. // If able move right
  484. if (!collision)
  485. {
  486. for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
  487. {
  488. for (int i = GRID_HORIZONTAL_SIZE - 1; i >= 1; i--) // We check the matrix from right to left
  489. {
  490. // Move everything to the right
  491. if (grid[i][j] == MOVING)
  492. {
  493. grid[i+1][j] = MOVING;
  494. grid[i][j] = EMPTY;
  495. }
  496. }
  497. }
  498. piecePositionX++;
  499. }
  500. }
  501. return collision;
  502. }
  503. static bool ResolveTurnMovement()
  504. {
  505. // Input for turning the piece
  506. if (IsKeyDown(KEY_UP))
  507. {
  508. int aux = 0;
  509. bool checker = false;
  510. // Check all turning possibilities
  511. if ((grid[piecePositionX + 3][piecePositionY] == MOVING) &&
  512. (grid[piecePositionX][piecePositionY] != EMPTY) &&
  513. (grid[piecePositionX][piecePositionY] != MOVING)) checker = true;
  514. if ((grid[piecePositionX + 3][piecePositionY + 3] == MOVING) &&
  515. (grid[piecePositionX + 3][piecePositionY] != EMPTY) &&
  516. (grid[piecePositionX + 3][piecePositionY] != MOVING)) checker = true;
  517. if ((grid[piecePositionX][piecePositionY + 3] == MOVING) &&
  518. (grid[piecePositionX + 3][piecePositionY + 3] != EMPTY) &&
  519. (grid[piecePositionX + 3][piecePositionY + 3] != MOVING)) checker = true;
  520. if ((grid[piecePositionX][piecePositionY] == MOVING) &&
  521. (grid[piecePositionX][piecePositionY + 3] != EMPTY) &&
  522. (grid[piecePositionX][piecePositionY + 3] != MOVING)) checker = true;
  523. if ((grid[piecePositionX + 1][piecePositionY] == MOVING) &&
  524. (grid[piecePositionX][piecePositionY + 2] != EMPTY) &&
  525. (grid[piecePositionX][piecePositionY + 2] != MOVING)) checker = true;
  526. if ((grid[piecePositionX + 3][piecePositionY + 1] == MOVING) &&
  527. (grid[piecePositionX + 1][piecePositionY] != EMPTY) &&
  528. (grid[piecePositionX + 1][piecePositionY] != MOVING)) checker = true;
  529. if ((grid[piecePositionX + 2][piecePositionY + 3] == MOVING) &&
  530. (grid[piecePositionX + 3][piecePositionY + 1] != EMPTY) &&
  531. (grid[piecePositionX + 3][piecePositionY + 1] != MOVING)) checker = true;
  532. if ((grid[piecePositionX][piecePositionY + 2] == MOVING) &&
  533. (grid[piecePositionX + 2][piecePositionY + 3] != EMPTY) &&
  534. (grid[piecePositionX + 2][piecePositionY + 3] != MOVING)) checker = true;
  535. if ((grid[piecePositionX + 2][piecePositionY] == MOVING) &&
  536. (grid[piecePositionX][piecePositionY + 1] != EMPTY) &&
  537. (grid[piecePositionX][piecePositionY + 1] != MOVING)) checker = true;
  538. if ((grid[piecePositionX + 3][piecePositionY + 2] == MOVING) &&
  539. (grid[piecePositionX + 2][piecePositionY] != EMPTY) &&
  540. (grid[piecePositionX + 2][piecePositionY] != MOVING)) checker = true;
  541. if ((grid[piecePositionX + 1][piecePositionY + 3] == MOVING) &&
  542. (grid[piecePositionX + 3][piecePositionY + 2] != EMPTY) &&
  543. (grid[piecePositionX + 3][piecePositionY + 2] != MOVING)) checker = true;
  544. if ((grid[piecePositionX][piecePositionY + 1] == MOVING) &&
  545. (grid[piecePositionX + 1][piecePositionY + 3] != EMPTY) &&
  546. (grid[piecePositionX + 1][piecePositionY + 3] != MOVING)) checker = true;
  547. if ((grid[piecePositionX + 1][piecePositionY + 1] == MOVING) &&
  548. (grid[piecePositionX + 1][piecePositionY + 2] != EMPTY) &&
  549. (grid[piecePositionX + 1][piecePositionY + 2] != MOVING)) checker = true;
  550. if ((grid[piecePositionX + 2][piecePositionY + 1] == MOVING) &&
  551. (grid[piecePositionX + 1][piecePositionY + 1] != EMPTY) &&
  552. (grid[piecePositionX + 1][piecePositionY + 1] != MOVING)) checker = true;
  553. if ((grid[piecePositionX + 2][piecePositionY + 2] == MOVING) &&
  554. (grid[piecePositionX + 2][piecePositionY + 1] != EMPTY) &&
  555. (grid[piecePositionX + 2][piecePositionY + 1] != MOVING)) checker = true;
  556. if ((grid[piecePositionX + 1][piecePositionY + 2] == MOVING) &&
  557. (grid[piecePositionX + 2][piecePositionY + 2] != EMPTY) &&
  558. (grid[piecePositionX + 2][piecePositionY + 2] != MOVING)) checker = true;
  559. if (!checker)
  560. {
  561. aux = piece[0][0];
  562. piece[0][0] = piece[3][0];
  563. piece[3][0] = piece[3][3];
  564. piece[3][3] = piece[0][3];
  565. piece[0][3] = aux;
  566. aux = piece[1][0];
  567. piece[1][0] = piece[3][1];
  568. piece[3][1] = piece[2][3];
  569. piece[2][3] = piece[0][2];
  570. piece[0][2] = aux;
  571. aux = piece[2][0];
  572. piece[2][0] = piece[3][2];
  573. piece[3][2] = piece[1][3];
  574. piece[1][3] = piece[0][1];
  575. piece[0][1] = aux;
  576. aux = piece[1][1];
  577. piece[1][1] = piece[2][1];
  578. piece[2][1] = piece[2][2];
  579. piece[2][2] = piece[1][2];
  580. piece[1][2] = aux;
  581. }
  582. for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
  583. {
  584. for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++)
  585. {
  586. if (grid[i][j] == MOVING)
  587. {
  588. grid[i][j] = EMPTY;
  589. }
  590. }
  591. }
  592. for (int i = piecePositionX; i < piecePositionX + 4; i++)
  593. {
  594. for (int j = piecePositionY; j < piecePositionY + 4; j++)
  595. {
  596. if (piece[i - piecePositionX][j - piecePositionY] == MOVING)
  597. {
  598. grid[i][j] = MOVING;
  599. }
  600. }
  601. }
  602. return true;
  603. }
  604. return false;
  605. }
  606. static void CheckDetection(bool *detection)
  607. {
  608. for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
  609. {
  610. for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++)
  611. {
  612. if ((grid[i][j] == MOVING) && ((grid[i][j+1] == FULL) || (grid[i][j+1] == BLOCK))) *detection = true;
  613. }
  614. }
  615. }
  616. static void CheckCompletion(bool *lineToDelete)
  617. {
  618. int calculator = 0;
  619. for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
  620. {
  621. calculator = 0;
  622. for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++)
  623. {
  624. // Count each square of the line
  625. if (grid[i][j] == FULL)
  626. {
  627. calculator++;
  628. }
  629. // Check if we completed the whole line
  630. if (calculator == GRID_HORIZONTAL_SIZE - 2)
  631. {
  632. *lineToDelete = true;
  633. calculator = 0;
  634. // points++;
  635. // Mark the completed line
  636. for (int z = 1; z < GRID_HORIZONTAL_SIZE - 1; z++)
  637. {
  638. grid[z][j] = FADING;
  639. }
  640. }
  641. }
  642. }
  643. }
  644. static void DeleteCompleteLines()
  645. {
  646. // Erase the completed line
  647. for (int j = GRID_VERTICAL_SIZE - 2; j >= 0; j--)
  648. {
  649. while (grid[1][j] == FADING)
  650. {
  651. for (int i = 1; i < GRID_HORIZONTAL_SIZE - 1; i++)
  652. {
  653. grid[i][j] = EMPTY;
  654. }
  655. for (int j2 = j-1; j2 >= 0; j2--)
  656. {
  657. for (int i2 = 1; i2 < GRID_HORIZONTAL_SIZE - 1; i2++)
  658. {
  659. if (grid[i2][j2] == FULL)
  660. {
  661. grid[i2][j2+1] = FULL;
  662. grid[i2][j2] = EMPTY;
  663. }
  664. else if (grid[i2][j2] == FADING)
  665. {
  666. grid[i2][j2+1] = FADING;
  667. grid[i2][j2] = EMPTY;
  668. }
  669. }
  670. }
  671. }
  672. }
  673. }