Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ----------------------------------------------MISC FUNCS
- if fs.exists("console") then
- shell.run("delete console")
- end
- local debug = true
- local h = fs.open("console","a")
- function log(t)
- if debug then
- if type(t) == "table" then
- for i,v in pairs(t) do
- h.write("i = ")
- h.write(i)
- h.write(" v = ")
- h.write(v)
- h.write("\n")
- end
- else
- h.write(t)
- h.write("\n")
- end
- h.flush()
- end
- end
- function logBoard(board, currentPos, futurePos)
- if debug then
- for y = 1, 9 do
- term.setCursorPos(1, y + math.ceil(y/3) - 1)
- for x = 1, 9 do
- if tonumber(board[y][x]) then
- term.setTextColor(colors.red)
- write(board[y][x])
- else
- term.setTextColor(colors.white)
- write("0")
- end
- if x == 3 or x == 6 then
- write(" ")
- end
- end
- end
- if currentPos then
- term.setTextColor(colors.orange)
- term.setCursorPos(currentPos[1] + math.floor((currentPos[1]-1)/3), currentPos[2] + math.floor((currentPos[2]-1)/3))
- term.write(board[currentPos[2]][currentPos[1]])
- end
- if futurePos then
- term.setTextColor(colors.lime)
- term.setCursorPos(futurePos[1] + math.floor((futurePos[1]-1)/3), currentPos[2] + math.floor((futurePos[2]-1)/3))
- term.write("*")
- os.pullEvent("mouse_click")
- end
- print("")
- sleep(.1)
- end
- end
- function printBoard(board, num)
- for y = 1, 9 do
- term.setCursorPos(1, y + math.ceil(y/3) - 1)
- for x = 1, 9 do
- if board[y][x][num] == 1 then
- term.setTextColor(colors.red)
- write(num)
- else
- term.setTextColor(colors.white)
- write("0")
- end
- if x == 3 or x == 6 then
- write(" ")
- end
- end
- end
- print("")
- end
- ----------------------------------------------GENERATION
- function initializeBoard(board)
- for y = 1, 9 do
- board[y] = {}
- for x = 1, 9 do
- board[y][x] = {1, 1, 1, 1, 1, 1, 1, 1, 1}
- end
- end
- end
- function generatePuzzle(board)
- log("-=-=-=-=-=-=-=-Starting Generation Algorithm-=-=-=-=-=-=-=-")
- for n = 1, 9 do
- log("Filling in " .. n .. " --------------")
- local scanRef = {1, 1, 1, 1, 1, 1, 1, 1, 1}
- for q = 1, 9 do
- log("Quadrant " .. q .. "...")
- scanRef = scanPatterns(board, n, scanRef)
- local cells = getAvailableCells(board, q, n)
- local c = cells[math.random(1, #cells)]
- isolateNumber(board, c[1], c[2], n)
- log("Quadrant " .. q .. " isolated>>")
- end
- end
- finalizeBoard(board)
- end
- function isolateNumber(board, x, y, num)
- for i = 1, 9 do
- board[i][x][num] = 0 --whole row
- board[y][i][num] = 0 --whole column
- board[(math.ceil(y/3)-1)*3+(i-1)%3+1][(math.ceil(x/3)-1)*3+(i-1)%3+1][num] = 0
- --whole box (holy crap! what a line of code!)
- end
- for i = 1, 9 do
- board[y][x][i] = 0
- end
- board[y][x][num] = 1
- end
- function scanPatterns(board, num, refTab)
- local flag = true
- while flag do
- flag = false
- for i = 1, 9 do
- local cells = getAvailableCells(board, i, num)
- if #cells < 1 then
- --convertBoard(board)
- printBoard(board, num)
- error("ERROR: No avilable places for number " .. num .. " in quadrant " .. i)
- elseif #cells <= 3 and refTab[i] == 1 then
- if #cells == 1 then
- isolateNumber(board, cells[1][1], cells[1][2], num)
- else
- local rays = detectLine(cells)
- for _, v in ipairs(rays) do
- log("Row?: " .. tostring(v[1]) .. " Slice:" .. v[2] .. " | Q" .. i)
- eliminateLine(board, v[1], v[2], i, num)
- end
- end
- refTab[i] = 0
- flag = true
- break;
- end
- end
- end
- return refTab
- end
- function getAvailableNum(board, quadrant, num)
- local cells = {}
- for i = 1, 3 do
- for j = 1, 3 do
- if board[(math.ceil(quadrant/3)-1)*3 + i][(quadrant-1)%3 + j][num] == 1 then
- table.insert(cells, {(quadrant-1)%3 + j, (math.ceil(quadrant/3)-1)*3 + i})
- end
- end
- end
- return cells
- end
- function detectLine(cells)
- local xList = {}
- local yList = {}
- for i, v in ipairs(cells) do
- table.insert(xList, v[1])
- table.insert(yList, v[2])
- end
- local rays = {}
- table.sort(xList)
- table.sort(yList)
- for i = 1, #xList-1 do
- if xList[i] == xList[i+1] then
- table.insert(rays, {true, xList[i]})
- break;
- end
- end
- for i = 1, #yList-1 do
- if yList[i] == yList[i+1] then
- table.insert(rays, {false, yList[i]})
- break;
- end
- end
- return rays
- end
- function eliminateLine(board, row, slice, homeQuadrant, num) --num: the current number
- --int[][][]board: the board, boolean row: whether it is a row or a column
- --int slice: row/col being altered, homeQuadrant: unnaffected quadrant
- if row then
- for i = 1, 9 do
- if math.ceil(i/3) ~= (homeQuadrant-1)%3 + 1 then
- board[slice][i][num] = 0
- end
- end
- else
- for i = 1, 9 do
- if math.ceil(i/3) ~= math.ceil(homeQuadrant/3) then
- board[i][slice][num] = 0
- end
- end
- end
- end
- function convertBoard(board)
- for y = 1, 9 do
- for x = 1, 9 do
- local num = 0
- for i = 1, 9 do
- if board[y][x][i] == 1 then
- if num ~= 0 then
- --error("ERROR: Multiple answers at " .. x .. ":" .. y)
- board[y][x] = 0
- break;
- else
- num = i
- end
- end
- end
- if num == 0 then
- --error("ERROR: No answers at " .. x .. ":" .. y)
- board[y][x] = {}
- else
- board[y][x] = num
- end
- end
- end
- end
- function finalizeBoard(board)
- for y = 1, 9 do
- for x = 1, 9 do
- local num = 0
- for i = 1, 9 do
- if board[y][x][i] == 1 then
- if num ~= 0 then
- error("ERROR: Multiple answers at " .. x .. ":" .. y)
- end
- num = i
- end
- end
- if num == 0 then
- error("ERROR: No answers at " .. x .. ":" .. y)
- end
- board[y][x] = num
- end
- end
- end
- function getAvailableCells(board, quadrant, num)
- local result = {}
- for y = (math.ceil(quadrant/3)-1)*3 + 1, (math.ceil(quadrant/3)-1)*3 + 3 do
- for x = ((quadrant-1)%3)*3 + 1, ((quadrant-1)%3)*3 + 3 do
- if board[y][x][num] == 1 then
- table.insert(result, {x, y})
- end
- end
- end
- return result
- end
- function iLocate(i, quadrantX, quadrantY, board)
- for y = 1, 3 do
- for x = 1, 3 do
- if board[y + (quadrantY-1)*3][x + (quadrantX-1)*3] == i then
- return {x, y}, {x + (quadrantX-1)*3, y + (quadrantY-1)*3}
- end
- end
- end
- printBoard(board)
- error("iLocate Failed")
- end
- ----------------------------------------------SOLUTION
- ----------------------------------------------ENGINE
- local tArgs = {...}
- term.setBackgroundColor(colors.black)
- term.setTextColor(colors.white)
- term.clear()
- if tArgs[1] == "generate" or tArgs[1] == "gen" then
- local board = {}
- initializeBoard(board)
- generatePuzzle(board)
- printBoard(board)
- elseif tArgs[1] == "solve" then
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement