Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- variables
- local args = {...}
- local picross = {}
- local size = 6
- local decodedRows = {}
- local decodedCols = {}
- local config = {}
- local configPath = shell.resolve('.picross-config')
- local running = true
- local drawGrid, clear, chooseDrawStyle
- -- logic functions
- local function loadConfig()
- local file = fs.open(configPath, 'r')
- if file then
- config = textutils.unserialize(file.readAll())
- return true, file.close()
- end
- return false
- end
- local function saveConfig()
- local file = fs.open(configPath, 'w')
- file.write(textutils.serialize(config))
- file.close()
- end
- local function genPicross()
- local x1, y1, x2, y2
- local image
- if args[1] then
- if tonumber(args[1]) then
- size = tonumber(args[1])
- else
- image = paintutils.loadImage(shell.resolve(args[1]))
- if image then
- local looping = true
- for y=1, #image do
- for x=1, #image[y] do
- if image[y][x] == 64 then
- if not (x1 and y1) then
- x1, y1 = x, y
- else
- x2, y2 = x, y
- looping = false
- break
- end
- end
- end
- if not looping then break end
- end
- end
- end
- end
- if x1 and y1 and x2 and y2 then
- x1, y1 = x1 + 1, y1 + 1
- x2, y2 = x2 - 1, y2 - 1
- size = math.max(x2 - x1 + 1, y2 - y1 + 1)
- end
- for y=1, size do
- picross[y] = {}
- for x=1, size do
- if image then
- picross[y][x] = {
- value = image[y + y1 - 1] and image[y + y1 - 1][x + x1 - 1] == 32768 and 1 or 0;
- marked = 1;
- }
- else
- picross[y][x] = {
- value = math.random() > 0.5 and 0 or 1;
- marked = 1;
- }
- end
- end
- end
- end
- local function decode(str)
- local decoded = {}
- for bunch in str:gmatch('1+') do
- table.insert(decoded, #bunch)
- end
- return decoded
- end
- local function decodePicross()
- for y=1, size do
- local rowstr = ''
- local decoded = ' '
- for i=1, #picross[y] do
- rowstr = rowstr .. picross[y][i].value
- end
- table.insert(decodedRows, decode(rowstr))
- end
- for x=1, size do
- local colstr = ''
- local decoded = ' '
- for i=1, size do
- colstr = colstr .. picross[i][x].value
- end
- table.insert(decodedCols, decode(colstr))
- end
- end
- local function checkCorrect()
- for y=1, size do
- for x=1, size do
- local cell = picross[y][x]
- if (cell.value == 0 and cell.marked == 2)
- or (cell.value == 1 and cell.marked ~= 2) then
- return false
- end
- end
- end
- return true
- end
- local function showSolution()
- for y=1, size do
- for x=1, size do
- local cell = picross[y][x]
- cell.marked = cell.value == 0 and 3 or 2
- end
- end
- end
- local function pause()
- repeat
- local ev = os.pullEvent()
- until ev == 'key' or ev == 'mouse_click'
- end
- local function getInput(ev, p1, p2, p3)
- if ev == 'mouse_click' or ev == 'mouse_drag' then
- local b, x, y = p1, p2, p3
- local cx, cy = config.drawStyle == 'ascii' and (x + 1)/2 or x, y
- if picross[cy] and picross[cy][cx] then
- local cell = picross[cy][cx]
- if b == 1 then
- cell.marked = cell.marked ~= 2 and 2 or 1
- elseif b == 2 then
- cell.marked = cell.marked ~= 3 and 3 or 1
- end
- if checkCorrect() then
- drawGrid(true)
- running = false
- end
- end
- end
- if ev == 'key' and p1 == keys.backspace then
- showSolution()
- drawGrid(true, true)
- running = false
- end
- end
- -- drawing functions
- function clear()
- term.setBackgroundColor(colors.black)
- term.setCursorPos(1,1)
- term.clear()
- end
- function chooseDrawStyle()
- local options = {
- {4,4,'Ascii', 'ascii'},
- {4,5,'Black and White', 'baw'},
- {4,6,'Color', 'color'}
- }
- local sel = 1
- local writeText = function(str, x, y, color)
- term.setTextColor(color or colors.white)
- term.setCursorPos(x, y)
- term.write(str)
- end
- local looping = true
- while looping do
- clear()
- writeText('Select Draw Style (Click twice)', 4, 2, colors.yellow)
- for i=1, #options do
- local opt = options[i]
- if sel == i then
- writeText('> '..opt[3], opt[1] - 2, opt[2], colors.lime)
- else
- writeText(opt[3], opt[1], opt[2], colors.white)
- end
- end
- local _, b, x, y = os.pullEvent('mouse_click')
- for i=1, #options do
- local opt = options[i]
- if y == opt[2] then
- if sel == i then
- config.drawStyle = opt[4]
- looping = false
- break
- else
- sel = i
- break
- end
- end
- end
- end
- clear()
- writeText('Type "picross --drawmode" to go', 4, 2, colors.yellow)
- writeText('back to this screen.', 4, 3, colors.yellow)
- writeText('Press any key to continue.', 4, 4, colors.yellow)
- pause()
- end
- function drawGrid(winning, solution)
- local t = term
- local offset = solution and (
- config.drawStyle == 'ascii' and size*2 + 7 or
- size + math.floor(size/2) + 5
- ) or 0
- if config.drawStyle == 'ascii' then
- local chars = {'.','#','X'}
- local color = {colors.white, winning and colors.lime or colors.yellow, colors.gray}
- for y=1, size do
- for x=1, size do
- local marked = picross[y][x].marked
- t.setCursorPos(x*2 - 1 + offset, y)
- t.setTextColor(color[marked])
- t.write(chars[marked])
- end
- end
- else
- -- useless table definitions but i'm too lazy to make it all shorter
- local color = config.drawStyle == 'baw' and {
- colors.black,
- winning and colors.white or colors.lightGray,
- colors.black
- }
- or config.drawStyle == 'color' and {
- colors.black,
- winning and colors.lime or colors.yellow,
- colors.black
- }
- for y=1, size do
- for x=1, size do
- local marked = picross[y][x].marked
- t.setCursorPos(x + offset, y)
- t.setBackgroundColor(color[marked])
- t.setTextColor(
- marked == 3 and colors.gray or
- colors.white
- )
- t.write(
- marked == 1 and '.' or
- marked == 3 and 'X' or
- ' '
- )
- end
- end
- end
- local t = term
- t.setTextColor(colors.lightBlue)
- t.setBackgroundColor(colors.black)
- for i=1, #decodedRows do
- local row = decodedRows[i]
- t.setCursorPos((config.drawStyle == 'ascii' and size*2 + 2 or size + 2) + offset, i)
- t.write(table.concat(row, ' '))
- end
- for i=1, #decodedCols do
- local col = decodedCols[i]
- for y=1, #col do
- t.setCursorPos((config.drawStyle == 'ascii' and i*2 - 1 or i) + offset, size + y + 1)
- t.write(tostring(col[y]):gsub('%..+$'))
- end
- end
- end
- -- main running function
- local function run()
- if args[1] == '--drawmode' or args[2] == '--drawmode' then
- chooseDrawStyle()
- end
- loadConfig()
- if not config.drawStyle then
- chooseDrawStyle()
- end
- genPicross()
- decodePicross()
- while running do
- clear()
- drawGrid()
- getInput(os.pullEvent())
- end
- saveConfig()
- pause()
- clear()
- end
- run()
Advertisement
Add Comment
Please, Sign In to add comment