midway refactoring sudoku logic
This commit is contained in:
		
							parent
							
								
									3555c49ad4
								
							
						
					
					
						commit
						ba7db7a04e
					
				| @ -1,8 +1,86 @@ | |||||||
| local utils = require "sudoku.utils" | -- dbg = require ("debugger") | ||||||
|  | -- dbg.auto_where = 2 | ||||||
| 
 | 
 | ||||||
| local sudoku = {} | function table2string(t) | ||||||
|  |     local myself = table2string | ||||||
|  |     local l = {} | ||||||
|  |     local n = 0 | ||||||
|  |     for k, v in pairs(t) do | ||||||
|  |         n = n + 1 | ||||||
|  |         if type(v) == "table" then | ||||||
|  |             l[n] = k .. ': ' .. myself(v) | ||||||
|  |         elseif type(v) == "string" then | ||||||
|  |             l[n] = k .. ': ' .. '"' .. v .. '"' | ||||||
|  |         else | ||||||
|  |             l[n] = k .. ': ' .. v | ||||||
|  |         end | ||||||
|  |     end | ||||||
|  |     return "{" .. table.concat(l, ", ") .. "}" | ||||||
|  | end | ||||||
| 
 | 
 | ||||||
| function sudoku.iterZones(board) | function find(array, element) | ||||||
|  |     local index = 0 | ||||||
|  |     for i = 1, #array do | ||||||
|  |         if array[i] == element then | ||||||
|  |             index = i | ||||||
|  |             break | ||||||
|  |         end | ||||||
|  |     end | ||||||
|  |     return index | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | function createEmptyBoard() | ||||||
|  |     local b = {} | ||||||
|  |     for i = 1, 9 do | ||||||
|  |         b[i] = {} | ||||||
|  |         for j = 1, 9 do | ||||||
|  |             b[i][j] = 0 | ||||||
|  |         end | ||||||
|  |     end | ||||||
|  |     return b | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | function cloneBoard(b) | ||||||
|  |     local c = {} | ||||||
|  |     for i = 1, 9 do | ||||||
|  |         c[i] = {} | ||||||
|  |         for j = 1, 9 do | ||||||
|  |             c[i][j] = b[i][j] | ||||||
|  |         end | ||||||
|  |     end | ||||||
|  |     return c | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | function loadBoard(fn) | ||||||
|  |     local boards = {} | ||||||
|  |     local r = 0 | ||||||
|  |     local board = {} | ||||||
|  |     for line in io.lines(fn) do | ||||||
|  |         if line:gsub("%s+", "") == "" then | ||||||
|  |             table.insert(boards, board) | ||||||
|  |             board = {} | ||||||
|  |             r = 0 | ||||||
|  |         else | ||||||
|  |             r = r + 1 | ||||||
|  |             local c = 0 | ||||||
|  |             board[r] = {} | ||||||
|  |             for item in line:gmatch("%w+") do | ||||||
|  |                 c = c + 1 | ||||||
|  |                 board[r][c] = tonumber(item) | ||||||
|  |             end | ||||||
|  |         end | ||||||
|  |     end | ||||||
|  |     table.insert(boards, board) | ||||||
|  |     return boards | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | function showBoard(board) | ||||||
|  |     for row = 1, 9 do | ||||||
|  |         print(table.concat(board[row], " ")) | ||||||
|  |     end | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | function iterZones(board) | ||||||
|     local row = 0 |     local row = 0 | ||||||
|     local column = 0 |     local column = 0 | ||||||
|     local block = 0 |     local block = 0 | ||||||
| @ -44,7 +122,7 @@ function sudoku.iterZones(board) | |||||||
|     end |     end | ||||||
| end | end | ||||||
| 
 | 
 | ||||||
| local function checkAUX(zone, pos) | function checkAUX(zone, pos) | ||||||
|     local isComplete = true |     local isComplete = true | ||||||
|     local ok = true |     local ok = true | ||||||
|     local conflictList = {} |     local conflictList = {} | ||||||
| @ -63,11 +141,11 @@ local function checkAUX(zone, pos) | |||||||
|     return ok, isComplete, conflictList |     return ok, isComplete, conflictList | ||||||
| end | end | ||||||
| 
 | 
 | ||||||
