From 5a95c9180cb7000b57d9b35a19eca65d586dcc07 Mon Sep 17 00:00:00 2001 From: Gregor Klevze Date: Sun, 7 Dec 2025 10:45:12 +0100 Subject: [PATCH] I block rotation fix --- src/gameplay/core/Game.cpp | 51 +++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/src/gameplay/core/Game.cpp b/src/gameplay/core/Game.cpp index ce174db..de33c32 100644 --- a/src/gameplay/core/Game.cpp +++ b/src/gameplay/core/Game.cpp @@ -2,6 +2,7 @@ #include "Game.h" #include #include +#include #include // Piece rotation bitmasks (row-major 4x4). Bit 0 = (0,0). @@ -400,8 +401,28 @@ void Game::rotate(int dir) { // Try rotation at current position first if (!collides(p)) { - cur = p; - return; + // If rotation at current position would place cells above the top, + // attempt to shift it down so the topmost block sits at gy == 0. + int minGy = std::numeric_limits::max(); + for (int cy = 0; cy < 4; ++cy) { + for (int cx = 0; cx < 4; ++cx) { + if (!cellFilled(p, cx, cy)) continue; + minGy = std::min(minGy, p.y + cy); + } + } + + if (minGy < 0) { + Piece adj = p; + adj.y += -minGy; + if (!collides(adj)) { + cur = adj; + return; + } + // Can't shift into place without collision - fall through to kicks + } else { + cur = p; + return; + } } // Standard SRS Wall Kicks @@ -457,8 +478,30 @@ void Game::rotate(int dir) { test.x = cur.x + kick.first; test.y = cur.y + kick.second; if (!collides(test)) { - cur = test; - return; + // Prevent rotated piece from ending up above the visible playfield. + // If any cell of `test` is above the top (gy < 0), try shifting it + // downward so the highest block sits at row 0. Accept the shift + // only if it doesn't collide; otherwise keep searching kicks. + int minGy = std::numeric_limits::max(); + for (int cy = 0; cy < 4; ++cy) { + for (int cx = 0; cx < 4; ++cx) { + if (!cellFilled(test, cx, cy)) continue; + minGy = std::min(minGy, test.y + cy); + } + } + + if (minGy < 0) { + Piece adj = test; + adj.y += -minGy; // shift down so topmost block is at gy == 0 + if (!collides(adj)) { + cur = adj; + return; + } + // couldn't shift without collision, try next kick + } else { + cur = test; + return; + } } } }