local RS = game:GetService("ReplicatedStorage")
local remote = RS:WaitForChild("RemoteEvents"):WaitForChild("")
local CELL = 5
local STEP_DELAY = 0.3
local SOLVE_LOOP = 0.8
local SHOW_RED = true
local SHOW_BLUE = true
local AUTO_REVEAL = true
local highlights = {}
local function setHL(part, color)
if highlights[part] then
highlights[part]:Destroy()
highlights[part] = nil
end
if not color then return end
local h = Instance.new("SelectionBox")
h.Adornee = part
h.Color3 = color
h.LineThickness = 0.07
h.SurfaceColor3 = color
h.SurfaceTransparency = 0.5
h.Parent = workspace
highlights[part] = h
end
local function clearAllHL()
for part in pairs(highlights) do
if highlights[part] then
highlights[part]:Destroy()
end
end
highlights = {}
end
local RED = Color3.fromRGB(255, 40, 40)
local BLUE = Color3.fromRGB(40, 160, 255)
local function isUnrevealed(square)
local sa = square:FindFirstChildWhichIsA("SurfaceAppearance")
if sa then return false end
local r = square.Color.R
return r < 0.5
end
local function getTileState(square)
local sa = square:FindFirstChildWhichIsA("SurfaceAppearance")
if not sa then
local r = square.Color.R
if r < 0.5 then
return "unknown"
else
return "empty"
end
end
if sa.Name == "Mine" then return "mine" end
local n = tonumber(sa.Name:match("%d+"))
if n then return n end
return "empty"
end
local function buildGrid()
local board = workspace:FindFirstChild("Clickable") and workspace.Clickable:FindFirstChild("Board")
if not board then return {}, {} end
local tiles = {}
local byPos = {}
for _, child in ipairs(board:GetChildren()) do
if child:IsA("MeshPart") and child.Name == "Square" then
local state = getTileState(child)
tiles[child] = state
local rx = math.round(child.Position.X / CELL) * CELL
local rz = math.round(child.Position.Z / CELL) * CELL
if not byPos[rx] then byPos[rx] = {} end
byPos[rx][rz] = child
end
end
return tiles, byPos
end
local DIRS = {
{-1,-1}, {0,-1}, {1,-1},
{-1, 0}, {1, 0},
{-1, 1}, {0, 1}, {1, 1},
}
local function getNeighbours(part, byPos)
local rx = math.round(part.Position.X / CELL) * CELL
local rz = math.round(part.Position.Z / CELL) * CELL
local nbrs = {}
for _, d in ipairs(DIRS) do
local col = byPos[rx + d[1] * CELL]
if col then
local n = col[rz + d[2] * CELL]
if n then table.insert(nbrs, n) end
end
end
return nbrs
end
local function solve(tiles, byPos)
local knownMine = {}
local knownSafe = {}
local changed = true
local passes = 0
while changed and passes < 30 do
changed = false
passes = passes + 1
for part, state in pairs(tiles) do
if type(state) ~= "number" or state <= 0 then continue end
local nbrs = getNeighbours(part, byPos)
local unknown = {}
local mineCount = 0
for _, n in ipairs(nbrs) do
local ns = tiles[n]
if knownMine[n] or ns == "mine" then
mineCount = mineCount + 1
elseif ns == "unknown" and not knownSafe[n] and not knownMine[n] then
table.insert(unknown, n)
end
end
local remaining = state - mineCount
if remaining == 0 and #unknown > 0 then
for _, u in ipairs(unknown) do
if not knownSafe[u] then
knownSafe[u] = true
changed = true
end
end
end
if remaining > 0 and remaining == #unknown then
for _, u in ipairs(unknown) do
if not knownMine[u] then
knownMine[u] = true
changed = true
end
end
end
end
end
return knownSafe, knownMine
end
local function reveal(part)
local p = part.Position
remote:FireServer(Vector3.new(p.X, p.Y, p.Z))
end
local lastRevealTime = 0
while true do
pcall(function()
local tiles, byPos = buildGrid()
local total, unknownCount = 0, 0
for _, s in pairs(tiles) do
total = total + 1
if s == "unknown" then unknownCount = unknownCount + 1 end
end
if total > 0 then
local toSafe, toMine = solve(tiles, byPos)
clearAllHL()
for part in pairs(toMine) do
if isUnrevealed(part) and SHOW_RED then
setHL(part, RED)
end
end
for part in pairs(toSafe) do
if isUnrevealed(part) and SHOW_BLUE then
setHL(part, BLUE)
end
end
if AUTO_REVEAL then
local now = tick()
if now - lastRevealTime >= STEP_DELAY then
for part in pairs(toSafe) do
if isUnrevealed(part) then
reveal(part)
lastRevealTime = now
break
end
end
end
end
end
end)
task.wait(SOLVE_LOOP)
end
Comments
No comments yet
Be the first to share your thoughts!