| function sudoku.checkBoard(board) | function checkBoard(board) | ||||||
|     local ok = true |     local ok = true | ||||||
|     local isComplete = true |     local isComplete = true | ||||||
|     local conflictList = {} |     local conflictList = {} | ||||||
|     for zone, pos in sudoku.iterZones(board) do |     for zone, pos in iterZones(board) do | ||||||
|         local tOk, tIsComplete, tConflictList = checkAUX(zone, pos) |         local tOk, tIsComplete, tConflictList = checkAUX(zone, pos) | ||||||
|         if not tOk then ok = false end |         if not tOk then ok = false end | ||||||
|         if not tIsComplete then isComplete = false end |         if not tIsComplete then isComplete = false end | ||||||
| @ -75,10 +153,11 @@ function sudoku.checkBoard(board) | |||||||
|             table.insert(conflictList, conflict) |             table.insert(conflictList, conflict) | ||||||
|         end |         end | ||||||
|     end |     end | ||||||
|  |     if not ok then isComplete = false end | ||||||
|     return ok, isComplete, conflictList |     return ok, isComplete, conflictList | ||||||
| end | end | ||||||
| 
 | 
 | ||||||
| function sudoku.calCellValidOptions(board, x, y) | function calCellValidOptions(board, x, y) | ||||||
|     if board[x][y] ~= 0 then return {} end |     if board[x][y] ~= 0 then return {} end | ||||||
|     local u = {} |     local u = {} | ||||||
|     local v = {} |     local v = {} | ||||||
| @ -104,19 +183,360 @@ function sudoku.calCellValidOptions(board, x, y) | |||||||
|     return v |     return v | ||||||
| end | end | ||||||
| 
 | 
 | ||||||
| function sudoku.buildSearchSpace(board) | function buildSearchSpace(board) | ||||||
|     local s = {} |     local s = {} | ||||||
|     for i = 1, 9 do |     for i = 1, 9 do | ||||||
|         s[i] = {} |         s[i] = {} | ||||||
|         for j = 1, 9 do |         for j = 1, 9 do | ||||||
|             s[i][j] = sudoku.calCellValidOptions(board, i, j) |             s[i][j] = calCellValidOptions(board, i, j) | ||||||
|         end |         end | ||||||
|     end |     end | ||||||
|     return s |     return s | ||||||
| end | end | ||||||
| 
 | 
 | ||||||
| sudoku.cloneBoard = utils.cloneBoard | function findPairsIndSearchSpace(board, searchSpace) | ||||||
| sudoku.createEmptyBoard = utils.createEmptyBoard |     local r = {} | ||||||
| sudoku.loadBoard = utils.loadBoard |     local zoneIndex = 0 | ||||||
| return sudoku |     for zone, pos in iterZones(board) do | ||||||
|  |         zoneIndex = zoneIndex + 1 | ||||||
|  |         for i = 1, 8 do | ||||||
|  |             local x1 = pos[i][1] | ||||||
|  |             local y1 = pos[i][2] | ||||||
|  |             local s1 = searchSpace[x1][y1] | ||||||
|  |             if #s1 == 2 then | ||||||
|  |                 for j = i + 1, 9 do | ||||||
|  |                     local x2 = pos[j][1] | ||||||
|  |                     local y2 = pos[j][2] | ||||||
|  |                     local s2 = searchSpace[x2][y2] | ||||||
|  |                     if #s2 == 2 then | ||||||
|  |                         if s1[1] == s2[1] and s1[2] == s2[2] then | ||||||
|  |                             -- if zoneIndex <= 18 or x1 ~= x2 and y1 ~= y2 then | ||||||
|  |                             table.insert(r, {zoneIndex=zoneIndex, cells={i, j}, pair=s1}) | ||||||
|  |                                 -- print("----------") | ||||||
|  |                                 -- print("zone: ", zoneIndex) | ||||||
|  |                                 -- print(table2string(zone)) | ||||||
|  |                                 -- print(i, j) | ||||||
|  |                                 -- print(table2string(s1)) | ||||||
|  |                             -- end | ||||||
|  |                         end | ||||||
|  |                     end | ||||||
|  |                 end | ||||||
|  |             end | ||||||
|  |         end | ||||||
|  |     end | ||||||
|  |     return r | ||||||
|  | end | ||||||
| 
 | 
 | ||||||
