I figured I would build the classic Minesweeper game.
I’ve a tiny logic challenge in my external module whose job it is to find adjacent empty cells and to clear their button.
Currently for testing, my buttons are semi-transparent so I can see underlaying bomb locations and numbers, so I can also see the empty cells. But once fixed I will remove the alpha and you wouldn’t see both buttons and bombs/number at the same time.
board is a matrix that populates an outter table or rows, before the inner table manages each column/cell in a row.
EG board[1][1] would reference the cell in the top left and board[10][10] the cell in the bottom right
The challenge is some adhoc cells above, and some adhoc cells below (north & south) are missed.
See screenshots.
The first cell listed in the cell the user clicked on.
function mod.clearEmptySquares(board, rowX, colY)
local rowMax = #board
local colMax = #board[1]
board[rowX][colY].info.btn = false -- receive in the box to show/hide
print("BOX["..rowX.."]["..colY.."]")
if (board[rowX][colY].info.number == 0) then
if rowX > 1 then -- ABOVE
if (colY > 1) then --LEFT
if (board[rowX-1][colY-1].info.btn == true) then
board = mod.clearEmptySquares(board, rowX-1, colY-1)
end
end
if (colY == 1) then --CENTER
if (board[rowX-1][colY].info.btn == true) then
board = mod.clearEmptySquares(board, rowX-1, colY)
end
end
if (colY < colMax) then --RIGHT
if (board[rowX-1][colY+1].info.btn == true)then
board = mod.clearEmptySquares(board, rowX-1, colY+1)
end
end
end
if rowX < rowMax then -- BELOW
if (colY > 1) then --LEFT
if (board[rowX+1][colY-1].info.btn == true) then
board = mod.clearEmptySquares(board, rowX+1, colY-1)
end
end
if (colY == 1) then --CENTER
if (board[rowX+1][colY].info.btn == true) then
board = mod.clearEmptySquares(board, rowX+1, colY)
end
end
if (colY < colMax) then -- RIGHT
if (board[rowX+1][colY+1].info.btn == true)then
board = mod.clearEmptySquares(board, rowX+1, colY+1)
end
end
end
if (colY > 1) then -- LEFT ADJACENT
if (board[rowX][colY-1].info.btn == true) then
board = mod.clearEmptySquares(board, rowX, colY-1)
end
end
if (colY < colMax) then -- RIGHT ADJACENT
if (board[rowX][colY+1].info.btn == true)then
board = mod.clearEmptySquares(board, rowX, colY+1)
end
end
end
return board
end
function mod.clearEmptySquares(board, rowX, colY)
local rowMax = #board
local colMax = #board[1]
board[rowX][colY].info.btn = false -- receive in the box to show/hide
-- if board[rowX-1][colY-1].imgBomb ~= nil then
-- board[rowX-1][colY-1].imgBomb.isVisible = true
-- end
-- if board[rowX-1][colY-1].imgText ~= nil then
-- board[rowX-1][colY-1].imgText.isVisible = true
-- end
print("BOX["..rowX.."]["..colY.."]")
if (board[rowX][colY].info.number == 0) then
if rowX > 1 then -- ABOVE
if (colY > 1) then --LEFT
if (board[rowX-1][colY-1].info.btn == true) then
board = mod.clearEmptySquares(board, rowX-1, colY-1)
end
end
if (colY > 1) then --CENTER
if (board[rowX-1][colY].info.btn == true) then
board = mod.clearEmptySquares(board, rowX-1, colY)
end
end
if (colY < colMax) then --RIGHT
if (board[rowX-1][colY+1].info.btn == true)then
board = mod.clearEmptySquares(board, rowX-1, colY+1)
end
end
end
if rowX < rowMax then -- BELOW
if (colY > 1) then --LEFT
if (board[rowX+1][colY-1].info.btn == true) then
board = mod.clearEmptySquares(board, rowX+1, colY-1)
end
end
if (colY > 1) then --CENTER
if (board[rowX+1][colY].info.btn == true) then
board = mod.clearEmptySquares(board, rowX+1, colY)
end
end
if (colY < colMax) then -- RIGHT
if (board[rowX+1][colY+1].info.btn == true)then
board = mod.clearEmptySquares(board, rowX+1, colY+1)
end
end
end
if (colY > 1) then -- LEFT ADJACENT
if (board[rowX][colY-1].info.btn == true) then
board = mod.clearEmptySquares(board, rowX, colY-1)
end
end
if (colY < colMax) then -- RIGHT ADJACENT
if (board[rowX][colY+1].info.btn == true)then
board = mod.clearEmptySquares(board, rowX, colY+1)
end
end
end
return board
end
Oh, well, I mean the two CENTER cases wouldn’t seem to need column checks, at all. As is, column 1 will be botched (I’m guessing that’s what we see in the last picture).
No… my code is design to search the row above the triggering cell. For the cells above, left, centre, right.
Then the code is designed to search the row below the triggering cell. For the cells below left, centre, right.
This just leave the two cells directly left and right of the trigger cell.
There is no column search.
This is what I meant by CENTER. In those two cases the column check is pointless (you don’t need to look left or right, so there’s no reason to guard) and I assume when colY is 1, it’s skipping the logic.
so I tweaked my code to this - still problem persists with north and south cells reveals.
function mod.clearEmptySquares(board, rowX, colY)
local rowMax = #board
local colMax = #board[1]
board[rowX][colY].info.btn = false -- receive in the box to show/hide
print("BOX["..rowX.."]["..colY.."]")
if (board[rowX][colY].info.number == 0) then
if rowX > 1 then -- ABOVE
if (colY > 1) then --LEFT
if (board[rowX-1][colY-1].info.btn == true) then
board = mod.clearEmptySquares(board, rowX-1, colY-1)
end
if (board[rowX-1][colY].info.btn == true) then
board = mod.clearEmptySquares(board, rowX-1, colY)
end
end
-- if (colY > 1) then --CENTER
-- if (board[rowX-1][colY].info.btn == true) then
-- board = mod.clearEmptySquares(board, rowX-1, colY)
-- end
-- end
if (colY < colMax) then --RIGHT
if (board[rowX-1][colY+1].info.btn == true) then
board = mod.clearEmptySquares(board, rowX-1, colY+1)
end
end
end
if rowX < rowMax then -- BELOW
if (colY > 1) then --LEFT
if (board[rowX+1][colY-1].info.btn == true) then
board = mod.clearEmptySquares(board, rowX+1, colY-1)
end
if (board[rowX+1][colY].info.btn == true) then
board = mod.clearEmptySquares(board, rowX+1, colY)
end
end
-- if (colY > 1) then --CENTER
-- if (board[rowX+1][colY].info.btn == true) then
-- board = mod.clearEmptySquares(board, rowX+1, colY)
-- end
-- end
if (colY < colMax) then -- RIGHT
if (board[rowX+1][colY+1].info.btn == true)then
board = mod.clearEmptySquares(board, rowX+1, colY+1)
end
end
end
if (colY > 1) then -- LEFT ADJACENT
if (board[rowX][colY-1].info.btn == true) then
board = mod.clearEmptySquares(board, rowX, colY-1)
end
end
if (colY < colMax) then -- RIGHT ADJACENT
if (board[rowX][colY+1].info.btn == true)then
board = mod.clearEmptySquares(board, rowX, colY+1)
end
end
end
return board
end
if rowX > 1 then -- ABOVE
if (colY > 1) then --LEFT
if (board[rowX-1][colY-1].info.btn == true) then
board = mod.clearEmptySquares(board, rowX-1, colY-1)
end
end
-- NOT inside the if statement
if (board[rowX-1][colY].info.btn == true) then
board = mod.clearEmptySquares(board, rowX-1, colY)
end
-- end
-- if (colY > 1) then --CENTER
-- if (board[rowX-1][colY].info.btn == true) then
-- board = mod.clearEmptySquares(board, rowX-1, colY)
-- end
-- end
and likewise for the below case, and see what you get.
I think with my initial code, i over thought it way to much!
Having scrapped my code and adopted your advice, I have success!!
Here was the resulting function code, for anyone who reads this forum post in the future and fancies learning from this
function mod.clearEmptySquares(board, rowX, colY)
local rowMax = #board
local colMax = #board[1]
local count = 1
if (board[rowX][colY].info.number == 0) then
for i = rowX-count, rowX+count do -- itterate matrix
for j = colY-count, colY+count do -- itterate matrix
if i >=1 and i <= rowMax then -- stay within board boundaries
if j >=1 and j <= colMax then -- stay within board boundaries
if (board[i][j].info.number >=1) then -- found clearing edge
board[i][j].info.btn = false
elseif ( i == rowX) and (j == colY) then -- found myself/trigger box
board[i][j].info.btn = false
elseif (board[i][j].info.number == 0 ) and ( board[i][j].info.btn == true ) then -- investigate box whose btn still shows
mod.clearEmptySquares(board, i, j)
end
end
end
end
end
end
return board
end
FYI, you can also optimize some more here (makes it more readable too)…
local tile = board[i][j].info
if (tile.number >=1) then -- found clearing edge
tile.btn = false
elseif ( i == rowX) and (j == colY) then -- found myself/trigger box
tile.btn = false
elseif (tile.number == 0 ) and ( tile.btn == true ) then -- investigate box whose btn still shows
mod.clearEmptySquares(board, i, j)
end