From 7bb401d9e8b0cca0f8ace40243fc9560eeb2282d Mon Sep 17 00:00:00 2001 From: ephphatha Date: Wed, 22 Jun 2022 17:13:55 +1000 Subject: [PATCH] Simplify loop used to find the area for a theme room --- Source/levels/gendung.cpp | 85 +++++++++++++-------------------------- 1 file changed, 27 insertions(+), 58 deletions(-) diff --git a/Source/levels/gendung.cpp b/Source/levels/gendung.cpp index b25dc274d..be36c13a4 100644 --- a/Source/levels/gendung.cpp +++ b/Source/levels/gendung.cpp @@ -80,11 +80,6 @@ std::unique_ptr LoadMinData(size_t &tileCount) bool WillThemeRoomFit(int floor, int x, int y, int minSize, int maxSize, int *width, int *height) { - bool yFlag = true; - bool xFlag = true; - int xCount = 0; - int yCount = 0; - if (x + maxSize > DMAXX && y + maxSize > DMAXY) { return false; // Original broken bounds check, avoids lower right corner } @@ -95,67 +90,41 @@ bool WillThemeRoomFit(int floor, int x, int y, int minSize, int maxSize, int *wi return false; } - int xArray[20] = {}; - int yArray[20] = {}; - - for (int ii = 0; ii < maxSize; ii++) { - if (xFlag && y + ii < DMAXY) { - for (int xx = x; xx < x + maxSize && xx < DMAXX; xx++) { - if (dungeon[xx][y + ii] != floor) { - if (xx >= minSize) { - break; - } - xFlag = false; - } else { - xCount++; - } - } - if (xFlag) { - xArray[ii] = xCount; - xCount = 0; + int maxWidth = std::min(DMAXX - x, maxSize); + int maxHeight = std::min(DMAXY - y, maxSize); + + // see if we can find a region at least as large as the minSize on each dimension + for (int yOffset = 0; yOffset < maxHeight; yOffset++) { + for (int xOffset = 0; xOffset < maxWidth; xOffset++) { + // Start out looking for the widest area at least as tall as minSize + if (dungeon[x + xOffset][y + yOffset] == floor) + continue; + + // found a floor tile earlier than the previous row, so the width has shrunk somewhat + + if (xOffset < minSize && yOffset < minSize) { + // area is too small to hold a room of the desired size + return false; } - } - if (yFlag && x + ii < DMAXX) { - for (int yy = y; yy < y + maxSize && yy < DMAXY; yy++) { - if (dungeon[x + ii][yy] != floor) { - if (yy >= minSize) { - break; - } - yFlag = false; - } else { - yCount++; - } + + if (yOffset >= minSize) { + // area is at least as high as necessary, this row now defines our max height (also breaks out of the outer loop) + maxHeight = yOffset; } - if (yFlag) { - yArray[ii] = yCount; - yCount = 0; + + if (xOffset < minSize) { + // current row is too small to meet the minimum size, so just use the last rows dimension + break; } - } - } - for (int ii = 0; ii < minSize; ii++) { - if (xArray[ii] < minSize || yArray[ii] < minSize) { - return false; + // otherwise we now have a new lower bound for how wide a row can be + maxWidth = xOffset; // soft break } } - int xSmallest = xArray[0]; - int ySmallest = yArray[0]; - - for (int ii = 0; ii < maxSize; ii++) { - if (xArray[ii] < minSize || yArray[ii] < minSize) { - break; - } - if (xArray[ii] < xSmallest) { - xSmallest = xArray[ii]; - } - if (yArray[ii] < ySmallest) { - ySmallest = yArray[ii]; - } - } + *width = maxWidth - 2; + *height = maxHeight - 2; - *width = xSmallest - 2; - *height = ySmallest - 2; return true; }