|  | function showSearchSpace(s) | ||||||
|  |     local hl = ("+-------+-------+-------+-------+-------+-------+-------+-------+-------+") | ||||||
|  |     print(hl) | ||||||
|  |     for i = 1, 27 do | ||||||
|  |         local x = math.floor((i - 1) / 3) + 1 | ||||||
|  |         local a = (i - 1) % 3 | ||||||
|  |         local row = {} | ||||||
|  |         for j = 1, 27 do | ||||||
|  |             local y = math.floor((j - 1) / 3) + 1 | ||||||
|  |             local k = ((j - 1) % 3 + 1) + 3 * a | ||||||
|  |             local found = false | ||||||
|  |             for _, m in ipairs(s[x][y]) do | ||||||
|  |                 if m == k then found = true; break end | ||||||
|  |             end | ||||||
|  |             if found then | ||||||
|  |                 table.insert(row, k) | ||||||
|  |             else | ||||||
|  |                 table.insert(row, " ") | ||||||
|  |             end | ||||||
|  |             if j % 3 == 0 then table.insert(row, "|") end | ||||||
|  |         end | ||||||
|  |         print("| "..table.concat(row, " ")) | ||||||
|  |         if i % 3 == 0 then print(hl) end | ||||||
|  |     end | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | function getZoneByIndex(board, zoneIndex) | ||||||
|  |     local index = (zoneIndex - 1) % 9 + 1 | ||||||
|  |     local block = math.floor((zoneIndex - 1) / 9) + 1 | ||||||
|  |     local a = {} | ||||||
|  |     local p = {} | ||||||
|  |     if block == 1 then | ||||||
|  |         for i = 1, 9 do | ||||||
|  |             a[i] = board[index][i] | ||||||
|  |             p[i] = {index, i} | ||||||
|  |         end | ||||||
|  |     elseif block == 2 then | ||||||
|  |         for i = 1, 9 do | ||||||
|  |             a[i] = board[i][index] | ||||||
|  |             p[i] = {index, i} | ||||||
|  |         end | ||||||
|  |     elseif block == 3 then | ||||||
|  |         local dx = math.floor((index - 1) / 3) | ||||||
|  |         local dy = (index - 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 | ||||||
|  |     end | ||||||
|  |     return a, p | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | function getZonePosByIndex(zoneIndex) | ||||||
|  |     local index = (zoneIndex - 1) % 9 + 1 | ||||||
|  |     local block = math.floor((zoneIndex - 1) / 9) + 1 | ||||||
|  |     local p = {} | ||||||
|  |     if block == 1 then | ||||||
|  |         for i = 1, 9 do | ||||||
|  |             p[i] = {index, i} | ||||||
|  |         end | ||||||
|  |     elseif block == 2 then | ||||||
|  |         for i = 1, 9 do | ||||||
|  |             p[i] = {index, i} | ||||||
|  |         end | ||||||
|  |     elseif block == 3 then | ||||||
|  |         local dx = math.floor((index - 1) / 3) | ||||||
|  |         local dy = (index - 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 | ||||||
|  |                 p[n] = {x, y} | ||||||
|  |             end | ||||||
|  |         end | ||||||
|  |     end | ||||||
|  |     return p | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | function iterZonePos(zoneIndex) | ||||||
|  |     local p = getZonePosByIndex(zoneIndex) | ||||||
|  |     local i = 0 | ||||||
|  |     return function() | ||||||
|  |         if i < 9 then | ||||||
|  |             i = i + 1 | ||||||
|  |             return p[i][1], p[i][2] | ||||||
|  |         end | ||||||
|  |     end | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | function fillSingles(board, searchSpace) | ||||||
|  |     local count = 0 | ||||||
|  |     for i = 1, 9 do | ||||||
|  |         for j = 1, 9 do | ||||||
|  |             if #searchSpace[i][j] == 1 then | ||||||
|  |                 board[i][j] = searchSpace[i][j][1] | ||||||
|  |                 count = count + 1 | ||||||
|  |             end | ||||||
|  |         end | ||||||
|  |     end | ||||||
|  |     return count | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | function applyFillSinglesRepeatedly(board, s) | ||||||
|  |     local s = s or buildSearchSpace(board) | ||||||
|  |     local count = fillSingles(board, s) | ||||||
|  |     local total = count | ||||||
|  |     while count ~= 0 do | ||||||
|  |         s = buildSearchSpace(board) | ||||||
|  |         count = fillSingles(board, s) | ||||||
|  |         total = total + count | ||||||
|  |     end | ||||||
|  |     return total | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | function eliminatePairsInSearchSpaceAUX(board, searchSpace, pair, zoneIndex, cells) | ||||||
|  |     local _, pos = getZoneByIndex(board, zoneIndex) | ||||||
|  |     local count = 0 | ||||||
|  |     for i = 1, 9 do | ||||||
|  |         if i ~= cells[1] and i ~= cells[2] then | ||||||
|  |             local x = pos[i][1] | ||||||
|  |             local y = pos[i][2] | ||||||
|  |             local del = {} | ||||||
|  |             for index, v in ipairs(searchSpace[x][y]) do | ||||||
|  |                 if v == pair[1] or v == pair[2] then | ||||||
|  |                     count = count + 1 | ||||||
|  |                     table.insert(del, index) | ||||||
|  |                 end | ||||||
|  |             end | ||||||
|  |             for _, index in ipairs(del) do | ||||||
|  |                 table.remove(searchSpace[x][y], index) | ||||||
|  |             end | ||||||
|  |         end | ||||||
|  |     end | ||||||
|  |     return count | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | function eliminatePairsInSearchSpace(board, searchSpace) | ||||||
|  |     local p = findPairsIndSearchSpace(board, searchSpace) | ||||||
|  |     local count = 0 | ||||||
|  |     for _, m in ipairs(p) do | ||||||
|  |         count = count + eliminatePairsInSearchSpaceAUX(board, searchSpace, m.pair, m.zoneIndex, m.cells) | ||||||
|  |     end | ||||||
|  |     return count | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | function allPairs(board) | ||||||
|  |     local s = buildSearchSpace(board) | ||||||
|  |     applyFillSinglesRepeatedly(board, s) | ||||||
|  |     eliminatePairsInSearchSpace(board, s) | ||||||
|  |     local count = applyFillSinglesRepeatedly(board, s) | ||||||
|  |     while count ~= 0 do | ||||||
|  |         -- print("--------------------------------------------------") | ||||||
|  |         -- showBoard(board) | ||||||
|  |         -- showSearchSpace(s) | ||||||
|  |         -- print(count) | ||||||
|  |         -- io.read(1) | ||||||
|  |         s = buildSearchSpace(board) | ||||||
|  |         eliminatePairsInSearchSpace(board, s) | ||||||
|  |         count = applyFillSinglesRepeatedly(board, s) | ||||||
|  |     end | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | function findFirstEmptyCell(board) | ||||||
|  |     for i = 1, 9 do | ||||||
|  |         for j = 1, 9 do | ||||||
|  |             if board[i][j] == 0 then | ||||||
|  |                 return i, j | ||||||
|  |             end | ||||||
|  |         end | ||||||
|  |     end | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | function checkSearchSpace(board, searchSpace) | ||||||
|  |     local s = searchSpace or buildSearchSpace(board) | ||||||
|  |     for i = 1, 9 do | ||||||
|  |         for j = 1, 9 do | ||||||
|  |             if board[i][j] == 0 then | ||||||
|  |                 if #s[i][j] == 0 then return false end | ||||||
|  |             end | ||||||
|  |         end | ||||||
|  |     end | ||||||
|  |     return true | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | function backTrace2(board, s) | ||||||
|  |     local s = s or buildSearchSpace(board) | ||||||
|  |     local x, y = findFirstEmptyCell(board) | ||||||
|  |     for _, v in ipairs(s[x][y]) do | ||||||
|  |         local b = cloneBoard(board) | ||||||
|  |         b[x][y] = v | ||||||
|  |         allPairs(b) | ||||||
|  |         local ok, finished = checkBoard(b) | ||||||
|  |         if finished then return b end | ||||||
|  |         if ok and checkSearchSpace(b) then | ||||||
|  |             local r = backTrace(b) | ||||||
|  |             if r then return r end | ||||||
|  |         end | ||||||
|  |     end | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | function backTrace3(board, tried) | ||||||
|  |     -- dbg() | ||||||
|  |     local tried = tried or createEmptyBoard() | ||||||
|  |     for x = 1, 9 do | ||||||
|  |         for y = 1, 9 do | ||||||
|  |             if tried[x][y] == 0 and board[x][y] == 0 then | ||||||
|  |                 tried[x][y] = 1 | ||||||
|  |                 print(x, y) | ||||||
|  |                 local s = buildSearchSpace(board) | ||||||
|  |                 for _, v in ipairs(s[x][y]) do | ||||||
|  |                     local b = cloneBoard(board) | ||||||
|  |                     b[x][y] = v | ||||||
|  |                     allPairs(b) | ||||||
|  |                     local ok, finished = checkBoard(b) | ||||||
|  |                     if finished then return b end | ||||||
|  |                     if ok and checkSearchSpace(b) then | ||||||
|  |                         local r = backTrace(b, tried) | ||||||
|  |                         if r then return r end | ||||||
|  |                     end | ||||||
|  |                 end | ||||||
|  |             end | ||||||
|  |         end | ||||||
|  |     end | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | function backTrace4(board, cx, cy) | ||||||
|  |     local s = buildSearchSpace(board) | ||||||
|  |     for x = 1, 9 do | ||||||
|  |         for y = 1, 9 do | ||||||
|  |             if x ~= cx and y ~=cy then | ||||||
|  |                 for _, v in ipairs(s[x][y]) do | ||||||
|  |                     local b= cloneBoard(board) | ||||||
|  |                     b[x][y] = v | ||||||
|  |                     print(x, y, v) | ||||||
|  |                     -- allPairs(b) | ||||||
|  |                     applyFillSinglesRepeatedly(b) | ||||||
|  |                     local ok, finished = checkBoard(b) | ||||||
|  |                     if finished then return b end | ||||||
|  |                     if ok and checkSearchSpace(b) then | ||||||
|  |                         local r = backTrace(b, x, y) | ||||||
|  |                         if r then return r end | ||||||
|  |                     end | ||||||
|  |                 end | ||||||
|  |             end | ||||||
|  |         end | ||||||
|  |     end | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | function backTrace(board) | ||||||
|  |     local s = buildSearchSpace(board) | ||||||
|  |     for x = 1, 9 do | ||||||
|  |         for y = 1, 9 do | ||||||
|  |             for _, v in ipairs(s[x][y]) do | ||||||
|  |                 local b= cloneBoard(board) | ||||||
|  |                 b[x][y] = v | ||||||
|  |                 -- allPairs(b) | ||||||
|  |                 applyFillSinglesRepeatedly(b) | ||||||
|  |                 local ok, finished = checkBoard(b) | ||||||
|  |                 print(x, y, v, ok, finished) | ||||||
|  |                 showBoard(b) | ||||||
|  |                 io.read(1) | ||||||
|  |                 if finished then return b end | ||||||
|  |                 if ok and checkSearchSpace(b) then | ||||||
|  |                     local r = backTrace(b, x, y) | ||||||
|  |                     if r then return r end | ||||||
|  |                 end | ||||||
|  |             end | ||||||
|  |             return | ||||||
|  |         end | ||||||
|  |     end | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | function solve(board) | ||||||
|  |     -- allPairs(board) | ||||||
|  |     applyFillSinglesRepeatedly(board) | ||||||
|  |     local ok, finished = checkBoard(board) | ||||||
|  |     if not ok then print("something's wrong!"); return end | ||||||
|  |     if finished then showBoard(board); return end | ||||||
|  |     local r = backTrace(board) | ||||||
|  |     if r then | ||||||
|  |         showBoard(r) | ||||||
|  |     else | ||||||
|  |         print "Could not solve!" | ||||||
|  |     end | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | function sHelper(n) | ||||||
|  |     local fn = string.format("/home/reza/p/lua/22.sudoku/boards/%03d.txt", n) | ||||||
|  |     local board = loadBoard(fn)[1] | ||||||
|  |     solve(board) | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | -- b = loadBoard("b.txt")[1] | ||||||
|  | -- applyFillSinglesRepeatedly(b) | ||||||
|  | -- s = buildSearchSpace(b) | ||||||
|  | -- allPairs(b) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | return { | ||||||
|  |     loadBoard = loadBoard, | ||||||
|  |     calCellValidOptions = calCellValidOptions, | ||||||
|  |     cloneBoard = cloneBoard, | ||||||
|  |     checkBoard = checkBoard, | ||||||
|  |     createEmptyBoard = createEmptyBoard, | ||||||
|  | } | ||||||
|  | |||||||
| @ -1,84 +0,0 @@ | |||||||
| local function table2string(t) |  | ||||||
|     local myself = table2string |  | ||||||
|     local l = {} |  | ||||||
|     local n = 0 |  | ||||||
|     for k, v in pairs(t) do |  | ||||||
|         n = n + 1 |  | ||||||
|         if type(v) == "table" then |  | ||||||
|             l[n] = k .. ': ' .. myself(v) |  | ||||||
|         elseif type(v) == "string" then |  | ||||||
|             l[n] = k .. ': ' .. '"' .. v .. '"' |  | ||||||
|         else |  | ||||||
|             l[n] = k .. ': ' .. v |  | ||||||
|         end |  | ||||||
|     end |  | ||||||
|     return "{" .. table.concat(l, ", ") .. "}" |  | ||||||
| end |  | ||||||
| 
 |  | ||||||
| local function find(array, element) |  | ||||||
|     local index = 0 |  | ||||||
|     for i = 1, #array do |  | ||||||
|         if array[i] == element then |  | ||||||
|             index = i |  | ||||||
|             break |  | ||||||
|         end |  | ||||||
|     end |  | ||||||
|     return index |  | ||||||
| end |  | ||||||
| 
 |  | ||||||
| local function createEmptyBoard() |  | ||||||
|     local b = {} |  | ||||||
|     for i = 1, 9 do |  | ||||||
|         b[i] = {} |  | ||||||
|         for j = 1, 9 do |  | ||||||
|             b[i][j] = 0 |  | ||||||
|         end |  | ||||||
|     end |  | ||||||
|     return b |  | ||||||
| end |  | ||||||
| 
 |  | ||||||
| local function cloneBoard(b) |  | ||||||
|     local c = {} |  | ||||||
|     for i = 1, 9 do |  | ||||||
|         c[i] = {} |  | ||||||
|         for j = 1, 9 do |  | ||||||
|             c[i][j] = b[i][j] |  | ||||||
|         end |  | ||||||
|     end |  | ||||||
|     return c |  | ||||||
| end |  | ||||||
| 
 |  | ||||||
| local function loadBoard(fn) |  | ||||||
|     local boards = {} |  | ||||||
|     local r = 0 |  | ||||||
|     local board = {} |  | ||||||
|     for line in io.lines(fn) do |  | ||||||
|         if line:gsub("%s+", "") == "" then |  | ||||||
|             table.insert(boards, board) |  | ||||||
|             board = {} |  | ||||||
|             r = 0 |  | ||||||
|         else |  | ||||||
|             r = r + 1 |  | ||||||
|             local c = 0 |  | ||||||
|             board[r] = {} |  | ||||||
|             for item in line:gmatch("%w+") do |  | ||||||
|                 c = c + 1 |  | ||||||
|                 board[r][c] = tonumber(item) |  | ||||||
|             end |  | ||||||
|         end |  | ||||||
|     end |  | ||||||
|     table.insert(boards, board) |  | ||||||
|     return boards |  | ||||||
| end |  | ||||||
| 
 |  | ||||||
| local function showBoard(board) |  | ||||||
|     for row = 1, 9 do |  | ||||||
|         print(table.concat(board[row], " ")) |  | ||||||
|     end |  | ||||||
| end |  | ||||||
| 
 |  | ||||||
| return { |  | ||||||
|     createEmptyBoard = createEmptyBoard, |  | ||||||
|     cloneBoard = cloneBoard, |  | ||||||
|     loadBoard = loadBoard, |  | ||||||
| } |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user