minewswep

Run Settings
LanguageLua
Language Version
Run Command
-- ceat_ceat -- missing textures and colors LOL -- original https://pastebin.com/KAjDQugX warn("mineswep by ceat yay") if game:GetService("RunService"):IsStudio() then require(game.ServerStorage.lsbenv)() owner,printf,warnf,LoadLibrary,LoadAssets,NLS=owner,printf,warnf,LoadLibrary,LoadAssets,NLS end local TweenService = game:GetService("TweenService") local Debris = game:GetService("Debris") local DEFAULT_TILE_WIDTH = 1.5 local FIELD_RADIUS = 1 local RESTART_TIME = 3 local UNOPENED_TEX = "rbxassetid://15144071117" local OPENED_TEX = "rbxassetid://13348346487" local MINE_TEX = "rbxassetid://13348250535" local FLAG_TEX = "rbxassetid://10720664742" local BLANK_TEX = "rbxassetid://12381187927" local NUMBER_FONT = Enum.Font.SourceSansBold local WIN_MINE_COLOR = Color3.new(0.5, 1, 0.5) local DIG_SOUND = "rbxassetid://3498493622" local FLAG_SOUND = "rbxassetid://8388724806" local CORRECT_SOUND = "rbxassetid://3422389728" local YAY_SOUND = "rbxassetid://9068897474" local ALARM_SOUND = "rbxassetid://2778386920" local EXPLODE_SOUND = "rbxassetid://165969964" local COLORS = { Color3.fromRGB(0, 0, 255), Color3.fromRGB(39, 107, 31), Color3.fromRGB(255, 0, 0), Color3.fromRGB(0, 0, 130), Color3.fromRGB(157, 0, 0), Color3.fromRGB(0, 214, 146), Color3.fromRGB(98, 0, 168), Color3.fromRGB(100, 100, 100), } local FLASH_TWEENINFO = TweenInfo.new(0.3, Enum.EasingStyle.Quad, Enum.EasingDirection.In) local WIN_FLASH_TWEENINFO = TweenInfo.new(0.75, Enum.EasingStyle.Linear, Enum.EasingDirection.In) local settings = { tileWidth = DEFAULT_TILE_WIDTH, use3DFlags = false, width = 25, height = 25, mineCount = 90, debug = false } local currentGame local function createTilePart(cf, tileWidth) local part = Instance.new("Part") part.Anchored = true part.CFrame = cf part.Size = Vector3.new(tileWidth, 0.5, tileWidth) local tileDecal = Instance.new("Decal") tileDecal.Name = "TileTexture" tileDecal.Texture = UNOPENED_TEX tileDecal.Face = Enum.NormalId.Top tileDecal.Parent = part local clickDetector = Instance.new("ClickDetector") clickDetector.Name = "ClickDetector" clickDetector.MaxActivationDistance = 30 clickDetector.Parent = part return part end local function createFlagDecal(part) local decal = Instance.new("Decal") decal.Name = "FlagDecal" decal.Texture = FLAG_TEX decal.Face = Enum.NormalId.Top decal.ZIndex = 5 decal.Parent = part return decal end local function displayNumber(tile) local surfaceGui = Instance.new("SurfaceGui") surfaceGui.Name = "NumberFace" surfaceGui.Face = Enum.NormalId.Top surfaceGui.SizingMode = Enum.SurfaceGuiSizingMode.PixelsPerStud surfaceGui.PixelsPerStud = 25 local label = Instance.new("TextLabel") label.Name = "NumberLabel" label.Text = tostring(tile.minesAround) label.Font = NUMBER_FONT label.TextColor3 = COLORS[tile.minesAround] label.TextScaled = true label.BackgroundTransparency = 1 label.AnchorPoint = Vector2.new(0.5, 0.5) label.Position = UDim2.fromScale(0.5, 0.5) label.Size = UDim2.fromScale(2, 2) label.TextTransparency = 1 label.Rotation = -90 local flashDecal = Instance.new("Decal") flashDecal.Texture = BLANK_TEX flashDecal.Face = Enum.NormalId.Top flashDecal.ZIndex = 5 flashDecal.Transparency = 0 flashDecal.Parent = tile.part label.Parent = surfaceGui surfaceGui.Parent = tile.part TweenService:Create(flashDecal, FLASH_TWEENINFO, { Transparency = 1 }):Play() TweenService:Create(label, TweenInfo.new(0.2), { TextTransparency = 0 }):Play() TweenService:Create(label, TweenInfo.new(0.2 + math.random()*0.2, Enum.EasingStyle.Quad, Enum.EasingDirection.In), { Size = UDim2.fromScale(1, 1) }):Play() Debris:AddItem(flashDecal, FLASH_TWEENINFO.Time) end local function iterTiles(tiles) local width = #tiles local height = #tiles[1] local x = 1 local y = 1 return function() if x > width then x = 1 y += 1 if y > height then return end end local x1 = x x += 1 return x1, y, tiles[x1][y] end end local function disableTile(tile) tile.enabled = false tile.leftClickConnection:Disconnect() tile.rightClickConnection:Disconnect() tile.leftClickConnection = nil tile.rightClickConnection = nil tile.clickDetector:Destroy() end local function unflagTile(tile) if tile.flagInstance then tile.flagInstance:Destroy() tile.flagInstance = nil end end local function getTilesToFlash(tiles, x, y, offset) local flashyGuys = {} -- top left -> top right for xOff = -offset, offset do local tile = tiles[x - xOff] and tiles[x - xOff][y - offset] if tile then table.insert(flashyGuys, tile) end end -- bottom left -> bottom right for xOff = -offset, offset do local tile = tiles[x + xOff] and tiles[x + xOff][y + offset] if tile and not table.find(flashyGuys, tile) then table.insert(flashyGuys, tile) end end -- top left -> bottom left if tiles[x - offset] then for yOff = -offset, offset do local tile = tiles[x - offset][y + yOff] if tile and not table.find(flashyGuys, tile) then table.insert(flashyGuys, tile) end end end -- top right -> bottom right if tiles[x + offset] then for yOff = -offset, offset do local tile = tiles[x + offset][y + yOff] if tile and not table.find(flashyGuys, tile) then table.insert(flashyGuys, tile) end end end return flashyGuys end local function flashTilesWave(tiles, tile, width, height, winner, color) local baseX = tile.x local baseY = tile.y for i = 0, math.max(width, height) do for _, tile in getTilesToFlash(tiles, baseX, baseY, i) do if tile.isFlagged then tile.isFlagged = false unflagTile(tile) end if winner then tile.tileTexture.Texture = OPENED_TEX else if tile.isMine then tile.tileTexture.Texture = MINE_TEX end end tile.tileTexture.Color3 = color if not tile.isMine then TweenService:Create(tile.tileTexture, WIN_FLASH_TWEENINFO, { Color3 = Color3.new(1, 1, 1) }):Play() end end task.wait() end end local function playSound(part, soundId, pitch) local sound = Instance.new("Sound") sound.SoundId = soundId sound.Pitch = pitch sound.Parent = part sound:Play() Debris:AddItem(sound, 4) return sound end -- debug visuals local function highlightTile(tile, color) local part = Instance.new("Part") part.Anchored = true part.CanCollide = false part.CanTouch = false part.CanQuery = false part.Material = Enum.Material.Neon part.Color = color part.Size = Vector3.new(settings.tileWidth, 0.7, settings.tileWidth) part.Transparency = 0.8 part.CFrame = tile.part.CFrame return part end local function showNeighbors(tiles, tile) local main = highlightTile(tile, Color3.new(1, 0, 0)) main.Parent = workspace local neighborParts = {} for _, position in tile.neighbors do local part = highlightTile(tiles[position.x][position.y], Color3.new(0, 0, 1)) part.Parent = workspace table.insert(neighborParts, part) end task.wait() main:Destroy() for _, part in neighborParts do part:Destroy() end end -- game wow local restartTask local function restart(spawnCF, width, height, numMines) restartTask = task.delay(RESTART_TIME, function() restartTask = nil stopGame(currentGame) currentGame = createGame(spawnCF, width, height, numMines) end) end function createGame(spawnCF, width, height, numMines) local gameObject = {} local gameSettings = table.clone(settings) gameObject.settings = gameSettings local model = Instance.new("Model") model.Name = "Minesweeper" gameObject.model = model local tiles = {} gameObject.tiles = tiles gameObject.active = true gameObject.didFirstClick = false gameObject.players = {} local function layMines(clickedTile) local validPositions = {} -- filter out start field for x, y, tile in iterTiles(tiles) do if math.abs(x - clickedTile.x) <= FIELD_RADIUS and math.abs(y - clickedTile.y) <= FIELD_RADIUS then continue end table.insert(validPositions, { x = x, y = y }) end for i = 1, math.min(numMines, #validPositions) do local pos = table.remove(validPositions, math.random(#validPositions)) local tile = tiles[pos.x][pos.y] tile.isMine = true if gameSettings.debug then tile.tileTexture.Color3 = Color3.new(1, 0.5, 0.5) end end -- count mines around tiles for x, y, tile in iterTiles(tiles) do for _, position in tile.neighbors do if tiles[position.x][position.y].isMine then tile.minesAround += 1 end end if gameSettings.debug then showNeighbors(tiles, tile) end end end local function onLose(plr, tile) gameObject.active = false for x, y, tile in iterTiles(tiles) do if tile.enabled then disableTile(tile) end if tile.isMine then tile.tileTexture.Texture = MINE_TEX end end tile.part.CFrame *= CFrame.new(0, 1, 0) tile.part.Anchored = false tile.part.Velocity = Vector3.new(-3 + math.random()*6, math.random(20, 30), -3 + math.random()*6) tile.part.RotVelocity = Vector3.new(math.random(-10, 10), math.random(-10, 10), math.random(-10, 10)) playSound(tile.part, ALARM_SOUND, 1).TimePosition = 0.35 playSound(tile.part, EXPLODE_SOUND, 1) local explod = Instance.new("Explosion") explod.BlastPressure = 0 explod.BlastRadius = 0 explod.Position = tile.part.Position explod.Parent = workspace flashTilesWave(tiles, tile, width, height, false, Color3.new(1, 0.5, 0.5)) restart(spawnCF, width, height, numMines) end local function onWin(tile) for x, y, tile in iterTiles(tiles) do if tile.enabled then disableTile(tile) end end playSound(tile.part, CORRECT_SOUND, 1) playSound(tile.part, YAY_SOUND, 1) flashTilesWave(tiles, tile, width, height, true, WIN_MINE_COLOR) restart(spawnCF, width, height, numMines) end local mineTile -- scream local function chordTile(plr, tile) local unflaggedTiles = {} local numFlagged = 0 for _, position in tile.neighbors do local otherTile = tiles[position.x][position.y] if otherTile.opened then continue end if otherTile.isFlagged then numFlagged += 1 else table.insert(unflaggedTiles, otherTile) end end if numFlagged == tile.minesAround then for _, otherTile in unflaggedTiles do mineTile(plr, otherTile) end end end function mineTile(plr, tile) if not gameObject.active then return end if tile.isMine then onLose(plr, tile) return end if tile.opened then chordTile(plr, tile) return end if not table.find(gameObject.players, plr.Name) then table.insert(gameObject.players, plr.Name) end if tile.isFlagged then tile.isFlagged = false unflagTile(tile) end tile.opened = true tile.tileTexture.Texture = OPENED_TEX if tile.minesAround == 0 then disableTile(tile) for _, position in tile.neighbors do local otherTile = tiles[position.x][position.y] if otherTile.opened then continue end mineTile(plr, otherTile) end else displayNumber(tile) end end local function checkWin() local numNonMines = 0 local numOpened = 0 for x, y, tile in iterTiles(tiles) do if not tile.isMine then numNonMines += 1 end if tile.opened then numOpened += 1 end end return numNonMines == numOpened end local function onLeftClick(tile) return function(plr) if tile.isFlagged then return end if not gameObject.didFirstClick then gameObject.didFirstClick = true layMines(tile) end playSound(tile.part, DIG_SOUND, 0.9 + math.random()*0.2) mineTile(plr, tile) if checkWin() then onWin(tile) end end end local function onRightClick(tile) return function(plr) if tile.opened then return end tile.isFlagged = not tile.isFlagged playSound(tile.part, FLAG_SOUND, 0.8 + math.random()*0.4) if tile.isFlagged then if gameSettings.use3DFlags then -- not implemented else tile.flagInstance = createFlagDecal(tile.part) end else unflagTile(tile) end end end local originCF = spawnCF * CFrame.new(-width/2*gameSettings.tileWidth, 0, -height/2*gameSettings.tileWidth) for x = 1, width do local row = {} for y = 1, height do local tileCF = originCF * CFrame.new(x*gameSettings.tileWidth, 0, y*gameSettings.tileWidth) local part = createTilePart(tileCF, gameSettings.tileWidth) --part.CanCollide = false --part.Transparency = 1 local self = { x = x, y = y, enabled = true, opened = false, isMine = false, isFlagged = false, neighbors = {}, -- {x = num, y = num} minesAround = 0, -- decided by layMines part = part, tileTexture = part.TileTexture, clickDetector = part.ClickDetector, flagInstance = nil, -- decal or instance leftClickConnection = nil, rightClickConnection = nil, } self.leftClickConnection = self.clickDetector.MouseClick:Connect(onLeftClick(self)) self.rightClickConnection = self.clickDetector.RightMouseClick:Connect(onRightClick(self)) for xOffset = -1, 1 do for yOffset = -1, 1 do if xOffset == 0 and yOffset == 0 then continue end local x2 = x + xOffset local y2 = y + yOffset if x2 < 1 or x2 > width then continue end if y2 < 1 or y2 > height then continue end table.insert(self.neighbors, { x = x2, y = y2 }) end end part.Parent = model --local delayTime = (y - 1)*(width)*0.00005 + x*0.00005 --TweenService:Create(part, TweenInfo.new(0.15 + math.random()*0.15, Enum.EasingStyle.Quad, Enum.EasingDirection.In), { -- Transparency = 0, -- CFrame = tileCF, -- CanCollide = true --}):Play() row[y] = self end tiles[x] = row end model.Parent = workspace return gameObject end function stopGame(gameObject) for x, y, tile in iterTiles(gameObject.tiles) do if tile.enabled then disableTile(tile) end end gameObject.model:Destroy() end -- currentGame = createGame(CFrame.new(0, 5, 0), settings.width, settings.height, settings.mineCount) local function getRootPos() local humanoid = owner.Character and owner.Character:FindFirstChildOfClass("Humanoid") if humanoid and humanoid.RootPart then return humanoid.RootPart.CFrame.Position end end owner.Chatted:Connect(function(msg) local cmdString = msg:match("ms/(.+)") if not cmdString then return end local args = cmdString:split("/") local cmdName = table.remove(args, 1) if cmdName == "size" then if args[2] then settings.width = tonumber(args[1]) settings.height = tonumber(args[2]) printf(`set size to <b>{settings.width}x{settings.height}</b>`) else local size = tonumber(args[1]) if not size then return printf("<i>pls provide size</i>") end settings.width = size settings.height = size printf(`set size to <b>{size}x{size}</b>`) end elseif cmdName == "mines" then local mineCount = tonumber(args[1]) if not mineCount then return printf("<i>pls provide minecount</i>") end settings.mineCount = mineCount printf(`set mine count to <b>{settings.mineCount}</b>`) elseif cmdName == "minefreq" then local freq = tonumber(args[1]) if not freq then return printf("<i>pls provide freq</i>") end settings.mineCount = math.floor(settings.width*settings.height*freq) printf(`set mine count to <b>{settings.mineCount}</b>`) elseif cmdName == "game" then local rootPos = getRootPos() if not rootPos then return printf("<i>could not find rootpos</i>") end if currentGame then stopGame(currentGame) end currentGame = createGame(CFrame.new(rootPos + Vector3.new(0, -1.75, 0)), settings.width, settings.height, settings.mineCount) printf("<i>started game</i>") elseif cmdName == "stop" then if restartTask then task.cancel(restartTask) restartTask = nil end if currentGame then stopGame(currentGame) else printf("<i>no game active</i>") end elseif cmdName == "debug" then settings.debug = not settings.debug printf(`<i>debug mode {settings.debug}</i>`) elseif cmdName == "cmds" then printf([[ <b>ms/size/[width]/[height]</b> set board size to (width, height) <b>ms/size/<[sideLength]</b> set board size to (sideLength, sideLength) <b>ms/mines/[mineCount]</b> set mine count to mineCount <b>ms/minefreq/[mineFrequency]</b> set mine count to width*height*mineFrequency <b>ms/game</b> start game <b>ms/stop</b> end game <b>ms/cmds</b> this thing ]]) else printf("<i>invalid ms/ command</i>") end end) print("ms/cmds for list of commands (works with /e)")
Editor Settings
Theme
Key bindings
Full width
Lines