123 lines
3.1 KiB
Lua
123 lines
3.1 KiB
Lua
local utils = require "sudoku.utils"
|
|
|
|
local sudoku = {}
|
|
|
|
function sudoku.iterZones(board)
|
|
local row = 0
|
|
local column = 0
|
|
local block = 0
|
|
return function()
|
|
local a = {}
|
|
local p = {}
|
|
if row < 9 then
|
|
row = row + 1
|
|
for i = 1, 9 do
|
|
a[i] = board[row][i]
|
|
p[i] = {row, i}
|
|
end
|
|
return a, p
|
|
end
|
|
if column < 9 then
|
|
column = column + 1
|
|
for i = 1, 9 do
|
|
a[i] = board[i][column]
|
|
p[i] = {i, column}
|
|
end
|
|
return a, p
|
|
end
|
|
if block < 9 then
|
|
block = block + 1
|
|
local dx = math.floor((block - 1) / 3)
|
|
local dy = (block - 1) % 3
|
|
local n = 0
|
|
for i = 1, 3 do
|
|
for j = 1, 3 do
|
|
local x = i + 3 * dx
|
|
local y = j + 3 * dy
|
|
n = n + 1
|
|
a[n] = board[x][y]
|
|
p[n] = {x, y}
|
|
end
|
|
end
|
|
return a, p
|
|
end
|
|
end
|
|
end
|
|
|
|
local function checkAUX(zone, pos)
|
|
local isComplete = true
|
|
local ok = true
|
|
local conflictList = {}
|
|
local n = 0
|
|
for i = 1, 8 do
|
|
for j = i+1, 9 do
|
|
if zone[i] == 0 then
|
|
isComplete = false
|
|
elseif zone[i] == zone[j] then
|
|
ok = false
|
|
n = n + 1
|
|
conflictList[n] = {x1=pos[i][1], y1=pos[i][2], x2=pos[j][1], y2=pos[j][2]}
|
|
end
|
|
end
|
|
end
|
|
return ok, isComplete, conflictList
|
|
end
|
|
|
|
function sudoku.checkBoard(board)
|
|
local ok = true
|
|
local isComplete = true
|
|
local conflictList = {}
|
|
for zone, pos in sudoku.iterZones(board) do
|
|
local tOk, tIsComplete, tConflictList = checkAUX(zone, pos)
|
|
if not tOk then ok = false end
|
|
if not tIsComplete then isComplete = false end
|
|
for _, conflict in ipairs(tConflictList) do
|
|
table.insert(conflictList, conflict)
|
|
end
|
|
end
|
|
return ok, isComplete, conflictList
|
|
end
|
|
|
|
function sudoku.calCellValidOptions(board, x, y)
|
|
if board[x][y] ~= 0 then return {} end
|
|
local u = {}
|
|
local v = {}
|
|
for i = 1, 9 do
|
|
if board[x][i] ~= 0 then table.insert(u, board[x][i]) end
|
|
if board[i][y] ~= 0 then table.insert(u, board[i][y]) end
|
|
end
|
|
local dx = math.floor((x - 1) / 3) * 3
|
|
local dy = math.floor((y - 1) / 3) * 3
|
|
for i = 1, 3 do
|
|
for j = 1, 3 do
|
|
local a = board[i+dx][j+dy]
|
|
if a ~= 0 then table.insert(u, a) end
|
|
end
|
|
end
|
|
for i = 1, 9 do
|
|
local found = false
|
|
for _, elm in ipairs(u) do
|
|
if elm == i then found = true; break end
|
|
end
|
|
if not found then table.insert(v, i) end
|
|
end
|
|
return v
|
|
end
|
|
|
|
function sudoku.buildSearchSpave(board)
|
|
local s = {}
|
|
for i = 1, 9 do
|
|
s[i] = {}
|
|
for j = 1, 9 do
|
|
s[i][j] = sudoku.calCellValidOptions(board, i, j)
|
|
end
|
|
end
|
|
return s
|
|
end
|
|
|
|
sudoku.cloneBoard = utils.cloneBoard
|
|
sudoku.createEmptyBoard = utils.createEmptyBoard
|
|
sudoku.loadBoard = utils.loadBoard
|
|
return sudoku
|
|
|