Advertisement
Mangus875

Roblox Minesweeper [WIP]

Aug 31st, 2023 (edited)
1,135
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 4.77 KB | None | 0 0
  1. local realBoard = {}    -- true/false = mine/no mine
  2. local myBoard = {}
  3. local gameState = {}    -- 0 = undiscovered / 1 = discovered / 2 = flag / 3 = ?
  4.  
  5. --[[
  6. local realBoard = {}    -- stores positions of mines
  7. local gameBoard = {}    -- stores numbers of adjacent mines
  8. local liveBoard = {}    -- stores current state of each board tile (unknown ,found, flagged, and marked)
  9. local gamePieces = {}   -- physical game pieces
  10. --]]
  11.  
  12. -- settings:
  13. local width = 9     -- board width
  14. local height = 9        -- board height
  15. local density = 0.123   -- avg mines/tile (nil to ignore) [0.123 = beginner / 0.156 = intermediate / 0.206 = expert]
  16. local mines = 10        -- mine count
  17. if density then mines = width*height*density end
  18. local deterministic = false -- avoid 50/50 guess cases (currently unimplemented)
  19. local openFirstMove = true  -- ensure first move lands on a tile with 0 surrounding mines
  20.  
  21. --[[    default board settings:
  22.     beginner : 9x9/10
  23.     intermediate : 16x16/40
  24.     expert : 30x16/99
  25. --]]
  26.  
  27. local function shuffle(table)
  28.     local buffer
  29.     for i = #table, 1, -1 do
  30.         local r = math.random(1,i)
  31.         buffer = table[i]
  32.         table[i] = table[r]
  33.         table[r] = buffer
  34.     end
  35. end
  36.  
  37. local function isValid(x, y)
  38.     return x>0 and x<=width and y>0 and y<=height
  39. end
  40.  
  41. local function getNeighbors(i)  -- gets neighbor indexes
  42.     local neighbors = {}
  43.     local x = (i-1)%width + 1
  44.     local y = math.floor((i-1)/width)+1
  45.    
  46.     for ix = x-1, x+1 do
  47.         for iy = y-1, y+1 do
  48.             if isValid(ix, iy) then
  49.                 table.insert(neighbors, ix+(iy-1)*width)
  50.             end
  51.         end
  52.     end
  53.    
  54.     return neighbors
  55. end
  56.  
  57. local function countNearbyMines(i)
  58.     local total = 0
  59.     for _, i in ipairs(getNeighbors(i)) do
  60.         if realBoard[i] then total += 1 end
  61.     end
  62.     return total
  63. end
  64.  
  65. local function labelTiles()
  66.     for i, bomb in ipairs(realBoard) do
  67.         if not bomb then return end
  68.         for _, n in ipairs(getNeighbors(i)) do
  69.             if not realBoard[n] then
  70.                 myBoard[n] = myBoard[n]+1
  71.             else
  72.                 myBoard[n] = "X"
  73.             end
  74.         end
  75.     end
  76. end
  77.  
  78. local function getGameState()   -- 0 = in progress / -1 = lost / 1 = won
  79.     local win = true
  80.     for i, v in ipairs(realBoard) do
  81.         if v and gameState[i] == 1 then
  82.             return -1
  83.         end
  84.         if win and not v and gameState[i] ~= 1 then
  85.             win = false
  86.         end
  87.     end
  88.     if win then return 1 end
  89.     return 0
  90. end
  91.  
  92. local function win()    -- does stuff when you win
  93. end
  94.  
  95. local function lose()   -- does stuff when you lost
  96. end
  97.  
  98. local function update()
  99.     -- add visual updates to the board here
  100.     local state = getGameState()
  101.     if state == -1 then return lose() end
  102.     if state == 1 then return win() end
  103. end
  104.  
  105. local function open(x,y)
  106.     local i = x+(y-1)*width
  107.     if not isValid(x, y) then return end
  108.     if not gameState[i] == 0 then return end
  109.     gameState[i] = 1
  110.     if myBoard[i] == 0 then
  111.         cord(x,y)
  112.     end
  113.     update()
  114. end
  115.  
  116. local function cord(x,y)
  117.     local state = gameState[x+(y-1)*width]
  118.     local nearbyFlags = 0
  119.     for _, i in ipairs(getNeighbors(x+(y-1)*width)) do
  120.         if gameState[i] == 2 then
  121.             nearbyFlags += 1
  122.         end
  123.     end
  124.    
  125.     if nearbyFlags == myBoard[t] and (state == 1 or state == 3) then
  126.         for ix = x-1, x+1 do
  127.             for iy = y-1, y+1 do
  128.                 open(ix,iy)
  129.             end
  130.         end
  131.     end
  132.     update()
  133. end
  134.  
  135. local function flag(x,y)
  136.     local i = x+(y-1)*width
  137.     local state = gameState[i]
  138.     if state == 0 then
  139.         gameState[i] = 2
  140.     elseif state == 2 then
  141.         gameState[i] = 3
  142.     elseif state = 3 then
  143.         gameState[i] = 0
  144.     end
  145. end
  146.  
  147. local function firstMove(x,y)
  148.     local i = x+(y-1)*width
  149.     if realBoard[i] then
  150.         local newPos = 1
  151.         while realBoard[newPos] do
  152.             newPos += 1
  153.         end
  154.         realBoard[newPos] = true
  155.         realBoard[i] = false
  156.     end
  157.     if openFirstMove then
  158.         local shift = 1
  159.         while countNearbyMines(i) > 0 and shift < width*height do
  160.             local buffer = realBoard[1]
  161.             for s = 1, #realBoard-1 do
  162.                 realBoard[s] = realBoard[s+1]
  163.             end
  164.             realBoard[#realBoard] = buffer
  165.             shift = shift + 1
  166.         end
  167.         if countNearbyMines(i) > 0 then
  168.             shuffle(realBoard)
  169.             firstMove(x,y)
  170.         end
  171.     end
  172.     labelTiles()
  173.     open(x,y)
  174. end
  175.  
  176. local function buildBoard() -- creates physical game board
  177. end
  178.  
  179. local function setupBoard()
  180.     realBoard = {}
  181.     myBoard = {}
  182.     gameState = {}
  183.    
  184.     mines = clamp(mines, 1, width*height-1)
  185.     for i = 1, width*height do
  186.         gameState[i] = 0
  187.         myBoard[i] = 0
  188.         realBoard[i] = false
  189.         if i <= mines then
  190.             realBoard[i] = true
  191.         end
  192.     end
  193.    
  194.     shuffle(realBoard)
  195.     buildBoard()
  196. end
  197.  
  198. setupBoard()
  199. firstMove(math.floor(width/2), math.floor(height/2))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement