123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- love.window.setMode(150, 40) -- Input box
- love.keyboard.setKeyRepeat(true)
- local bit = require 'bit'
- -- Validation function for numeric input
- local function numeric(t)
- return type(t) == "string" and t >= "0" and t <= "9"
- end
- -- Validation function for UTF-8 text input
- local function text(t)
- local L, U, b2, b3, b4 = #t, t:byte(1, 4)
- if L <= 1 then
- return U and U < 128
- end
- -- Check correctness of bit encoding and length
- if b2 < 128 or b2 > 191
- or L ~= 2 and (b3 < 128 or b3 > 191)
- or L == 2 and (U < 0xC2 or U > 0xDF)
- or L == 3 and (U < 0xE0 or U > 0xEF)
- or L == 4 and (U < 0xF0 or U > 0xF4 or b4 < 128 or b4 > 191)
- then
- return false
- end
- -- Basic encoding/length validation test passed - decode the bits
- U = bit.lshift(U - 192, 6) + (b2 - 128)
- if L >= 3 then
- U = bit.lshift(U - 0x800, 6) + (b3 - 128)
- if L >= 4 then
- U = bit.lshift(U - 0x10000, 6) + (b4 - 128)
- end
- end
- if L == 3 and U < 0x800 or L == 4 and U < 0x10000 -- overlong
- or U > 0x10FFFD -- out of range
- or U >= 0xD800 and U <= 0xDFFF -- surrogate
- or U >= 0xFDD0 and U <= 0xFDEF -- invalid range
- then
- return false
- end
- local low = bit.band(U, 0xFFFF)
- return low ~= 0xFFFE and low ~= 0xFFFF
- end
- -- Input function that allows entering any text:
- local function simpleInput(x, y, maxlen, validFn)
- local r_save, g_save, b_save, a_save = love.graphics.getColor()
- local font = love.graphics.getFont()
- local H = font:getHeight()
- local W = font:getWidth("M") -- hopefully the thickest letter in the font
- local str = ''
- repeat
- poll()
- love.graphics.setColor(love.graphics.getBackgroundColor())
- love.graphics.rectangle("fill", x, y, (maxlen + 1) * W, H)
- love.graphics.setColor(r_save, g_save, b_save, a_save)
- love.graphics.print(str .. "_", x, y)
- local ret, k = peek.keypressed()
- local t = ""
- if peek.textinput() then
- ret, t = peek.textinput()
- end
- if k == "escape" then
- quit()
- end
- if k == "backspace" and str ~= "" then
- str = str:sub(1, -2)
- elseif validFn(t) then
- str = str .. t
- end
- if #str > maxlen then
- str = str:sub(1, maxlen)
- end
- until k == 'kpenter' or k == 'return'
- love.graphics.setColor(r_save, g_save, b_save, a_save)
- return str
- end
- do
- local text = "Enter N (4-16): "
- love.graphics.print(text, 20, 10)
- local w = love.graphics.getFont():getWidth(text)
- repeat
- N = tonumber(simpleInput(w + 20, 10, 2, numeric))
- until N and N >= 4 and N <= 16
- end
- local size = 40
- love.window.setMode((N + 1) * size, (N + 1.5) * size, {vsync = false})
- -- Work around problem where a new keypress event is sent to the new window
- -- if it was pressed, by ignoring the keypressed events for 1 frame
- wait.update() -- wait for this update
- wait.update() -- wait for the *next* uppate
- local img = love.graphics.newImage('queen-black-40x40.png')
- local function clear(x, y)
- if (x + y) % 2 == 1 then
- love.graphics.setColor(0, 0, 0)
- else
- love.graphics.setColor(255, 255, 255)
- end
- love.graphics.rectangle("fill", x*size, y*size, size, size)
- love.graphics.setColor(255, 255, 255)
- end
- -- Set origin to top left of board
- love.graphics.translate(size/2, size)
- -- Draw border
- love.graphics.rectangle("fill", -4, -4, N*size+8, N*size+8)
- for y = 0, N-1 do
- for x = 0, N-1 do
- clear(x, y)
- end
- end
- local board = {}
- local nSolutions = 0
- local function printSolution()
- for i = 1, N do
- print(("*"):rep(board[i]) .. "Q" .. ("*"):rep(N - 1 - board[i]))
- end
- print(("-"):rep(N))
- nSolutions = nSolutions + 1
- -- Erase background before printing
- for i = 1, 3 do
- love.graphics.setColor(love.graphics.getBackgroundColor())
- love.graphics.rectangle("fill", 10, -30, N*size, 14)
- sleep(0.2)
- love.graphics.setColor(255, 255, 255)
- love.graphics.print("Number of solutions: " .. nSolutions, 10, -30)
- sleep(0.2)
- end
- pause(1.5)
- end
- love.graphics.print("Number of solutions: 0", 10, -30)
- local function tryQueen(row)
- for x = 0, N - 1 do
- love.graphics.draw(img, x*size, row*size)
- pause(0)
- local failed = false
- for i = 1, row do
- if board[i] == x or board[i] - x == row - (i - 1) or x - board[i] == row - (i - 1) then
- failed = true
- break
- end
- end
- if not failed then
- board[row + 1] = x
- if row == N - 1 then
- printSolution()
- else
- tryQueen(row + 1)
- end
- end
- clear(x, row)
- end
- end
- tryQueen(0)
- love.graphics.setColor(255, 0, 0)
- love.graphics.print("No more solutions\nPress a key", 10, 40)
- print("No more solutions")
- wait.keypressed()
- quit()
|