Advertisement
HappySunChild

Minesweeper-OpenComputers

Aug 7th, 2022
749
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 6.17 KB | None | 0 0
  1. local args = {...}
  2.  
  3. local component = require("component")
  4. local term = require("term")
  5. local draw = require("draw")
  6. local event = require("event")
  7. local computer = require("computer")
  8. local color3 = require("color3")
  9.  
  10. local gpu = component.gpu
  11. local sx,sy = gpu.getResolution()
  12. local mx,my = sx/2,sy/2
  13.  
  14. local mines = {}
  15.  
  16. local gridSizeX = 20
  17. local gridSizeY = 20
  18.  
  19. local clicks = 0
  20. local ensureSafety = args[2] == "Y"
  21. local assist = args[3] == "Y"
  22. local assistFrequency = tonumber(args[4]) or 5
  23. local debug = args[5] == "Y"
  24.  
  25. local numMines = tonumber(args[1] or 10)
  26. local running = true
  27.  
  28. local openColor = color3.fromRGB(185, 185, 185)
  29. local closeColor = color3.fromRGB(129, 129, 129)
  30.  
  31. local neighborMineColors = {
  32.   color3.fromRGB(0,0,200),
  33.   color3.fromRGB(0,200,0),
  34.   color3.fromRGB(200,0,0),
  35.   color3.fromRGB(200,0,200),
  36.   color3.fromRGB(150,0,0),
  37.   color3.fromRGB(0,150,200),
  38.   color3.fromRGB(132,0,132),
  39.   color3.fromRGB(117,117,117)
  40. }
  41.  
  42. local function placeMine()
  43.   local randX = math.random(1,gridSizeX)
  44.   local randY = math.random(1,gridSizeY)
  45.  
  46.   local cell = mines[randX][randY]
  47.  
  48.   if cell.mine == true or cell.open == true then
  49.     placeMine()
  50.     return
  51.   end
  52.  
  53.   mines[randX][randY].mine = true
  54. end
  55.  
  56. local function setUpBoard()
  57.   for x = 1,gridSizeX do
  58.     mines[x] = {}
  59.     for y = 1,gridSizeY do
  60.       local state = {mine = false, open = false, flagged = false}
  61.       mines[x][y] = state
  62.     end
  63.   end
  64.  
  65.   for i = 1,numMines do
  66.     placeMine()
  67.   end
  68. end
  69.  
  70. local function drawCell(x,y,color,text,textcolor)
  71.   local px, py = (mx - gridSizeX) + x*2, (my - gridSizeY/2) + y
  72.  
  73.   draw.rect(px,py,2,1,color)
  74.   if text then
  75.     draw.text(px,py,text,color,textcolor)
  76.   end
  77. end
  78.  
  79. local function drawBoard()
  80.   local settingsString = ("Mines: %s / First Click Safety: %s / Assist Mode: %s"):format(tostring(numMines),tostring(ensureSafety and "Yes" or "No"),tostring(assist and "Yes" or "No"))
  81.  
  82.   draw.text((mx - gridSizeX), (my - gridSizeY/2) - 1,settingsString, color3.fromRGB(0,0,0),color3.fromHSV(0,0,1))
  83.   draw.rect((mx - gridSizeX),(my - gridSizeY/2),gridSizeX*2 + 4,gridSizeY + 2,color3.fromHSV(0,0,0.1))
  84.  
  85.   for x = 1,gridSizeX do
  86.     for y = 1,gridSizeY do
  87.       local state = mines[x][y]
  88.       drawCell(x,y,debug and (state.mine and openColor) or closeColor)
  89.     end
  90.   end
  91. end
  92.  
  93. local function getNeighbors(x,y)
  94.   local sum = 0
  95.  
  96.   for xoff = -1,1 do
  97.     for yoff = -1,1 do
  98.       if mines[x+xoff] then
  99.         if mines[x+xoff][y+yoff] then
  100.           sum = sum + (mines[x+xoff][y+yoff].mine == true and 1 or 0)
  101.         end
  102.       end
  103.     end
  104.   end
  105.  
  106.   return sum
  107. end
  108.  
  109. local function flagCell(x,y)
  110.     if mines[x] and mines[x][y] then
  111.       local cell = mines[x][y]
  112.  
  113.       if cell.open == false then
  114.         cell.flagged = not cell.flagged
  115.  
  116.         drawCell(x,y,closeColor,cell.flagged and "P" or " ",color3.fromRGB(0,0,0))
  117.  
  118.         computer.beep()
  119.       end
  120.     end
  121. end
  122.  
  123. local function openCell(x,y,fill)
  124.   local nearbyMines = getNeighbors(x,y)
  125.   local cell = mines[x][y]
  126.  
  127.   cell.open = true
  128.  
  129.   drawCell(x,y,openColor,nearbyMines > 0 and nearbyMines or nil,neighborMineColors[nearbyMines])
  130.  
  131.   if cell.mine then
  132.     drawCell(x,y,color3.fromHSV(0,1,1),"@",color3.fromRGB(0,0,0))
  133.     computer.beep(500,2)
  134.     running = false
  135.   else
  136.     if nearbyMines == 0 and cell.flagged == false and cell.open == true then
  137.       --print("open neighbors")
  138.       --openNeighbors(x,y)
  139.  
  140.       for xoff = -1,1 do
  141.         for yoff = -1,1 do
  142.           if mines[x+xoff] and mines[x+xoff][y+yoff] then
  143.             local neighbor = mines[x+xoff][y+yoff]
  144.             if neighbor.mine == false and neighbor.flagged == false and neighbor.open == false then
  145.               openCell(x+xoff,y+yoff,true)
  146.             end
  147.           end
  148.         end
  149.       end
  150.     end
  151.   end
  152.  
  153.   if running and not fill then
  154.     for i = 1,nearbyMines do
  155.       computer.beep(nearbyMines*100,0.05)
  156.     end
  157.   end
  158. end
  159.  
  160. print("Setting up a game of minesweeper with " .. numMines .. " mines")
  161.  
  162. setUpBoard()
  163. drawBoard()
  164.  
  165. while running do
  166.   local _,_,x,y,button = event.pull("touch")
  167.  
  168.   x,y = math.floor(math.abs(((mx-x) - gridSizeX)/2)), math.abs((my-y) - gridSizeY/2)
  169.  
  170.   if button == 0 then
  171.     if mines[x] and mines[x][y] and mines[x][y].open == false and mines[x][y].flagged == false then
  172.       local cell = mines[x][y]
  173.  
  174.       if ensureSafety and clicks == 0 then
  175.         for xoff = -1,1 do
  176.           for yoff = -1,1 do
  177.             if mines[x+xoff] and mines[x+xoff][y+yoff] then
  178.               local cell = mines[x+xoff][y+yoff]
  179.  
  180.               if cell.mine == true then
  181.                 placeMine()
  182.                 cell.mine = false
  183.               end
  184.             end
  185.           end
  186.         end
  187.       end
  188.  
  189.       openCell(x,y)
  190.       clicks = clicks + 1
  191.  
  192.       if assist and clicks % assistFrequency == 0 then
  193.         -- flag a random cell
  194.         local actualMines = {}
  195.  
  196.         for x = 1,gridSizeX do
  197.           for y = 1,gridSizeY do
  198.             if mines[x][y].mine == true and mines[x][y].flagged == false then
  199.               actualMines[#actualMines+1] = {x = x,y = y}
  200.             end
  201.           end
  202.         end
  203.  
  204.         if #actualMines > 0 then
  205.           local cell = actualMines[math.random(1,#actualMines)]
  206.           flagCell(cell.x,cell.y)
  207.         end
  208.       end
  209.     end
  210.   else
  211.     flagCell(x,y)
  212.   end
  213.  
  214.   local count = 0
  215.  
  216.   for x = 1,gridSizeX do
  217.     for y = 1,gridSizeY do
  218.       local cell = mines[x][y]
  219.  
  220.       if cell.flagged == true and cell.mine == true then
  221.         count = count + 1
  222.       end
  223.     end
  224.   end
  225.  
  226.   if count == numMines then
  227.     for x = 1,gridSizeX do
  228.       for y = 1,gridSizeY do
  229.         local cell = mines[x][y]
  230.  
  231.         if cell.mine == true then
  232.           drawCell(x,y,color3.fromRGB(0,255,0),"#",color3.fromRGB(0,0,0))
  233.         else
  234.           if cell.flagged == true then
  235.             drawCell(x,y,color3.fromRGB(255,0,0),"PX",color3.fromRGB(0,0,0))
  236.           end
  237.         end
  238.       end
  239.     end
  240.  
  241.     for i = 3,6 do
  242.       computer.beep((i+2)*100)
  243.     end
  244.  
  245.     computer.beep(1000)
  246.     computer.beep(800)
  247.     computer.beep(1000,0.7)
  248.  
  249.     running = false
  250.   end
  251. end
  252.  
  253. term.setCursor(1,1)
  254. term.clearLine()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement