Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Minesweeper Game for SimpleOS
- -- CC: Tweaked compatible
- local w, h = term.getSize()
- -- Game settings
- local gridWidth = 9
- local gridHeight = 9
- local mineCount = 10
- local startX = math.floor((w - gridWidth * 2) / 2)
- local startY = 3
- -- Game state
- local grid = {}
- local revealed = {}
- local flagged = {}
- local gameOver = false
- local gameWon = false
- local cursorX, cursorY = 1, 1
- local firstClick = true
- -- Initialize grid
- local function initGrid()
- grid = {}
- revealed = {}
- flagged = {}
- for y = 1, gridHeight do
- grid[y] = {}
- revealed[y] = {}
- flagged[y] = {}
- for x = 1, gridWidth do
- grid[y][x] = 0
- revealed[y][x] = false
- flagged[y][x] = false
- end
- end
- end
- -- Place mines (avoiding first click)
- local function placeMines(avoidX, avoidY)
- local placed = 0
- while placed < mineCount do
- local x = math.random(1, gridWidth)
- local y = math.random(1, gridHeight)
- if grid[y][x] ~= -1 and not (x == avoidX and y == avoidY) then
- grid[y][x] = -1
- placed = placed + 1
- end
- end
- -- Calculate numbers
- for y = 1, gridHeight do
- for x = 1, gridWidth do
- if grid[y][x] ~= -1 then
- local count = 0
- for dy = -1, 1 do
- for dx = -1, 1 do
- local nx, ny = x + dx, y + dy
- if nx >= 1 and nx <= gridWidth and ny >= 1 and ny <= gridHeight then
- if grid[ny][nx] == -1 then
- count = count + 1
- end
- end
- end
- end
- grid[y][x] = count
- end
- end
- end
- end
- -- Count flags
- local function countFlags()
- local count = 0
- for y = 1, gridHeight do
- for x = 1, gridWidth do
- if flagged[y][x] then count = count + 1 end
- end
- end
- return count
- end
- -- Check win condition
- local function checkWin()
- for y = 1, gridHeight do
- for x = 1, gridWidth do
- if grid[y][x] ~= -1 and not revealed[y][x] then
- return false
- end
- end
- end
- return true
- end
- -- Reveal cell
- local function reveal(x, y)
- if x < 1 or x > gridWidth or y < 1 or y > gridHeight then return end
- if revealed[y][x] or flagged[y][x] then return end
- revealed[y][x] = true
- if grid[y][x] == -1 then
- gameOver = true
- -- Reveal all mines
- for my = 1, gridHeight do
- for mx = 1, gridWidth do
- if grid[my][mx] == -1 then
- revealed[my][mx] = true
- end
- end
- end
- return
- end
- if grid[y][x] == 0 then
- -- Flood fill
- for dy = -1, 1 do
- for dx = -1, 1 do
- reveal(x + dx, y + dy)
- end
- end
- end
- if checkWin() then
- gameWon = true
- end
- end
- -- Draw game
- local function draw()
- term.setBackgroundColor(colors.black)
- term.clear()
- -- Title
- term.setTextColor(colors.yellow)
- term.setCursorPos(math.floor(w/2) - 5, 1)
- term.write("MINESWEEPER")
- -- Info
- term.setTextColor(colors.white)
- term.setCursorPos(2, 2)
- term.write("Mines: " .. mineCount .. " Flags: " .. countFlags())
- term.setCursorPos(w - 10, 2)
- term.write("[Q] Quit")
- -- Draw grid
- local numberColors = {
- colors.blue, colors.green, colors.red, colors.purple,
- colors.brown, colors.cyan, colors.gray, colors.black
- }
- for y = 1, gridHeight do
- for x = 1, gridWidth do
- local screenX = startX + (x - 1) * 2
- local screenY = startY + y - 1
- term.setCursorPos(screenX, screenY)
- local isSelected = (x == cursorX and y == cursorY)
- if revealed[y][x] then
- if grid[y][x] == -1 then
- term.setBackgroundColor(colors.red)
- term.setTextColor(colors.black)
- term.write("* ")
- elseif grid[y][x] == 0 then
- term.setBackgroundColor(colors.lightGray)
- term.write(" ")
- else
- term.setBackgroundColor(colors.lightGray)
- term.setTextColor(numberColors[grid[y][x]] or colors.black)
- term.write(grid[y][x] .. " ")
- end
- elseif flagged[y][x] then
- term.setBackgroundColor(isSelected and colors.yellow or colors.gray)
- term.setTextColor(colors.red)
- term.write("F ")
- else
- term.setBackgroundColor(isSelected and colors.yellow or colors.gray)
- term.setTextColor(colors.white)
- term.write("# ")
- end
- end
- end
- -- Controls
- term.setBackgroundColor(colors.black)
- term.setTextColor(colors.gray)
- term.setCursorPos(2, startY + gridHeight + 1)
- term.write("Arrow keys: Move SPACE: Reveal F: Flag")
- end
- -- Game over screen
- local function showGameOver()
- term.setTextColor(colors.red)
- term.setCursorPos(math.floor(w/2) - 4, startY + gridHeight + 3)
- term.write("GAME OVER!")
- term.setTextColor(colors.white)
- term.setCursorPos(math.floor(w/2) - 8, startY + gridHeight + 4)
- term.write("ENTER=Restart Q=Quit")
- end
- -- Win screen
- local function showWin()
- term.setTextColor(colors.lime)
- term.setCursorPos(math.floor(w/2) - 4, startY + gridHeight + 3)
- term.write("YOU WIN!")
- term.setTextColor(colors.white)
- term.setCursorPos(math.floor(w/2) - 8, startY + gridHeight + 4)
- term.write("ENTER=Restart Q=Quit")
- end
- -- Main game loop
- local function run()
- initGrid()
- gameOver = false
- gameWon = false
- firstClick = true
- cursorX, cursorY = math.floor(gridWidth/2), math.floor(gridHeight/2)
- while true do
- draw()
- if gameOver then
- showGameOver()
- elseif gameWon then
- showWin()
- end
- local event, key = os.pullEvent("key")
- if gameOver or gameWon then
- if key == keys.enter then
- initGrid()
- gameOver = false
- gameWon = false
- firstClick = true
- cursorX, cursorY = math.floor(gridWidth/2), math.floor(gridHeight/2)
- elseif key == keys.q then
- return
- end
- else
- if key == keys.up then
- cursorY = math.max(1, cursorY - 1)
- elseif key == keys.down then
- cursorY = math.min(gridHeight, cursorY + 1)
- elseif key == keys.left then
- cursorX = math.max(1, cursorX - 1)
- elseif key == keys.right then
- cursorX = math.min(gridWidth, cursorX + 1)
- elseif key == keys.space then
- if not flagged[cursorY][cursorX] then
- if firstClick then
- placeMines(cursorX, cursorY)
- firstClick = false
- end
- reveal(cursorX, cursorY)
- end
- elseif key == keys.f then
- if not revealed[cursorY][cursorX] then
- flagged[cursorY][cursorX] = not flagged[cursorY][cursorX]
- end
- elseif key == keys.q then
- return
- end
- end
- end
- end
- run()
Advertisement