Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local tW,tH = term.getSize()
- local field = {}
- local cX,cY = 1,1
- local width,height,mines
- local flagCount = 0
- local running = true
- local cursorSwap = true
- local updateTimer
- local function getField(x,y)
- if field[x] == nil then field[x] = {} end
- if field[x][y] == nil then field[x][y] = { fType = "unknown", x=x, y=y } end
- return field[x][y]
- end
- local function getNum(cField)
- if not cField.x or not cField.y then return " " end
- local nums = 0
- for dX=-1,1,1 do
- for dY=-1,1,1 do
- if dX ~= 0 or dY ~= 0 then
- if field[cField.x+dX] and field[cField.x+dX][cField.y+dY] then
- if field[cField.x+dX][cField.y+dY].mine then
- nums=nums+1
- end
- end
- end
- end
- end
- return (nums==0 and " " or string.format("%d",nums))
- end
- local function getChar(field)
- if field == nil then field = { fType = "unknown" } end
- local tab = { flag="F", unknown="#", openMine = "X" }
- if field.fType == "open" then
- return getNum(field)
- else
- return tab[field.fType]
- end
- end
- local function readNum(min,max,intOnly)
- local tX,tY = term.getCursorPos()
- while true do
- term.setCursorPos(tX,tY)
- term.clearLine()
- local inp = tonumber(read())
- if inp and (intOnly == false or (math.abs(inp)==inp)) then
- if (min == nil or inp >= min) and (max == nil or inp <= max) then
- return inp
- end
- end
- end
- end
- local function putMine(x,y)
- local field = getField(x,y)
- if field.mine == true then return false end
- field.mine = true
- return true
- end
- local function drawSpace(x,y)
- term.setCursorPos(x,y)
- if field[x] and field[x][y] then
- term.write(getChar(getField(x,y)))
- else
- term.write(getChar(nil))
- end
- end
- local function drawBorder()
- term.setBackgroundColor(colors.white)
- for y=1,height,1 do
- term.setCursorPos(width+1,y)
- term.write(" ")
- end
- for x=1,width+1,1 do
- term.setCursorPos(x,height+1)
- term.write(" ")
- end
- term.setBackgroundColor(colors.black)
- end
- local function updateFlagCount()
- term.setCursorPos(width+9,5)
- term.write(string.format("%d",mines))
- term.setCursorPos(width+9,6)
- term.write(string.format("%d",flagCount))
- end
- local function drawInstructions()
- term.setCursorPos(width+3,1)
- term.write("Enter - Expose field")
- term.setCursorPos(width+3,2)
- term.write("F - Flag/Unflag field")
- term.setCursorPos(width+3,3)
- term.write("Arrow Keys - Move")
- term.setCursorPos(width+3,5)
- term.write("Mines")
- term.setCursorPos(width+3,6)
- term.write("Flags")
- updateFlagCount()
- end
- local function drawField()
- term.clear()
- for x=1,width,1 do
- for y=1,height,1 do
- drawSpace(x,y)
- end
- end
- drawBorder()
- drawInstructions()
- end
- term.clear()
- term.setCursorPos(1,1)
- print("Width of field?")
- width = readNum(1,tW,true)
- print("Height of field?")
- height = readNum(1,tH,true)
- print("Number of mines?")
- mines = readNum(1,width*height,true)
- term.setCursorBlink(false)
- do
- local minesPut = 0
- while minesPut < mines do
- if putMine(math.random(1,width),math.random(1,height)) then
- minesPut = minesPut + 1
- end
- end
- end
- local function updateCursor()
- cursorSwap = not cursorSwap
- if cursorSwap then
- term.setCursorPos(cX,cY)
- term.write("|")
- else
- drawSpace(cX,cY)
- end
- updateTimer = os.startTimer(0.3)
- end
- local function moveCursor(nX,nY)
- nX = math.min(width,math.max(1,nX))
- nY = math.min(height,math.max(1,nY))
- drawSpace(cX,cY)
- cX,cY = nX,nY
- cursorSwap = false
- updateCursor()
- end
- local function sweep(originField)
- local sweepList = { originField }
- local function sweepCheck(x,y)
- if x >= 1 and x <= width and y >= 1 and y <= height then
- local pField = getField(x,y)
- if pField.fType == "unknown" then
- pField.fType = "open"
- if getNum(pField) == " " then
- table.insert(sweepList,pField)
- end
- end
- end
- end
- while #sweepList > 0 do
- local sweepField = table.remove(sweepList,1)
- for dX=-1,1,1 do
- for dY=-1,1,1 do
- if dX ~= 0 or dY ~= 0 then
- sweepCheck(sweepField.x+dX,sweepField.y+dY)
- end
- end
- end
- end
- drawField()
- end
- local function drawMines()
- for x=1,width,1 do
- for y=1,height,1 do
- if field[x] and field[x][y] then
- local fld = getField(x,y)
- if fld.mine then
- fld.fType = "openMine"
- end
- end
- end
- end
- end
- local function checkWin()
- for x=1,width,1 do
- for y=1,height,1 do
- if not field[x] or not field[x][y] or (field[x][y].fType == "unknown" and field[x][y].mine == false) then
- return false
- end
- end
- end
- return true
- end
- drawField()
- updateTimer = os.startTimer(0.3)
- while running do
- local evData = {os.pullEvent()}
- if evData[1] == "timer" and evData[2] == updateTimer then
- updateCursor()
- elseif evData[1] == "key" then
- if evData[2] == keys.f4 then
- running = false
- elseif evData[2] == keys.left then
- moveCursor(cX-1,cY)
- elseif evData[2] == keys.right then
- moveCursor(cX+1,cY)
- elseif evData[2] == keys.down then
- moveCursor(cX,cY+1)
- elseif evData[2] == keys.up then
- moveCursor(cX,cY-1)
- elseif evData[2] == keys.f then
- local field = getField(cX,cY)
- if field.fType == "unknown" then
- field.fType = "flag"
- flagCount = flagCount + 1
- updateFlagCount()
- elseif field.fType == "flag" then
- field.fType = "unknown"
- flagCount = flagCount - 1
- updateFlagCount()
- end
- cursorSwap = true
- updateCursor()
- elseif evData[2] == keys.enter then
- local field = getField(cX,cY)
- if field.fType == "unknown" or field.fType == "flag" then
- if field.mine then
- drawMines()
- drawField()
- term.setCursorPos(width+3,height)
- print("GAME OVER")
- sleep(5)
- running = false
- else
- field.fType = "open"
- if getNum(field) == " " then
- sweep(field)
- end
- if checkWin() then
- drawField()
- term.setCursorPos(width+3,height)
- print("YOU WON")
- sleep(5)
- running = false
- end
- end
- end
- end
- end
- end
- term.clear()
- term.setCursorPos(1,1)
- term.setCursorBlink(true)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement