From 7eaec7cf753cc1c4e9980f01801e651e0c3342d8 Mon Sep 17 00:00:00 2001
From: Murray Fordyce <undeadherbs@gmail.com>
Date: Sun, 12 Mar 2023 00:30:13 -0600
Subject: [PATCH] Fixed bug in Tetris

Game re-places the last piece after it is placed and a new one is generated.
This only happens sometimes, I think because it depends on how the location was reached and isn't visible if lines weren't removed.
---
 .../plugins/tetris_game/tetris_game.c         | 85 +++++++++----------
 1 file changed, 40 insertions(+), 45 deletions(-)

diff --git a/applications/plugins/tetris_game/tetris_game.c b/applications/plugins/tetris_game/tetris_game.c
index a569f46d42..dad2109855 100644
--- a/applications/plugins/tetris_game/tetris_game.c
+++ b/applications/plugins/tetris_game/tetris_game.c
@@ -296,59 +296,54 @@ static void
     tetris_game_process_step(TetrisState* tetris_state, Piece* newPiece, bool wasDownMove) {
     if(tetris_state->gameState == GameStateGameOver) return;
 
-    tetris_game_remove_curr_piece(tetris_state);
-
-    if(wasDownMove) {
-        if(tetris_game_piece_at_bottom(tetris_state, newPiece)) {
-            furi_timer_stop(tetris_state->timer);
-
-            tetris_game_render_curr_piece(tetris_state);
-            uint8_t numLines = 0;
-            uint8_t lines[] = {0, 0, 0, 0};
-            uint16_t nextFallSpeed;
-
-            tetris_game_check_for_lines(tetris_state, lines, &numLines);
-            if(numLines > 0) {
-                for(int i = 0; i < numLines; i++) {
-                    // zero out row
-                    for(int j = 0; j < FIELD_WIDTH; j++) {
-                        tetris_state->playField[lines[i]][j] = false;
-                    }
-                    // move all above rows down
-                    for(int k = lines[i]; k >= 0; k--) {
-                        for(int m = 0; m < FIELD_WIDTH; m++) {
-                            tetris_state->playField[k][m] =
-                                (k == 0) ? false : tetris_state->playField[k - 1][m];
-                        }
-                    }
+    if(wasDownMove && tetris_game_piece_at_bottom(tetris_state, newPiece)) {
+        furi_timer_stop(tetris_state->timer);
+
+        uint8_t numLines = 0;
+        uint8_t lines[] = {0, 0, 0, 0};
+        uint16_t nextFallSpeed;
+
+        tetris_game_check_for_lines(tetris_state, lines, &numLines);
+        if(numLines > 0) {
+            for(int i = 0; i < numLines; i++) {
+                // zero out row
+                for(int j = 0; j < FIELD_WIDTH; j++) {
+                    tetris_state->playField[lines[i]][j] = false;
                 }
-
-                uint16_t oldNumLines = tetris_state->numLines;
-                tetris_state->numLines += numLines;
-                if((oldNumLines / 10) % 10 != (tetris_state->numLines / 10) % 10) {
-                    nextFallSpeed =
-                        tetris_state->fallSpeed - (100 / (tetris_state->numLines / 10));
-                    if(nextFallSpeed >= MIN_FALL_SPEED) {
-                        tetris_state->fallSpeed = nextFallSpeed;
+                // move all above rows down
+                for(int k = lines[i]; k >= 0; k--) {
+                    for(int m = 0; m < FIELD_WIDTH; m++) {
+                        tetris_state->playField[k][m] =
+                            (k == 0) ? false : tetris_state->playField[k - 1][m];
                     }
                 }
             }
 
-            // Check for game over
-            Piece* spawnedPiece = &shapes[rand() % 7];
-            if(!tetris_game_is_valid_pos(tetris_state, spawnedPiece->p)) {
-                tetris_state->gameState = GameStateGameOver;
-            } else {
-                memcpy(&tetris_state->currPiece, spawnedPiece, sizeof(tetris_state->currPiece));
-                furi_timer_start(tetris_state->timer, tetris_state->fallSpeed);
+            uint16_t oldNumLines = tetris_state->numLines;
+            tetris_state->numLines += numLines;
+            if((oldNumLines / 10) % 10 != (tetris_state->numLines / 10) % 10) {
+                nextFallSpeed =
+                    tetris_state->fallSpeed - (100 / (tetris_state->numLines / 10));
+                if(nextFallSpeed >= MIN_FALL_SPEED) {
+                    tetris_state->fallSpeed = nextFallSpeed;
+                }
             }
         }
-    }
 
-    if(tetris_game_is_valid_pos(tetris_state, newPiece->p)) {
-        memcpy(&tetris_state->currPiece, newPiece, sizeof(tetris_state->currPiece));
+        // Check for game over
+        Piece* spawnedPiece = &shapes[rand() % 7];
+        if(!tetris_game_is_valid_pos(tetris_state, spawnedPiece->p)) {
+            tetris_state->gameState = GameStateGameOver;
+        } else {
+            memcpy(&tetris_state->currPiece, spawnedPiece, sizeof(tetris_state->currPiece));
+            furi_timer_start(tetris_state->timer, tetris_state->fallSpeed);
+        }
+    }else{
+        tetris_game_remove_curr_piece(tetris_state);
+        if(tetris_game_is_valid_pos(tetris_state, newPiece->p)) {
+            memcpy(&tetris_state->currPiece, newPiece, sizeof(tetris_state->currPiece));
+        }
     }
-
     tetris_game_render_curr_piece(tetris_state);
 }
 
@@ -480,4 +475,4 @@ int32_t tetris_game_app() {
     free(tetris_state);
 
     return 0;
-}
\ No newline at end of file
+}