Inaccurate Mine Counts on a Minesweeper Board

I am trying to recreate the mechanics of minesweeper, where “safe” tiles will show the amount of mines surrounding it (so it should be checking 8 tiles).

I am doing this by getting the looping through the mine tiles and finding the positions of what would be the surrounding 8 tiles. These positions are stored in a table, and the script will go through all of the safe tiles in the board and check whether its position is stored in the table and how many times it occurs (using a counter) in order to suggest how many mines are around it.

However I’ve recently noticed that this isn’t always accurate, and there are some instances where the tile doesn’t correctly reflect how many mines are around it.
An example below of a fully revealed board— some tiles only display “1” when there is more than one mine (red tile) adjacent to it. Some tiles are also empty or have “0 mines surrounding it” even though they should have a value displayed:

So I’m not sure if I missed something in the script or this is a result of Roblox’s wacky positions? It’s just weird since the rest of the board seems to be correct, and I’m pretty sure I’ve been able to achieve perfectly normal boards in the past. Alternatively, I can change the system entirely but it would require me to take into account some more considerations like the size of the board so I figured that this is an ideal(ish) way of going about it.

Parts of the script used for this are here vv. If you might know the problem or have any suggestions on how to fix this, thank you!!

for i, v in pairs(mines) do -- grabs all randomly selected mine tiles
	CollectionService:AddTag(v.ClickDetector, "Mine")
	-- vv finds the position of the 8 tiles surrounding the mine and adds it to "warnings" table
	table.insert(warnings, v.Position + Vector3.new(5, 0, -5)) -- topleft
	table.insert(warnings, v.Position + Vector3.new(5, 0, 0)) -- top
	table.insert(warnings, v.Position + Vector3.new(5, 0, 5)) -- topright
	table.insert(warnings, v.Position + Vector3.new(0, 0, -5)) -- left
	table.insert(warnings, v.Position + Vector3.new(0, 0, 5)) -- right
	table.insert(warnings, v.Position + Vector3.new(-5, 0, -5)) -- bottomleft
	table.insert(warnings, v.Position + Vector3.new(-5, 0, 0)) -- bottom
	table.insert(warnings, v.Position + Vector3.new(-5, 0, 5)) -- bottomright
end

for i, v in pairs(board:GetChildren()) do -- iterates through all the tiles in the board
	if not table.find(mines, v) then -- (that aren't mines)
		CollectionService:AddTag(v.ClickDetector, "Safe")
		
		local mineval = 0
		for _, pos in pairs(warnings) do -- loops through the "warnings" table
			if pos == v.Position then -- checks whether it corresponds with part's position
				mineval += 1 -- adds to a counter whenever the position matches
			end
		end
		v:SetAttribute("Minecount", mineval) -- sets the tile's attribute, which is displayed on the tile, as the counter
	end
end

While I can’t prove that it’s the case right now, this has the potential to not work based on the positioning of the tiles, since you are doing an exact comparison between positions. You should check the comparisons being done for the tiles that are currently wrong to see if they are very slightly different.
Try replacing the comparison with this for now and see if there’s a change:

pos == v.Position
to
(pos - v.Position).Magnitude < 1.0
1 Like

i figured it had something to do with that, but completely forgot about magnitude lmao.
though it seems to be working as intended now, thank you!

1 Like