Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[ BOARD SETTINGS ]]--
- local size = 9 -- side length of the board (e.g. 5 = 5x5 board)
- local mines = 10 -- how many mines are on the board
- -- Classic difficulty settings: (SIZE x MINES)
- -- beginner = 09x10 (12.35%)
- -- intermediate = 16x40 (15.63%)
- -- expert = 22x99 (20.63%)
- --[[ CELL TABLES ]]--
- local realBoard = {} -- stores which cells have mines
- local gameBoard = {} -- stores how many mines are near each cell
- local liveBoard = {} -- stores current state of each cell (unknown, known, or flagged)
- local showBoard = {} -- stores what is currently being shown to the player
- local rng = Random.new()
- local function toXY(i)
- local x = (i-1)%size+1
- local y = math.floor((i-1)/size)+1
- return x,y
- end
- local function toIndex(x,y)
- return x+(y-1)*size
- end
- local function isValid(x,y)
- return x > 0 and x <= size and y > 0 and y <= size
- end
- local function getNeighbors(x,y)
- local neighbors = {}
- for ix = x-1, x+1 do
- for iy = y-1, y+1 do
- if isValid(ix,iy) then
- table.insert(neighbors,toIndex(ix,iy))
- end
- end
- end
- return neighbors
- end
- local function countNearbyMines(x,y)
- local count = 0
- for _, i in ipairs(getNeighbors(x,y)) do
- count = count + if realBoard[i] then 1 else 0
- end
- end
- local function display()
- local board = '\n\n '
- for i = 1, size do
- board = board..i..' '
- end
- board = board..'\n '
- for i = 1, size-1 do
- board = board..'‾‾'
- end
- board = board..'‾\n'
- for y = 1, size do
- local line = ""
- for x = 1, size do
- local v = showBoard[toIndex(x,y)]
- if v ~= 0 then
- line = line..v
- else
- line = line..'·'
- end
- line = line..' '
- end
- line = y.."| "..line..'\n'
- board = board..line
- end
- print(board..'\n')
- end
- local function update()
- for i, v in ipairs(liveBoard) do
- showBoard[i] = ''
- if v == 0 then
- showBoard[i] = '■'
- elseif v == 1 then
- if realBoard[i] then
- warn("game ova")
- end
- showBoard[i] = gameBoard[i]
- else
- showBoard[i] = '▲'
- end
- end
- display()
- end
- local function expand(x,y)
- local nextLayer = {}
- for _, i in ipairs(getNeighbors(x,y)) do
- if liveBoard[i] ~= 0 then continue end
- liveBoard[i] = 1
- if gameBoard[i] == 0 then
- table.insert(nextLayer,i)
- end
- end
- for _, v in ipairs(nextLayer) do
- expand(toXY(v))
- end
- end
- local firstMove
- local isFirst = true
- local function open(x,y)
- if isFirst then
- isFirst = false
- firstMove(x,y)
- end
- liveBoard[toIndex(x,y)] = 1
- if gameBoard[toIndex(x,y)] == 0 then
- expand(x,y)
- end
- update()
- end
- local function chord(x,y)
- local flagCount = 0
- for _, i in ipairs(getNeighbors(x,y)) do
- if liveBoard[i] == 2 then
- flagCount += 1
- end
- end
- if flagCount == gameBoard[toIndex(x,y)] then
- for _, i in ipairs(getNeighbors(x,y)) do
- if liveBoard[i] ~= 0 then continue end
- open(toXY(i))
- end
- end
- end
- local function getAvailableSpots(myTable,exclude)
- local available = {}
- for i, v in ipairs(myTable) do
- if v ~= exclude then
- table.insert(available,i)
- end
- end
- return available
- end
- local function labelCells()
- for _, m in ipairs(getAvailableSpots(realBoard,false)) do
- for _, c in ipairs(getNeighbors(toXY(m))) do
- gameBoard[c] += 1
- end
- end
- end
- function firstMove(x,y)
- local c = toIndex(x,y)
- local available = getAvailableSpots(realBoard,true)
- for _, i in ipairs(getNeighbors(x,y)) do
- table.remove(available,table.find(available,i))
- if realBoard[i] then
- local newPos = rng:NextInteger(1,#available)
- table.remove(available,newPos)
- realBoard[i] = false
- realBoard[newPos] = true
- end
- end
- labelCells()
- open(x,y)
- end
- local function flag(x,y)
- local c = toIndex(x,y)
- if liveBoard[c] == 1 then return end
- liveBoard[c] = (liveBoard[c]+2)%4
- update()
- end
- local function shuffle(myTable)
- local buffer
- for i = #myTable, 1, -1 do
- local r = rng:NextInteger(1,i)
- buffer = myTable[i]
- myTable[i] = myTable[r]
- myTable[r] = buffer
- end
- return myTable
- end
- local function setup()
- realBoard = {}
- gameBoard = {}
- liveBoard = {}
- showBoard = {}
- isFirst = true
- if mines > size^2+9 then
- error("Too many mines. (Max mine count: "..(size^2+9)..")")
- end
- for i = 1, size^2 do
- realBoard[i] = false
- gameBoard[i] = 0
- liveBoard[i] = 0
- if i <= mines then
- realBoard[i] = true
- end
- end
- shuffle(realBoard)
- end
- setup()
Advertisement
Comments
-
- ebic website: https://mrgris.com/projects/minesweepr/demo/player/
Add Comment
Please, Sign In to add comment
Advertisement