Advertisement
Pinkishu

assignment1-minesweeper

Feb 23rd, 2013
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.30 KB | None | 0 0
  1. local tW,tH = term.getSize()
  2. local field = {}
  3. local cX,cY = 1,1
  4. local width,height,mines
  5. local flagCount = 0
  6. local running = true
  7. local cursorSwap = true
  8. local updateTimer
  9.  
  10. local function getField(x,y)
  11.     if field[x] == nil then field[x] = {} end
  12.     if field[x][y] == nil then field[x][y] = { fType = "unknown", x=x, y=y } end
  13.     return field[x][y]
  14. end
  15.  
  16. local function getNum(cField)
  17.     if not cField.x or not cField.y then return " " end
  18.     local nums = 0
  19.     for dX=-1,1,1 do
  20.         for dY=-1,1,1 do
  21.             if dX ~= 0 or dY ~= 0 then
  22.                 if field[cField.x+dX] and field[cField.x+dX][cField.y+dY] then
  23.                     if field[cField.x+dX][cField.y+dY].mine then
  24.                         nums=nums+1
  25.                     end
  26.                 end
  27.             end
  28.         end
  29.     end
  30.     return (nums==0 and " " or string.format("%d",nums))
  31. end
  32.  
  33. local function getChar(field)
  34.     if field == nil then field = { fType = "unknown" } end
  35.     local tab = { flag="F", unknown="#", openMine = "X" }
  36.     if field.fType == "open" then
  37.         return getNum(field)
  38.     else
  39.         return tab[field.fType]
  40.     end
  41. end
  42.  
  43. local function readNum(min,max,intOnly)
  44.     local tX,tY = term.getCursorPos()
  45.  
  46.     while true do
  47.         term.setCursorPos(tX,tY)
  48.         term.clearLine()
  49.  
  50.         local inp = tonumber(read())
  51.         if inp and (intOnly == false or (math.abs(inp)==inp)) then
  52.             if (min == nil or inp >= min) and (max == nil or inp <= max) then
  53.                 return inp
  54.             end
  55.         end
  56.  
  57.     end
  58. end
  59.  
  60. local function putMine(x,y)
  61.     local field = getField(x,y)
  62.     if field.mine == true then return false end
  63.     field.mine = true
  64.     return true
  65. end
  66.  
  67. local function drawSpace(x,y)
  68.     term.setCursorPos(x,y)
  69.     if field[x] and field[x][y] then
  70.         term.write(getChar(getField(x,y)))
  71.     else
  72.         term.write(getChar(nil))
  73.     end    
  74. end
  75.  
  76. local function drawBorder()
  77.     term.setBackgroundColor(colors.white)
  78.     for y=1,height,1 do
  79.         term.setCursorPos(width+1,y)
  80.         term.write(" ")
  81.     end
  82.     for x=1,width+1,1 do
  83.         term.setCursorPos(x,height+1)
  84.         term.write(" ")
  85.     end
  86.     term.setBackgroundColor(colors.black)
  87. end
  88.  
  89. local function updateFlagCount()
  90.     term.setCursorPos(width+9,5)
  91.     term.write(string.format("%d",mines))
  92.     term.setCursorPos(width+9,6)
  93.     term.write(string.format("%d",flagCount))
  94. end
  95.  
  96. local function drawInstructions()
  97.     term.setCursorPos(width+3,1)
  98.     term.write("Enter - Expose field")
  99.     term.setCursorPos(width+3,2)
  100.     term.write("F - Flag/Unflag field")
  101.     term.setCursorPos(width+3,3)
  102.     term.write("Arrow  Keys - Move")
  103.     term.setCursorPos(width+3,5)
  104.     term.write("Mines")
  105.     term.setCursorPos(width+3,6)
  106.     term.write("Flags")
  107.     updateFlagCount()
  108. end
  109.  
  110. local function drawField()
  111.     term.clear()
  112.     for x=1,width,1 do
  113.         for y=1,height,1 do
  114.             drawSpace(x,y)
  115.         end
  116.     end
  117.     drawBorder()
  118.     drawInstructions()
  119. end
  120.  
  121.  
  122.  
  123. term.clear()
  124. term.setCursorPos(1,1)
  125. print("Width of field?")
  126. width = readNum(1,tW,true)
  127. print("Height of field?")
  128. height = readNum(1,tH,true)
  129. print("Number of mines?")
  130. mines = readNum(1,width*height,true)
  131. term.setCursorBlink(false)
  132.  
  133. do
  134.     local minesPut = 0
  135.     while minesPut < mines do
  136.         if putMine(math.random(1,width),math.random(1,height)) then
  137.             minesPut = minesPut + 1
  138.         end
  139.     end
  140. end
  141.  
  142. local function updateCursor()
  143.     cursorSwap = not cursorSwap
  144.     if cursorSwap then
  145.         term.setCursorPos(cX,cY)
  146.         term.write("|")
  147.     else
  148.         drawSpace(cX,cY)
  149.     end
  150.     updateTimer = os.startTimer(0.3)
  151. end
  152.  
  153. local function moveCursor(nX,nY)
  154.     nX = math.min(width,math.max(1,nX))
  155.     nY = math.min(height,math.max(1,nY))
  156.     drawSpace(cX,cY)
  157.     cX,cY = nX,nY
  158.     cursorSwap = false
  159.     updateCursor()    
  160. end
  161.  
  162. local function sweep(originField)
  163.     local sweepList = { originField }
  164.     local function sweepCheck(x,y)
  165.         if x >= 1 and x <= width and y >= 1 and y <= height then
  166.             local pField = getField(x,y)
  167.             if pField.fType == "unknown" then
  168.                 pField.fType = "open"
  169.                 if getNum(pField) == " " then
  170.                     table.insert(sweepList,pField)
  171.                 end
  172.             end
  173.         end
  174.     end
  175.     while #sweepList > 0 do
  176.         local sweepField = table.remove(sweepList,1)
  177.         for dX=-1,1,1 do
  178.             for dY=-1,1,1 do
  179.                 if dX ~= 0 or dY ~= 0 then
  180.                     sweepCheck(sweepField.x+dX,sweepField.y+dY)
  181.                 end
  182.             end
  183.         end
  184.     end
  185.     drawField()
  186. end
  187.  
  188. local function drawMines()
  189.     for x=1,width,1 do
  190.         for y=1,height,1 do
  191.             if field[x] and field[x][y] then
  192.                 local fld = getField(x,y)
  193.                 if fld.mine then
  194.                     fld.fType = "openMine"
  195.                 end
  196.             end
  197.         end
  198.     end
  199. end
  200.  
  201. local function checkWin()
  202.     for x=1,width,1 do
  203.         for y=1,height,1 do
  204.             if not field[x] or not field[x][y] or (field[x][y].fType == "unknown" and field[x][y].mine == false) then
  205.                 return false
  206.             end
  207.         end
  208.     end
  209.     return true
  210. end
  211.  
  212. drawField()
  213. updateTimer = os.startTimer(0.3)
  214. while running do
  215.     local evData = {os.pullEvent()}
  216.  
  217.     if evData[1] == "timer" and evData[2] == updateTimer then
  218.         updateCursor()
  219.     elseif evData[1] == "key" then
  220.         if evData[2] == keys.f4 then
  221.             running = false
  222.         elseif evData[2] == keys.left then
  223.             moveCursor(cX-1,cY)
  224.         elseif evData[2] == keys.right then
  225.             moveCursor(cX+1,cY)
  226.         elseif evData[2] == keys.down then
  227.             moveCursor(cX,cY+1)
  228.         elseif evData[2] == keys.up then
  229.             moveCursor(cX,cY-1)
  230.         elseif evData[2] == keys.f then
  231.             local field = getField(cX,cY)
  232.             if field.fType == "unknown" then
  233.                 field.fType = "flag"
  234.                 flagCount = flagCount + 1
  235.                 updateFlagCount()
  236.             elseif field.fType == "flag" then
  237.                 field.fType = "unknown"
  238.                 flagCount = flagCount - 1
  239.                 updateFlagCount()
  240.             end
  241.             cursorSwap = true
  242.             updateCursor()
  243.         elseif evData[2] == keys.enter then
  244.             local field = getField(cX,cY)
  245.             if field.fType == "unknown" or field.fType == "flag" then
  246.                 if field.mine then
  247.                     drawMines()
  248.                     drawField()
  249.                     term.setCursorPos(width+3,height)
  250.                     print("GAME OVER")
  251.                     sleep(5)
  252.                     running = false
  253.                 else
  254.                     field.fType = "open"
  255.                     if getNum(field) == " " then
  256.                         sweep(field)
  257.                     end
  258.                     if checkWin() then
  259.                         drawField()
  260.                         term.setCursorPos(width+3,height)
  261.                         print("YOU WON")
  262.                         sleep(5)
  263.                         running = false
  264.                     end
  265.                 end
  266.             end
  267.         end
  268.     end
  269. end
  270.  
  271. term.clear()
  272. term.setCursorPos(1,1)
  273. term.setCursorBlink(true)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement