Code formatting
This commit is contained in:
parent
bc408aeeb3
commit
cb74bdf740
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
|
@ -1,4 +1,4 @@
|
||||||
{
|
{
|
||||||
"editor.insertSpaces": false,
|
"editor.insertSpaces": true,
|
||||||
"editor.detectIndentation": false
|
"editor.detectIndentation": false,
|
||||||
}
|
}
|
3
0hh1.p8
3
0hh1.p8
|
@ -2,10 +2,9 @@ pico-8 cartridge // http://www.pico-8.com
|
||||||
version 38
|
version 38
|
||||||
__lua__
|
__lua__
|
||||||
|
|
||||||
|
|
||||||
-- Font M3X6 by daniel linssen
|
-- Font M3X6 by daniel linssen
|
||||||
poke(0x5600, 4, 4, 7)
|
poke(0x5600, 4, 4, 7)
|
||||||
poke4(0x5700,unpack(split"0x0000.0000,0x0000.0000,0x0202.0202,0x0000.0200,0x0000.0505,0x0000.0000,0x0505.0705,0x0000.0507,0x0407.0106,0x0000.0203,0x0204.0100,0x0000.0401,0x0102.0502,0x0000.0305,0x0000.0102,0x0000.0000,0x0101.0102,0x0000.0201,0x0202.0201,0x0000.0102,0x0205.0000,0x0000.0005,0x0702.0000,0x0000.0002,0x0000.0000,0x0000.0102,0x0700.0000,0x0000.0000,0x0000.0000,0x0000.0200,0x0202.0404,0x0000.0101,0x0505.0506,0x0000.0305,0x0202.0302,0x0000.0702,0x0204.0403,0x0000.0701,0x0403.0403,0x0000.0304,0x0406.0505,0x0000.0404,0x0403.0107,0x0000.0304,0x0503.0106,0x0000.0605,0x0204.0407,0x0000.0202,0x0502.0506,0x0000.0305,0x0605.0503,0x0000.0304,0x0002.0000,0x0000.0002,0x0002.0000,0x0000.0102,0x0102.0400,0x0000.0402,0x0007.0000,0x0000.0007,0x0402.0100,0x0000.0102,0x0204.0403,0x0000.0200,0x0505.0506,0x0000.0601,0x0604.0300,0x0000.0705,0x0505.0301,0x0000.0705,0x0101.0600,0x0000.0701,0x0505.0604,0x0000.0705,0x0705.0600,0x0000.0601,0x0702.0204,0x0000.0202,0x0705.0600,0x0000.0304,0x0505.0301,0x0000.0505,0x0202.0002,0x0000.0202,0x0202.0002,0x0000.0102,0x0305.0101,0x0000.0505,0x0202.0202,0x0000.0402,0x0707.0300,0x0000.0507,0x0505.0300,0x0000.0505,0x0505.0600,0x0000.0305,0x0305.0700,0x0000.0101,0x0705.0600,0x0000.0404,0x0101.0600,0x0000.0101,0x0701.0600,0x0000.0304,0x0207.0202,0x0000.0202,0x0505.0500,0x0000.0705,0x0505.0500,0x0000.0205,0x0705.0500,0x0000.0507,0x0205.0500,0x0000.0505,0x0605.0500,0x0000.0304,0x0204.0700,0x0000.0701,0x0101.0103,0x0000.0301,0x0202.0101,0x0000.0404,0x0202.0203,0x0000.0302,0x0000.0502,0x0000.0000,0x0000.0000,0x0000.0403,0x0000.0201,0x0000.0000,0x0507.0506,0x0000.0505,0x0507.0503,0x0000.0705,0x0101.0106,0x0000.0701,0x0505.0503,0x0000.0305,0x0103.0107,0x0000.0701,0x0301.0106,0x0000.0101,0x0501.0106,0x0000.0705,0x0507.0505,0x0000.0505,0x0202.0207,0x0000.0702,0x0404.0407,0x0000.0304,0x0503.0505,0x0000.0505,0x0101.0101,0x0000.0701,0x0507.0705,0x0000.0505,0x0505.0503,0x0000.0505,0x0505.0506,0x0000.0305,0x0103.0507,0x0000.0101,0x0505.0506,0x0000.0403,0x0503.0507,0x0000.0505,0x0407.0106,0x0000.0304,0x0202.0207,0x0000.0202,0x0505.0505,0x0000.0705,0x0505.0505,0x0000.0205,0x0705.0505,0x0000.0507,0x0202.0505,0x0000.0505,0x0205.0505,0x0000.0202,0x0202.0407,0x0000.0701,0x0302.0204,0x0000.0402,0x0202.0202,0x0000.0202,0x0602.0201,0x0000.0102,0x0704.0000,0x0000.0001,0x0205.0200,0x0000.0000"))
|
poke4(0x5700, unpack(split "0x0000.0000,0x0000.0000,0x0202.0202,0x0000.0200,0x0000.0505,0x0000.0000,0x0505.0705,0x0000.0507,0x0407.0106,0x0000.0203,0x0204.0100,0x0000.0401,0x0102.0502,0x0000.0305,0x0000.0102,0x0000.0000,0x0101.0102,0x0000.0201,0x0202.0201,0x0000.0102,0x0205.0000,0x0000.0005,0x0702.0000,0x0000.0002,0x0000.0000,0x0000.0102,0x0700.0000,0x0000.0000,0x0000.0000,0x0000.0200,0x0202.0404,0x0000.0101,0x0505.0506,0x0000.0305,0x0202.0302,0x0000.0702,0x0204.0403,0x0000.0701,0x0403.0403,0x0000.0304,0x0406.0505,0x0000.0404,0x0403.0107,0x0000.0304,0x0503.0106,0x0000.0605,0x0204.0407,0x0000.0202,0x0502.0506,0x0000.0305,0x0605.0503,0x0000.0304,0x0002.0000,0x0000.0002,0x0002.0000,0x0000.0102,0x0102.0400,0x0000.0402,0x0007.0000,0x0000.0007,0x0402.0100,0x0000.0102,0x0204.0403,0x0000.0200,0x0505.0506,0x0000.0601,0x0604.0300,0x0000.0705,0x0505.0301,0x0000.0705,0x0101.0600,0x0000.0701,0x0505.0604,0x0000.0705,0x0705.0600,0x0000.0601,0x0702.0204,0x0000.0202,0x0705.0600,0x0000.0304,0x0505.0301,0x0000.0505,0x0202.0002,0x0000.0202,0x0202.0002,0x0000.0102,0x0305.0101,0x0000.0505,0x0202.0202,0x0000.0402,0x0707.0300,0x0000.0507,0x0505.0300,0x0000.0505,0x0505.0600,0x0000.0305,0x0305.0700,0x0000.0101,0x0705.0600,0x0000.0404,0x0101.0600,0x0000.0101,0x0701.0600,0x0000.0304,0x0207.0202,0x0000.0202,0x0505.0500,0x0000.0705,0x0505.0500,0x0000.0205,0x0705.0500,0x0000.0507,0x0205.0500,0x0000.0505,0x0605.0500,0x0000.0304,0x0204.0700,0x0000.0701,0x0101.0103,0x0000.0301,0x0202.0101,0x0000.0404,0x0202.0203,0x0000.0302,0x0000.0502,0x0000.0000,0x0000.0000,0x0000.0403,0x0000.0201,0x0000.0000,0x0507.0506,0x0000.0505,0x0507.0503,0x0000.0705,0x0101.0106,0x0000.0701,0x0505.0503,0x0000.0305,0x0103.0107,0x0000.0701,0x0301.0106,0x0000.0101,0x0501.0106,0x0000.0705,0x0507.0505,0x0000.0505,0x0202.0207,0x0000.0702,0x0404.0407,0x0000.0304,0x0503.0505,0x0000.0505,0x0101.0101,0x0000.0701,0x0507.0705,0x0000.0505,0x0505.0503,0x0000.0505,0x0505.0506,0x0000.0305,0x0103.0507,0x0000.0101,0x0505.0506,0x0000.0403,0x0503.0507,0x0000.0505,0x0407.0106,0x0000.0304,0x0202.0207,0x0000.0202,0x0505.0505,0x0000.0705,0x0505.0505,0x0000.0205,0x0705.0505,0x0000.0507,0x0202.0505,0x0000.0505,0x0205.0505,0x0000.0202,0x0202.0407,0x0000.0701,0x0302.0204,0x0000.0402,0x0202.0202,0x0000.0202,0x0602.0201,0x0000.0102,0x0704.0000,0x0000.0001,0x0205.0200,0x0000.0000"))
|
||||||
|
|
||||||
#include globals.lua
|
#include globals.lua
|
||||||
--
|
--
|
||||||
|
|
57
bg.lua
57
bg.lua
|
@ -1,35 +1,36 @@
|
||||||
function draw_animated_bg(startx)
|
function draw_animated_bg(startx)
|
||||||
if (amplitude <= 0) return
|
if (amplitude <= 0) return
|
||||||
startx = startx or 0
|
startx = startx or 0
|
||||||
fillp(0b0101101001011010)
|
fillp(0b0101101001011010)
|
||||||
|
|
||||||
local color = 1
|
local color = 1
|
||||||
-- vertical lines
|
-- vertical lines
|
||||||
local t = t()+10
|
local t = t() + 10
|
||||||
for i=startx-1,127,9 do
|
for i = startx - 1, 127, 9 do
|
||||||
local a=sin(i*t/512)*amplitude+64
|
local a = sin(i * t / 512) * amplitude + 64
|
||||||
local b=cos(i*t/256)*amplitude+64
|
local b = cos(i * t / 256) * amplitude + 64
|
||||||
line(
|
line(
|
||||||
i,
|
i,
|
||||||
a,
|
a,
|
||||||
i,
|
i,
|
||||||
b ,
|
b,
|
||||||
color)
|
color
|
||||||
end
|
)
|
||||||
|
end
|
||||||
|
|
||||||
-- horizontal lines
|
-- horizontal lines
|
||||||
for i=startx-1,127,9 do
|
for i = startx - 1, 127, 9 do
|
||||||
local a=sin(i*t/512)*amplitude+64
|
local a = sin(i * t / 512) * amplitude + 64
|
||||||
local b=cos(i*t/256)*amplitude+64
|
local b = cos(i * t / 256) * amplitude + 64
|
||||||
line(
|
line(
|
||||||
a,
|
a,
|
||||||
i,
|
i,
|
||||||
b ,
|
b,
|
||||||
i,
|
i,
|
||||||
color)
|
color
|
||||||
end
|
)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function draw_bg_menu()
|
function draw_bg_menu()
|
||||||
|
|
||||||
end
|
end
|
794
board.lua
794
board.lua
|
@ -1,447 +1,441 @@
|
||||||
local Board = {}
|
local Board = {}
|
||||||
function Board.new()
|
function Board.new()
|
||||||
local debug = false
|
local debug = false
|
||||||
|
|
||||||
local width = board_size -- tiles
|
local width = board_size
|
||||||
local tile_width = 8 -- pixels
|
-- tiles
|
||||||
local padding = 1
|
local tile_width = 8
|
||||||
local tiles = {}
|
-- pixels
|
||||||
local locked = {} -- list of indexes
|
local padding = 1
|
||||||
|
local tiles = {}
|
||||||
|
local locked = {}
|
||||||
|
-- list of indexes
|
||||||
|
|
||||||
local reset = function()
|
local reset = function()
|
||||||
tiles = {}
|
tiles = {}
|
||||||
for i = 1, width * width do
|
for i = 1, width * width do
|
||||||
tiles[i] = 0
|
tiles[i] = 0
|
||||||
end
|
end
|
||||||
locked = {}
|
locked = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
reset()
|
reset()
|
||||||
|
|
||||||
return {
|
return {
|
||||||
reset = reset,
|
reset = reset,
|
||||||
|
|
||||||
get_tile = function(self, idx)
|
get_tile = function(self, idx)
|
||||||
return tiles[idx]
|
return tiles[idx]
|
||||||
end,
|
end,
|
||||||
|
|
||||||
-- returns a COPY of the tiles array
|
-- returns a COPY of the tiles array
|
||||||
get_tiles_copy = function(self)
|
get_tiles_copy = function(self)
|
||||||
return copy(tiles)
|
return copy(tiles)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
-- overwrites the whole tiles array
|
-- overwrites the whole tiles array
|
||||||
set_tiles = function(self, newtiles)
|
set_tiles = function(self, newtiles)
|
||||||
assert(#newtiles == #tiles, "New tiles array must have a length of " .. #tiles)
|
assert(#newtiles == #tiles, "New tiles array must have a length of " .. #tiles)
|
||||||
tiles = copy(newtiles)
|
tiles = copy(newtiles)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
idx_xy = function(self, idx)
|
idx_xy = function(self, idx)
|
||||||
return idx_xy(idx, width)
|
return idx_xy(idx, width)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
xy_idx = function(self, x, y)
|
xy_idx = function(self, x, y)
|
||||||
return xy_idx(x, y, width)
|
return xy_idx(x, y, width)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
draw_coords = function(self, x, y)
|
draw_coords = function(self, x, y)
|
||||||
local margin = (128 - (tile_width + padding) * width) / 2- padding
|
local margin = (128 - (tile_width + padding) * width) / 2 - padding
|
||||||
if not y then x, y = self:idx_xy(x) end
|
if not y then x, y = self:idx_xy(x) end
|
||||||
return margin + (x-1)*tile_width + (x-1)*padding,
|
return margin + (x - 1) * tile_width + (x - 1) * padding, margin + (y - 1) * tile_width + (y - 1) * padding
|
||||||
margin + (y-1)*tile_width + (y-1)*padding
|
end,
|
||||||
end,
|
|
||||||
|
|
||||||
get_size = function(self)
|
get_size = function(self)
|
||||||
return width
|
return width
|
||||||
end,
|
end,
|
||||||
|
|
||||||
get_tile_width = function(self)
|
get_tile_width = function(self)
|
||||||
return tile_width + padding
|
return tile_width + padding
|
||||||
end,
|
end,
|
||||||
|
|
||||||
fill = function(self, idx, color, invert)
|
fill = function(self, idx, color, invert)
|
||||||
if idx > width*width then return end
|
if idx > width * width then return end
|
||||||
if invert then
|
if invert then
|
||||||
color = color == YELLOW and BLUE or YELLOW
|
color = color == YELLOW and BLUE or YELLOW
|
||||||
end
|
end
|
||||||
tiles[idx] = color
|
tiles[idx] = color
|
||||||
end,
|
end,
|
||||||
|
|
||||||
try_flip_tile = function(self, id)
|
try_flip_tile = function(self, id)
|
||||||
local to_color = nil
|
local to_color = nil
|
||||||
if locked[id] then return end
|
if locked[id] then return end
|
||||||
local from_color = tiles[id]
|
local from_color = tiles[id]
|
||||||
if tiles[id] == 0 then
|
if tiles[id] == 0 then
|
||||||
to_color = YELLOW
|
to_color = YELLOW
|
||||||
elseif tiles[id] == YELLOW then
|
elseif tiles[id] == YELLOW then
|
||||||
to_color = BLUE
|
to_color = BLUE
|
||||||
else tiles[id] = 0
|
else
|
||||||
-- empty tile
|
tiles[id] = 0
|
||||||
end
|
-- empty tile
|
||||||
if to_color then
|
end
|
||||||
tiles[id] = to_color
|
if to_color then
|
||||||
end
|
tiles[id] = to_color
|
||||||
local x,y = self:draw_coords(id)
|
end
|
||||||
spawn_tile_transition(x, y, tile_width-1, tile_width-1, from_color, to_color)
|
local x, y = self:draw_coords(id)
|
||||||
end,
|
spawn_tile_transition(x, y, tile_width - 1, tile_width - 1, from_color, to_color)
|
||||||
|
end,
|
||||||
|
|
||||||
get_rows = function(self)
|
get_rows = function(self)
|
||||||
local ret = {}
|
local ret = {}
|
||||||
for i = 1, width do
|
for i = 1, width do
|
||||||
add(ret, slice(tiles, ((i - 1) * width) + 1, i * width))
|
add(ret, slice(tiles, (i - 1) * width + 1, i * width))
|
||||||
end
|
end
|
||||||
return ret
|
return ret
|
||||||
end,
|
end,
|
||||||
|
|
||||||
get_cols = function(self)
|
get_cols = function(self)
|
||||||
local ret = {}
|
local ret = {}
|
||||||
local rows = self.get_rows(self)
|
local rows = self.get_rows(self)
|
||||||
for i = 1, width do
|
for i = 1, width do
|
||||||
add(ret, map(rows, function(v) return v[i] end))
|
add(ret, map(rows, function(v) return v[i] end))
|
||||||
end
|
end
|
||||||
return ret
|
return ret
|
||||||
end,
|
end,
|
||||||
|
|
||||||
is_complete = function(self)
|
--- Returns true if all tiles are filled
|
||||||
return count(tiles, 0) == 0
|
is_complete = function(self)
|
||||||
end,
|
return count(tiles, 0) == 0
|
||||||
|
end,
|
||||||
|
|
||||||
is_valid = function(self)
|
--- Returns true if the board is valid (respects the rules)
|
||||||
return #self:get_issues() == 0
|
is_valid = function(self)
|
||||||
end,
|
return #self:get_issues() == 0
|
||||||
|
end,
|
||||||
|
|
||||||
-- returns a list of issues of the board's current state
|
-- returns a list of issues of the board's current state
|
||||||
get_issues = function(self, details)
|
get_issues = function(self, details)
|
||||||
local rows = self:get_rows()
|
local rows = self:get_rows()
|
||||||
local issues = {}
|
local issues = {}
|
||||||
for y,row in ipairs(rows) do
|
for y, row in ipairs(rows) do
|
||||||
local filled = count(row, 0) == 0
|
local filled = count(row, 0) == 0
|
||||||
-- check count
|
-- check count
|
||||||
if filled and count(row, BLUE) ~= count(row, YELLOW) then
|
if filled and count(row, BLUE) ~= count(row, YELLOW) then
|
||||||
add(issues, {"row", "count", row, y})
|
add(issues, { "row", "count", row, y })
|
||||||
if (debug) printh("uneven count on row "..y)
|
if (debug) printh("uneven count on row " .. y) if (not details) return issues
|
||||||
if (not details) return issues
|
end
|
||||||
end
|
-- check identical lines
|
||||||
-- check identical lines
|
for k, other in ipairs(rows) do
|
||||||
for k,other in ipairs(rows) do
|
if filled and equal(other, row) and other ~= row then
|
||||||
if filled and equal(other, row) and other ~= row then
|
add(issues, { "row", "identical", row, y, k })
|
||||||
add(issues, {"row", "identical", row, y, k})
|
if (debug) printh("equal rows " .. k) if (not details) return issues
|
||||||
if (debug) printh("equal rows "..k)
|
end
|
||||||
if (not details) return issues
|
end
|
||||||
end
|
-- check triples
|
||||||
end
|
if self:count_consecutives(row) > 2 then
|
||||||
-- check triples
|
add(issues, { "row", "triples", row, y })
|
||||||
if self:count_consecutives(row) > 2 then
|
if (debug) printh("triples") if (not details) return issues
|
||||||
add(issues, {"row", "triples", row, y})
|
end
|
||||||
if (debug) printh("triples")
|
end
|
||||||
if (not details) return issues
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local cols = self:get_cols()
|
local cols = self:get_cols()
|
||||||
for x,col in ipairs(cols) do
|
for x, col in ipairs(cols) do
|
||||||
local filled = count(col, 0) == 0
|
local filled = count(col, 0) == 0
|
||||||
|
|
||||||
-- check count
|
-- check count
|
||||||
if filled and count(col, BLUE) ~= count(col, YELLOW) then
|
if filled and count(col, BLUE) ~= count(col, YELLOW) then
|
||||||
add(issues, {"col", "count", col, x})
|
add(issues, { "col", "count", col, x })
|
||||||
if (debug) printh("uneven count")
|
if (debug) printh("uneven count") if (not details) return issues
|
||||||
if (not details) return issues
|
end
|
||||||
end
|
-- check identical lines
|
||||||
-- check identical lines
|
for k, other in ipairs(cols) do
|
||||||
for k,other in ipairs(cols) do
|
if filled and equal(other, col) and other ~= col then
|
||||||
if filled and equal(other, col) and other ~= col then
|
add(issues, { "col", "identical", col, x, k })
|
||||||
add(issues, {"col", "identical", col, x, k})
|
if (debug) printh("equal cols") if (not details) return issues
|
||||||
if (debug) printh("equal cols")
|
end
|
||||||
if (not details) return issues
|
end
|
||||||
end
|
-- check triples
|
||||||
end
|
if self:count_consecutives(col) > 2 then
|
||||||
-- check triples
|
add(issues, { "col", "triples", col, x })
|
||||||
if self:count_consecutives(col) > 2 then
|
if (debug) printh("triples") if (not details) return issues
|
||||||
add(issues, {"col", "triples", col, x})
|
end
|
||||||
if (debug) printh("triples")
|
end
|
||||||
if (not details) return issues
|
return issues
|
||||||
end
|
end,
|
||||||
end
|
|
||||||
return issues
|
|
||||||
end,
|
|
||||||
|
|
||||||
count_consecutives = function(self, line)
|
count_consecutives = function(self, line)
|
||||||
local top = 0
|
local top = 0
|
||||||
local current = 0
|
local current = 0
|
||||||
local last = 0
|
local last = 0
|
||||||
for v in all(line) do
|
for v in all(line) do
|
||||||
if v ~= last then
|
if v ~= last then
|
||||||
top = max(current, top)
|
top = max(current, top)
|
||||||
current = 1
|
current = 1
|
||||||
last = v
|
last = v
|
||||||
elseif v~= 0 then
|
elseif v ~= 0 then
|
||||||
current += 1
|
current += 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return max(current, top)
|
return max(current, top)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Returns the index of a random zero tile
|
-- Returns the index of a random zero tile
|
||||||
--
|
--
|
||||||
get_random_zero = function(self)
|
get_random_zero = function(self)
|
||||||
assert(count(tiles, 0) > 0, "No zero left")
|
assert(count(tiles, 0) > 0, "No zero left")
|
||||||
local zeroes = filter(tiles, function(v) return v == 0 end, true)
|
local zeroes = filter(tiles, function(v) return v == 0 end, true)
|
||||||
local z = {}
|
local z = {}
|
||||||
for k,v in pairs(zeroes) do
|
for k, v in pairs(zeroes) do
|
||||||
add(z, k)
|
add(z, k)
|
||||||
end
|
end
|
||||||
return rnd(z)
|
return rnd(z)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Returns the index of a random non-zero tile
|
-- Returns the index of a random non-zero tile
|
||||||
--
|
--
|
||||||
get_random_non_zero = function(self)
|
get_random_non_zero = function(self)
|
||||||
assert(count(tiles, 0) < #tiles, "All zeroes")
|
assert(count(tiles, 0) < #tiles, "All zeroes")
|
||||||
local numbers = filter(tiles, function(v) return v ~= 0 end, true)
|
local numbers = filter(tiles, function(v) return v ~= 0 end, true)
|
||||||
local z = {}
|
local z = {}
|
||||||
for k,v in pairs(numbers) do
|
for k, v in pairs(numbers) do
|
||||||
add(z, k)
|
add(z, k)
|
||||||
end
|
end
|
||||||
return rnd(z)
|
return rnd(z)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
tostring = function(self)
|
tostring = function(self)
|
||||||
local str = ''
|
local str = ''
|
||||||
for v in all(tiles) do
|
for v in all(tiles) do
|
||||||
str ..= ", " .. v
|
str ..= ", " .. v
|
||||||
end
|
end
|
||||||
return str
|
return str
|
||||||
end,
|
end,
|
||||||
|
|
||||||
-- Solves 1 step of the board
|
-- Solves 1 step of the board
|
||||||
-- Returns "valid" if it solved it without guessing
|
-- Returns "valid" if it solved it without guessing
|
||||||
-- Returns "invalid" if the board cannot be solved
|
-- Returns "invalid" if the board cannot be solved
|
||||||
solve_step = function(self, random)
|
solve_step = function(self, random)
|
||||||
local zeroes = count(tiles, 0)
|
local zeroes = count(tiles, 0)
|
||||||
self:surround_doubles()
|
self:surround_doubles()
|
||||||
self:split_triples()
|
self:split_triples()
|
||||||
self:fill_lines()
|
self:fill_lines()
|
||||||
self:no_identical_lines()
|
self:no_identical_lines()
|
||||||
local changed = zeroes ~= count(tiles, 0)
|
local changed = zeroes ~= count(tiles, 0)
|
||||||
|
|
||||||
if not changed and random and not self:is_complete() then
|
if not changed and random and not self:is_complete() then
|
||||||
-- Set a random color
|
-- Set a random color
|
||||||
local z = self:get_random_zero()
|
local z = self:get_random_zero()
|
||||||
self:fill(z, rnd({BLUE, YELLOW}))
|
self:fill(z, rnd({ BLUE, YELLOW }))
|
||||||
if (debug) printh("!!!!!!!!!!!!!!!!! RANDOM FILL AT " .. z)
|
if (debug) printh("!!!!!!!!!!!!!!!!! RANDOM FILL AT " .. z) return "invalid"
|
||||||
return "invalid"
|
end
|
||||||
end
|
return (changed or self:is_complete()) and "valid" or "invalid"
|
||||||
return (changed or self:is_complete()) and "valid" or "invalid"
|
end,
|
||||||
end,
|
|
||||||
|
|
||||||
surround_doubles = function(self)
|
surround_doubles = function(self)
|
||||||
for idx,v in ipairs(tiles) do
|
for idx, v in ipairs(tiles) do
|
||||||
local x,y = self:idx_xy(idx)
|
local x, y = self:idx_xy(idx)
|
||||||
if v == 0 then
|
if v == 0 then
|
||||||
local neighbors = {}
|
local neighbors = {}
|
||||||
-- 2 tiles on the left
|
-- 2 tiles on the left
|
||||||
if x >= 3 then
|
if x >= 3 then
|
||||||
add(neighbors, {idx, idx-1, idx-2})
|
add(neighbors, { idx, idx - 1, idx - 2 })
|
||||||
end
|
end
|
||||||
-- 2 tiles on the right
|
-- 2 tiles on the right
|
||||||
if x <= width-2 then
|
if x <= width - 2 then
|
||||||
add(neighbors, {idx, idx+1, idx+2})
|
add(neighbors, { idx, idx + 1, idx + 2 })
|
||||||
end
|
end
|
||||||
-- 2 tiles on top
|
-- 2 tiles on top
|
||||||
if y >= 3 then
|
if y >= 3 then
|
||||||
add(neighbors, {idx, idx-width, idx - width*2})
|
add(neighbors, { idx, idx - width, idx - width * 2 })
|
||||||
end
|
end
|
||||||
-- 2 tiles under
|
-- 2 tiles under
|
||||||
if y <= width-2 then
|
if y <= width - 2 then
|
||||||
add(neighbors, {idx, idx+width, idx + width*2})
|
add(neighbors, { idx, idx + width, idx + width * 2 })
|
||||||
end
|
end
|
||||||
|
|
||||||
-- only keep pairs that are identical (and not 0)
|
-- only keep pairs that are identical (and not 0)
|
||||||
neighbors = filter(neighbors, function (o) return tiles[o[2]] == tiles[o[3]] and tiles[o[2]] ~= 0 end)
|
neighbors = filter(neighbors, function(o) return tiles[o[2]] == tiles[o[3]] and tiles[o[2]] ~= 0 end)
|
||||||
|
|
||||||
-- do the surrounding
|
-- do the surrounding
|
||||||
for item in all(neighbors) do
|
for item in all(neighbors) do
|
||||||
if item[1] then
|
if item[1] then
|
||||||
if (debug) printh("Surrounding at " .. item[1])
|
if (debug) printh("Surrounding at " .. item[1]) self:fill(item[1], tiles[item[2]], true)
|
||||||
self:fill(item[1], tiles[item[2]], true)
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end,
|
||||||
end,
|
|
||||||
|
|
||||||
split_triples = function(self)
|
split_triples = function(self)
|
||||||
for idx, col in ipairs(tiles) do
|
for idx, col in ipairs(tiles) do
|
||||||
local x,y = self:idx_xy(idx)
|
local x, y = self:idx_xy(idx)
|
||||||
if col == 0 then
|
if col == 0 then
|
||||||
|
if x > 1 and x < width then
|
||||||
|
-- check horizontal
|
||||||
|
local prev = tiles[idx - 1]
|
||||||
|
local next = tiles[idx + 1]
|
||||||
|
if prev ~= 0 and prev == next then
|
||||||
|
if (debug) printh("Splitting at " .. idx) self:fill(idx, prev, true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if x > 1 and x < width then
|
if y > 1 and y < width then
|
||||||
-- check horizontal
|
-- check vertical
|
||||||
local prev = tiles[idx-1]
|
local prev = tiles[idx - width]
|
||||||
local next = tiles[idx+1]
|
local next = tiles[idx + width]
|
||||||
if prev ~= 0 and prev == next then
|
if prev ~= 0 and prev == next then
|
||||||
if (debug) printh("Splitting at " .. idx)
|
if (debug) printh("Splitting at " .. idx) self:fill(idx, prev, true)
|
||||||
self:fill(idx, prev, true)
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
|
||||||
if y>1 and y < width then
|
fill_lines = function(self)
|
||||||
-- check vertical
|
local rows = self:get_rows()
|
||||||
local prev = tiles[idx-width]
|
local cols = self:get_cols()
|
||||||
local next = tiles[idx+width]
|
|
||||||
if prev ~= 0 and prev == next then
|
|
||||||
if (debug) printh("Splitting at " .. idx)
|
|
||||||
self:fill(idx, prev, true)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
|
|
||||||
fill_lines = function(self)
|
-- rows
|
||||||
local rows = self:get_rows()
|
for y, row in ipairs(rows) do
|
||||||
local cols = self:get_cols()
|
local a = count(row, BLUE)
|
||||||
|
local b = count(row, YELLOW)
|
||||||
|
if a ~= b then
|
||||||
|
if a == width / 2 then self:fill_row(y, YELLOW) end
|
||||||
|
if b == width / 2 then self:fill_row(y, BLUE) end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- rows
|
-- columns
|
||||||
for y,row in ipairs(rows) do
|
for x, col in ipairs(cols) do
|
||||||
local a = count(row, BLUE)
|
local a = count(col, BLUE)
|
||||||
local b = count(row, YELLOW)
|
local b = count(col, YELLOW)
|
||||||
if a ~= b then
|
if a ~= b then
|
||||||
if a == width/2 then self:fill_row(y, YELLOW) end
|
if a == width / 2 then self:fill_col(x, YELLOW) end
|
||||||
if b == width/2 then self:fill_row(y, BLUE) end
|
if b == width / 2 then self:fill_col(x, BLUE) end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end,
|
||||||
|
|
||||||
-- columns
|
fill_row = function(self, y, color)
|
||||||
for x,col in ipairs(cols) do
|
if (debug) printh("Filling line " .. y .. " in " .. (color == BLUE and "blue" or "yellow"))
|
||||||
local a = count(col, BLUE)
|
local idx = self:xy_idx(1, y)
|
||||||
local b = count(col, YELLOW)
|
for i = idx, idx + width - 1 do
|
||||||
if a ~= b then
|
if self:get_tile(i) == 0 then
|
||||||
if a == width/2 then self:fill_col(x, YELLOW) end
|
self:fill(i, color)
|
||||||
if b == width/2 then self:fill_col(x, BLUE) end
|
end
|
||||||
end
|
end
|
||||||
end
|
end,
|
||||||
end,
|
|
||||||
|
|
||||||
fill_row = function(self, y, color)
|
fill_col = function(self, x, color)
|
||||||
if (debug) printh("Filling line " .. y .. " in " .. (color == BLUE and "blue" or "yellow"))
|
if (debug) printh("Filling column " .. x .. " in " .. (color == BLUE and "blue" or "yellow"))
|
||||||
local idx = self:xy_idx(1, y)
|
local idx = self:xy_idx(x, 1)
|
||||||
for i = idx, (idx+width-1) do
|
for i = idx, #tiles, width do
|
||||||
if self:get_tile(i) == 0 then
|
if self:get_tile(i) == 0 then
|
||||||
self:fill(i, color)
|
self:fill(i, color)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
|
||||||
fill_col = function(self, x, color)
|
-- Finds "identical" lines, and fill the 2 remaining tiles with inverted colors
|
||||||
if (debug) printh("Filling column " .. x .. " in " .. (color == BLUE and "blue" or "yellow"))
|
no_identical_lines = function(self)
|
||||||
local idx = self:xy_idx(x, 1)
|
-- columns
|
||||||
for i = idx, #tiles, width do
|
local cols = self:get_cols()
|
||||||
if self:get_tile(i) == 0 then
|
for x, col in ipairs(cols) do
|
||||||
self:fill(i, color)
|
-- if the line has the corrent number of colors,
|
||||||
end
|
-- but missing 2 tiles
|
||||||
end
|
if count(col, 0) == 2 and count(col, BLUE) == count(col, YELLOW) then
|
||||||
end,
|
local y1, y2 = unpack(find(col, 0)) -- get the position of the 2 missing tiles
|
||||||
|
-- create both both solutions
|
||||||
|
local ab = copy(col) ab[y1] = BLUE ab[y2] = YELLOW
|
||||||
|
local ba = copy(col) ba[y1] = YELLOW ba[y2] = BLUE
|
||||||
|
-- Check if a dupe exists
|
||||||
|
for x2, col in ipairs(cols) do
|
||||||
|
if equal(col, ab) then
|
||||||
|
self:fill(self:xy_idx(x, y1), YELLOW)
|
||||||
|
self:fill(self:xy_idx(x, y2), BLUE)
|
||||||
|
goto continue
|
||||||
|
elseif equal(col, ba) then
|
||||||
|
self:fill(self:xy_idx(x, y1), BLUE)
|
||||||
|
self:fill(self:xy_idx(x, y2), YELLOW)
|
||||||
|
goto continue
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
::continue::
|
||||||
|
end
|
||||||
|
|
||||||
-- Finds "identical" lines, and fill the 2 remaining tiles with inverted colors
|
-- rows
|
||||||
no_identical_lines = function(self)
|
local rows = self:get_rows()
|
||||||
-- columns
|
for y, row in ipairs(rows) do
|
||||||
local cols = self:get_cols()
|
if count(row, 0) == 2 and count(row, BLUE) == count(row, YELLOW) then
|
||||||
for x,col in ipairs(cols) do
|
local x1, x2 = unpack(find(row, 0))
|
||||||
-- if the line has the corrent number of colors,
|
local ab = copy(row) ab[x1] = BLUE ab[x2] = YELLOW
|
||||||
-- but missing 2 tiles
|
local ba = copy(row) ba[x1] = YELLOW ba[x2] = BLUE
|
||||||
if count(col, 0) == 2 and count(col, BLUE) == count(col, YELLOW) then
|
-- Check if a dupe exists
|
||||||
local y1, y2 = unpack(find(col, 0)) -- get the position of the 2 missing tiles
|
for y2, row in ipairs(rows) do
|
||||||
-- create both both solutions
|
if equal(row, ab) then
|
||||||
local ab = copy(col) ab[y1] = BLUE ab[y2] = YELLOW
|
self:fill(self:xy_idx(x1, y), YELLOW)
|
||||||
local ba = copy(col) ba[y1] = YELLOW ba[y2] = BLUE
|
self:fill(self:xy_idx(x2, y), BLUE)
|
||||||
-- Check if a dupe exists
|
goto continue
|
||||||
for x2,col in ipairs(cols) do
|
elseif equal(row, ba) then
|
||||||
if equal(col, ab) then
|
self:fill(self:xy_idx(x1, y), BLUE)
|
||||||
self:fill(self:xy_idx(x,y1), YELLOW)
|
self:fill(self:xy_idx(x2, y), YELLOW)
|
||||||
self:fill(self:xy_idx(x,y2), BLUE)
|
goto continue
|
||||||
goto continue
|
end
|
||||||
elseif equal(col, ba) then
|
end
|
||||||
self:fill(self:xy_idx(x,y1), BLUE)
|
end
|
||||||
self:fill(self:xy_idx(x,y2), YELLOW)
|
::continue::
|
||||||
goto continue
|
end
|
||||||
end
|
end,
|
||||||
end
|
|
||||||
end
|
|
||||||
::continue::
|
|
||||||
end
|
|
||||||
|
|
||||||
-- rows
|
lock_tiles = function(self)
|
||||||
local rows = self:get_rows()
|
locked = {}
|
||||||
for y,row in ipairs(rows) do
|
for k, v in ipairs(tiles) do
|
||||||
if count(row, 0) == 2 and count(row, BLUE) == count(row, YELLOW) then
|
if v > 0 then locked[k] = true end
|
||||||
local x1, x2 = unpack(find(row, 0))
|
end
|
||||||
local ab = copy(row) ab[x1] = BLUE ab[x2] = YELLOW
|
end,
|
||||||
local ba = copy(row) ba[x1] = YELLOW ba[x2] = BLUE
|
|
||||||
-- Check if a dupe exists
|
|
||||||
for y2,row in ipairs(rows) do
|
|
||||||
if equal(row, ab) then
|
|
||||||
self:fill(self:xy_idx(x1,y), YELLOW)
|
|
||||||
self:fill(self:xy_idx(x2,y), BLUE)
|
|
||||||
goto continue
|
|
||||||
elseif equal(row, ba) then
|
|
||||||
self:fill(self:xy_idx(x1,y), BLUE)
|
|
||||||
self:fill(self:xy_idx(x2,y), YELLOW)
|
|
||||||
goto continue
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
::continue::
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
|
|
||||||
lock_tiles = function(self)
|
is_locked = function(self, idx)
|
||||||
locked = {}
|
return locked[idx]
|
||||||
for k,v in ipairs(tiles) do
|
end,
|
||||||
if v > 0 then locked[k] = true end
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
|
|
||||||
is_locked = function(self, idx)
|
draw_bg_tile = function(self, k)
|
||||||
return locked[idx]
|
local w = tile_width
|
||||||
end,
|
local x, y = self:draw_coords(k)
|
||||||
|
rectfill2(x + 1, y, w - 2, w, 1)
|
||||||
|
rectfill2(x, y + 1, w, w - 2, 1)
|
||||||
|
end,
|
||||||
|
|
||||||
draw_bg_tile = function(self, k)
|
draw = function(self)
|
||||||
local w = tile_width
|
local w = tile_width
|
||||||
local x,y = self:draw_coords(k)
|
for k, v in ipairs(tiles) do
|
||||||
rectfill2(x+1, y, w-2, w, 1)
|
self:draw_tile(k)
|
||||||
rectfill2(x, y+1, w, w-2, 1)
|
end
|
||||||
end,
|
end,
|
||||||
|
|
||||||
draw = function(self)
|
draw_tile = function(self, idx)
|
||||||
local w = tile_width
|
local w = tile_width
|
||||||
for k,v in ipairs(tiles) do
|
local v = tiles[idx]
|
||||||
self:draw_tile(k)
|
if v > 0 then
|
||||||
end
|
local x, y = self:draw_coords(idx)
|
||||||
end,
|
local color = get_main_color(v)
|
||||||
|
local shade = get_shade_color(v)
|
||||||
draw_tile = function(self, idx)
|
if color == 1 then fillp(▒) else fillp(█) end
|
||||||
local w = tile_width
|
if self:is_locked(idx) then
|
||||||
local v = tiles[idx]
|
rectfill2(x, y, w, w, color)
|
||||||
if v > 0 then
|
else
|
||||||
local x,y = self:draw_coords(idx)
|
roundedrect(x, y, w, w, color)
|
||||||
local color = get_main_color(v)
|
line(x + 1, y + w - 1, x + w - 2, y + w - 1, shade)
|
||||||
local shade = get_shade_color(v)
|
line(x + w - 1, y + 1, x + w - 1, y + w - 2, shade)
|
||||||
if color == 1 then fillp(▒) else fillp(█) end
|
end
|
||||||
if self:is_locked(idx) then
|
else
|
||||||
rectfill2(x, y, w, w, color)
|
fillp(█)
|
||||||
else
|
self:draw_bg_tile(idx)
|
||||||
roundedrect(x, y, w, w, color)
|
end
|
||||||
line(x+1, y+w-1, x+w-2, y+w-1, shade)
|
end
|
||||||
line(x+w-1, y+1, x+w-1, y+w-2, shade)
|
}
|
||||||
end
|
|
||||||
else
|
|
||||||
fillp(█)
|
|
||||||
self:draw_bg_tile(idx)
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
end
|
end
|
|
@ -1,34 +1,35 @@
|
||||||
local coroutines={}
|
local coroutines = {}
|
||||||
|
|
||||||
-- starts a coroutine and saves it for future reference
|
-- starts a coroutine and saves it for future reference
|
||||||
function startcoroutine(co)
|
function startcoroutine(co)
|
||||||
assert(tostr(co) == "[thread]") -- make sure that co is a coroutine, the return value of cocreate()
|
assert(tostr(co) == "[thread]")
|
||||||
add(coroutines, co)
|
-- make sure that co is a coroutine, the return value of cocreate()
|
||||||
|
add(coroutines, co)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- stops the the coroutine
|
-- stops the the coroutine
|
||||||
function stopcoroutine(co)
|
function stopcoroutine(co)
|
||||||
del(coroutines, co)
|
del(coroutines, co)
|
||||||
end
|
end
|
||||||
|
|
||||||
function _coresolve()
|
function _coresolve()
|
||||||
for co in all(coroutines) do
|
for co in all(coroutines) do
|
||||||
if costatus(co) != 'dead' then
|
if costatus(co) != 'dead' then
|
||||||
assert(coresume(co))
|
assert(coresume(co))
|
||||||
else
|
else
|
||||||
stopcoroutine(co)
|
stopcoroutine(co)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- to be used inside a coroutine
|
-- to be used inside a coroutine
|
||||||
function wait(seconds)
|
function wait(seconds)
|
||||||
wait_frames(seconds*30)
|
wait_frames(seconds * 30)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- to be used inside a coroutine
|
-- to be used inside a coroutine
|
||||||
function wait_frames(frames)
|
function wait_frames(frames)
|
||||||
for i=1,frames do
|
for i = 1, frames do
|
||||||
yield()
|
yield()
|
||||||
end
|
end
|
||||||
end
|
end
|
36
globals.lua
36
globals.lua
|
@ -12,24 +12,24 @@ local YELLOW = 1
|
||||||
|
|
||||||
-- 🅾️ Z[C]N ❎ [X]VM
|
-- 🅾️ Z[C]N ❎ [X]VM
|
||||||
-- X and C have the same position on QWERTY and AZERTY
|
-- X and C have the same position on QWERTY and AZERTY
|
||||||
local LEFT,RIGHT,UP,DOWN,BTN_O,BTN_X = 0,1,2,3,4,5
|
local LEFT, RIGHT, UP, DOWN, BTN_O, BTN_X = 0, 1, 2, 3, 4, 5
|
||||||
|
|
||||||
local patterns = {
|
local patterns = {
|
||||||
0b0000000000000000,
|
0b0000000000000000,
|
||||||
0b1000000000000000,
|
0b1000000000000000,
|
||||||
0b1000000000100000,
|
0b1000000000100000,
|
||||||
0b1010000000100000,
|
0b1010000000100000,
|
||||||
0b1010000010100000,
|
0b1010000010100000,
|
||||||
0b1010010010100000,
|
0b1010010010100000,
|
||||||
0b1010010010100001,
|
0b1010010010100001,
|
||||||
0b1010010110100001,
|
0b1010010110100001,
|
||||||
0b1010010110100101,
|
0b1010010110100101,
|
||||||
0b1110010110100101,
|
0b1110010110100101,
|
||||||
0b1110010110110101,
|
0b1110010110110101,
|
||||||
0b1111010110110101,
|
0b1111010110110101,
|
||||||
0b1111010111110101,
|
0b1111010111110101,
|
||||||
0b1111110111110101,
|
0b1111110111110101,
|
||||||
0b1111110111110111,
|
0b1111110111110111,
|
||||||
0b1111111111110111,
|
0b1111111111110111,
|
||||||
0b1111111111111111,
|
0b1111111111111111
|
||||||
}
|
}
|
123
main.lua
123
main.lua
|
@ -3,62 +3,63 @@
|
||||||
--
|
--
|
||||||
|
|
||||||
function custom_font()
|
function custom_font()
|
||||||
poke(0x5f58,0x81)
|
poke(0x5f58, 0x81)
|
||||||
end
|
end
|
||||||
|
|
||||||
function standard_font(font)
|
function standard_font(font)
|
||||||
poke(0x5f58,0x80)
|
poke(0x5f58, 0x80)
|
||||||
end
|
end
|
||||||
|
|
||||||
function idx_xy(idx, width)
|
function idx_xy(idx, width)
|
||||||
return (idx - 1) % width + 1, (idx - 1) \ width + 1
|
return (idx - 1) % width + 1, (idx - 1) \ width + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
function xy_idx(x, y, width)
|
function xy_idx(x, y, width)
|
||||||
return ((y - 1) * width) + x
|
return (y - 1) * width + x
|
||||||
end
|
end
|
||||||
|
|
||||||
function map(tbl, f)
|
function map(tbl, f)
|
||||||
local t = {}
|
local t = {}
|
||||||
for k, v in pairs(tbl) do
|
for k, v in pairs(tbl) do
|
||||||
t[k] = f(v)
|
t[k] = f(v)
|
||||||
end
|
end
|
||||||
return t
|
return t
|
||||||
end
|
end
|
||||||
|
|
||||||
function filter(tbl, f, keepindex)
|
function filter(tbl, f, keepindex)
|
||||||
local ret = {}
|
local ret = {}
|
||||||
for k, v in pairs(tbl) do
|
for k, v in pairs(tbl) do
|
||||||
if f(v) then
|
if f(v) then
|
||||||
if keepindex
|
if keepindex then
|
||||||
then ret[k] = v
|
ret[k] = v
|
||||||
else add(ret, v)
|
else
|
||||||
end
|
add(ret, v)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return ret
|
end
|
||||||
|
return ret
|
||||||
end
|
end
|
||||||
|
|
||||||
function slice(tbl, first, last, step)
|
function slice(tbl, first, last, step)
|
||||||
local sliced = {}
|
local sliced = {}
|
||||||
for i = (first or 1), (last or #tbl), (step or 1) do
|
for i = first or 1, last or #tbl, step or 1 do
|
||||||
sliced[#sliced + 1] = tbl[i]
|
sliced[#sliced + 1] = tbl[i]
|
||||||
end
|
end
|
||||||
return sliced
|
return sliced
|
||||||
end
|
end
|
||||||
|
|
||||||
function rectfill2(x, y, w, h, col)
|
function rectfill2(x, y, w, h, col)
|
||||||
rectfill(x, y, x+w-1, y+h-1, col)
|
rectfill(x, y, x + w - 1, y + h - 1, col)
|
||||||
end
|
end
|
||||||
|
|
||||||
function roundedrect(x, y, w, h, col)
|
function roundedrect(x, y, w, h, col)
|
||||||
rectfill2(x,y,w,h,0)
|
rectfill2(x, y, w, h, 0)
|
||||||
rectfill2(x+1, y, w-2, h, col)
|
rectfill2(x + 1, y, w - 2, h, col)
|
||||||
rectfill2(x, y+1, w, h-2, col)
|
rectfill2(x, y + 1, w, h - 2, col)
|
||||||
end
|
end
|
||||||
|
|
||||||
function rect2(x, y, w, h, col)
|
function rect2(x, y, w, h, col)
|
||||||
rect(x, y, x+w, y+h, col)
|
rect(x, y, x + w, y + h, col)
|
||||||
end
|
end
|
||||||
|
|
||||||
--
|
--
|
||||||
|
@ -74,7 +75,6 @@ end
|
||||||
-- return c
|
-- return c
|
||||||
-- end
|
-- end
|
||||||
|
|
||||||
|
|
||||||
-- function tostring(any)
|
-- function tostring(any)
|
||||||
-- if (type(any)~="table") return tostr(any)
|
-- if (type(any)~="table") return tostr(any)
|
||||||
-- local str = "{"
|
-- local str = "{"
|
||||||
|
@ -85,53 +85,50 @@ end
|
||||||
-- return str.."}"
|
-- return str.."}"
|
||||||
-- end
|
-- end
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- main loop
|
-- main loop
|
||||||
--
|
--
|
||||||
|
|
||||||
function _init()
|
function _init()
|
||||||
-- pal({[0]=0,128,132,7,136,8,14,137,9,10,131,3,11,1,140,12},1)
|
-- pal({[0]=0,128,132,7,136,8,14,137,9,10,131,3,11,1,140,12},1)
|
||||||
-- poke(0x5f2e,1) --to keep colors
|
-- poke(0x5f2e,1) --to keep colors
|
||||||
|
|
||||||
printh(" ")
|
printh(" ")
|
||||||
printh("*************")
|
printh("*************")
|
||||||
printh(" ")
|
printh(" ")
|
||||||
local date = stat(80)..stat(81)..stat(82)..stat(84)..stat(85)
|
local date = stat(80) .. stat(81) .. stat(82) .. stat(84) .. stat(85)
|
||||||
srand(date)
|
srand(date)
|
||||||
printh("seed " .. date)
|
printh("seed " .. date)
|
||||||
|
|
||||||
|
frame_count = 0
|
||||||
|
|
||||||
frame_count = 0
|
states = {
|
||||||
|
rules = state_rules(),
|
||||||
states = {
|
menu = state_menu(),
|
||||||
rules = state_rules(),
|
loading = state_loading(),
|
||||||
menu = state_menu(),
|
game = state_game(),
|
||||||
loading = state_loading(),
|
endgame = state_endgame()
|
||||||
game = state_game(),
|
}
|
||||||
endgame = state_endgame(),
|
|
||||||
}
|
|
||||||
|
|
||||||
set_state(states.menu)
|
|
||||||
|
|
||||||
|
set_state(states.menu)
|
||||||
end
|
end
|
||||||
|
|
||||||
function _update60()
|
function _update60()
|
||||||
frame_count += 1
|
frame_count += 1
|
||||||
|
|
||||||
-- update mouse coords
|
-- update mouse coords
|
||||||
mouse_x = stat(32)
|
mouse_x = stat(32)
|
||||||
mouse_y = stat(33)
|
mouse_y = stat(33)
|
||||||
|
|
||||||
_coresolve()
|
_coresolve()
|
||||||
gs._update()
|
gs._update()
|
||||||
end
|
end
|
||||||
|
|
||||||
function _draw()
|
function _draw()
|
||||||
gs._draw()
|
gs._draw()
|
||||||
for overlay in all(overlays) do
|
for overlay in all(overlays) do
|
||||||
overlay:_draw()
|
overlay:_draw()
|
||||||
end
|
end
|
||||||
-- mouse cursor
|
-- mouse cursor
|
||||||
spr(1, mouse_x, mouse_y)
|
spr(1, mouse_x, mouse_y)
|
||||||
end
|
end
|
|
@ -1,51 +1,54 @@
|
||||||
function state_endgame()
|
function state_endgame()
|
||||||
local board
|
local board
|
||||||
local message = "웃웃 yay! 웃웃"
|
local message = "웃웃 yay! 웃웃"
|
||||||
local message_x = 0
|
local message_x = 0
|
||||||
|
|
||||||
local function go_to_menu()
|
local function go_to_menu()
|
||||||
set_state(states.menu)
|
set_state(states.menu)
|
||||||
end
|
end
|
||||||
|
|
||||||
local btn_back = make_button({x=1, y=118, h=7, text="🅾️/C bACK TO mENU", color=8,
|
local btn_back = make_button({
|
||||||
on_click=function() go_to_menu() end,
|
x = 1, y = 118, h = 7, text = "🅾️/C bACK TO mENU", color = 8,
|
||||||
on_hover=function(btn) btn.color = 7 end})
|
on_click = function() go_to_menu() end,
|
||||||
|
on_hover = function(btn) btn.color = 7 end
|
||||||
|
})
|
||||||
|
|
||||||
local function _enter(_board)
|
local function _enter(_board)
|
||||||
board = _board
|
board = _board
|
||||||
message_x = (128 - print(message,0,-100))/2
|
message_x = (128 - print(message, 0, -100)) / 2
|
||||||
end
|
end
|
||||||
|
|
||||||
local function _update()
|
local function _update()
|
||||||
btn_back:update()
|
btn_back:update()
|
||||||
if btnp(BTN_O) then
|
if btnp(BTN_O) then
|
||||||
go_to_menu()
|
go_to_menu()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function _draw()
|
local function _draw()
|
||||||
cls()
|
cls()
|
||||||
board:draw()
|
board:draw()
|
||||||
|
|
||||||
-- wavy message
|
-- wavy message
|
||||||
local offset=0
|
local offset = 0
|
||||||
for i = 1, #message, 1 do -- loop through every letter
|
for i = 1, #message, 1 do
|
||||||
letter = sub(message, i, i) -- grab this letter
|
-- loop through every letter
|
||||||
local st = t() + 0.125 * i -- create a modified time for this letter
|
letter = sub(message, i, i) -- grab this letter
|
||||||
print(letter, message_x + offset, 20 + sin(st*0.5)*10, 7) -- draw this letter
|
local st = t() + 0.125 * i -- create a modified time for this letter
|
||||||
offset += print(letter,0,-100)
|
print(letter, message_x + offset, 20 + sin(st * 0.5) * 10, 7) -- draw this letter
|
||||||
end
|
offset += print(letter, 0, -100)
|
||||||
|
end
|
||||||
|
|
||||||
btn_back:draw()
|
btn_back:draw()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function _leave()
|
local function _leave()
|
||||||
end
|
end
|
||||||
|
|
||||||
return {
|
return {
|
||||||
_enter = _enter,
|
_enter = _enter,
|
||||||
_update = _update,
|
_update = _update,
|
||||||
_draw = _draw,
|
_draw = _draw,
|
||||||
_leave = _leave
|
_leave = _leave
|
||||||
}
|
}
|
||||||
end
|
end
|
231
states/game.lua
231
states/game.lua
|
@ -1,134 +1,133 @@
|
||||||
function state_game()
|
function state_game()
|
||||||
|
local board
|
||||||
|
local selected_id = 1
|
||||||
|
local timer_clue = 0
|
||||||
|
local mx, mx = 0, 0
|
||||||
|
|
||||||
local board
|
local clues = {}
|
||||||
local selected_id = 1
|
local function show_clues()
|
||||||
local timer_clue = 0
|
local issues = board:get_issues(true)
|
||||||
local mx,mx = 0,0
|
clues = {}
|
||||||
|
for issue in all(issues) do
|
||||||
|
local type, err, row, pos, other = unpack(issue)
|
||||||
|
printh(type .. " " .. err .. " " .. pos)
|
||||||
|
add(clues, { type = type, pos = pos, t = 0 })
|
||||||
|
if err == "identical" then
|
||||||
|
add(clues, { type = type, pos = other, t = 0 })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local clues = {}
|
local function draw_selected_tile()
|
||||||
local function show_clues()
|
local x, y = board:draw_coords(selected_id)
|
||||||
local issues = board:get_issues(true)
|
local w = board:get_tile_width()
|
||||||
clues = {}
|
-- fillp(▒)
|
||||||
for issue in all(issues) do
|
rect2(x - 1, y - 1, w, w, 6)
|
||||||
local type, err, row, pos, other = unpack(issue)
|
line()
|
||||||
printh(type .. " " .. err .. " " .. pos)
|
fillp(█)
|
||||||
add(clues, {type=type, pos=pos, t=0})
|
end
|
||||||
if err == "identical" then
|
|
||||||
add(clues, {type=type, pos=other, t=0})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function draw_selected_tile()
|
local function update_mouse()
|
||||||
local x, y = board:draw_coords(selected_id)
|
-- update mouse position
|
||||||
local w = board:get_tile_width()
|
if mx == mouse_x and my == mouse_y then return end
|
||||||
-- fillp(▒)
|
mx, my = mouse_x, mouse_y
|
||||||
rect2(x-1, y-1, w, w, 6)
|
local board_x, board_y = board:draw_coords(1)
|
||||||
line()
|
local tw = board:get_tile_width()
|
||||||
fillp(█)
|
local bw = board:get_size()
|
||||||
end
|
-- pixels coords to grid coords
|
||||||
|
local x = mid(1, (mouse_x - board_x) \ tw + 1, bw)
|
||||||
|
local y = mid(1, (mouse_y - board_y) \ tw + 1, bw)
|
||||||
|
selected_id = board:xy_idx(x, y)
|
||||||
|
end
|
||||||
|
|
||||||
local function update_mouse()
|
local function check_endgame()
|
||||||
-- update mouse position
|
if board:is_complete() and board:is_valid() then
|
||||||
if mx == mouse_x and my == mouse_y then return end
|
set_state(states.endgame, board)
|
||||||
mx,my = mouse_x, mouse_y
|
end
|
||||||
local board_x, board_y = board:draw_coords(1)
|
end
|
||||||
local tw = board:get_tile_width()
|
|
||||||
local bw = board:get_size()
|
|
||||||
-- pixels coords to grid coords
|
|
||||||
local x = mid(1, (mouse_x - board_x) \ tw + 1, bw)
|
|
||||||
local y = mid(1, (mouse_y - board_y) \ tw + 1, bw)
|
|
||||||
selected_id = board:xy_idx(x,y)
|
|
||||||
end
|
|
||||||
|
|
||||||
local function check_endgame()
|
local function _enter(_board)
|
||||||
if board:is_complete() and board:is_valid() then
|
-- mouse bound to buttons
|
||||||
set_state(states.endgame, board)
|
poke(0x5F2D, 3)
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function _enter(_board)
|
board = _board
|
||||||
-- mouse bound to buttons
|
-- lock the initial tiles
|
||||||
poke(0x5F2D, 3)
|
board:lock_tiles()
|
||||||
|
end
|
||||||
|
|
||||||
board = _board
|
local function _leave()
|
||||||
-- lock the initial tiles
|
-- stopcoroutine(show_clues)
|
||||||
board:lock_tiles()
|
end
|
||||||
end
|
|
||||||
|
|
||||||
local function _leave()
|
local function _update()
|
||||||
-- stopcoroutine(show_clues)
|
update_mouse()
|
||||||
end
|
|
||||||
|
|
||||||
local function _update()
|
local size = board:get_size()
|
||||||
update_mouse()
|
local x, y = board:idx_xy(selected_id)
|
||||||
|
local moved = false
|
||||||
|
|
||||||
local size = board:get_size()
|
if btnp(UP) then
|
||||||
local x, y = board:idx_xy(selected_id)
|
moved = true
|
||||||
local moved = false
|
y -= 1
|
||||||
|
elseif btnp(DOWN) then
|
||||||
|
moved = true
|
||||||
|
y += 1
|
||||||
|
elseif btnp(LEFT) then
|
||||||
|
moved = true
|
||||||
|
x -= 1
|
||||||
|
elseif btnp(RIGHT) then
|
||||||
|
moved = true
|
||||||
|
x += 1
|
||||||
|
end
|
||||||
|
if moved then
|
||||||
|
selected_id = board:xy_idx(x, y)
|
||||||
|
end
|
||||||
|
|
||||||
if btnp(UP) then
|
if btnp(BTN_X) then
|
||||||
moved = true
|
board:try_flip_tile(selected_id)
|
||||||
y -= 1
|
show_clues()
|
||||||
elseif btnp(DOWN) then
|
end
|
||||||
moved = true
|
|
||||||
y += 1
|
|
||||||
elseif btnp(LEFT) then
|
|
||||||
moved = true
|
|
||||||
x -= 1
|
|
||||||
elseif btnp(RIGHT) then
|
|
||||||
moved = true
|
|
||||||
x += 1
|
|
||||||
end
|
|
||||||
if moved then
|
|
||||||
selected_id = board:xy_idx(x, y)
|
|
||||||
end
|
|
||||||
|
|
||||||
if btnp(BTN_X) then
|
if (x < 1) x = size
|
||||||
board:try_flip_tile(selected_id)
|
if (x > size) x = 1
|
||||||
show_clues()
|
if (y < 1) y = size
|
||||||
end
|
if (y > size) y = 1
|
||||||
|
check_endgame()
|
||||||
|
end
|
||||||
|
|
||||||
if (x<1) x=size
|
local function _draw()
|
||||||
if (x>size) x=1
|
cls()
|
||||||
if (y<1) y=size
|
local x, y = board:draw_coords(1)
|
||||||
if (y>size) y=1
|
draw_animated_bg(x)
|
||||||
|
|
||||||
check_endgame()
|
board:draw()
|
||||||
end
|
draw_selected_tile()
|
||||||
|
|
||||||
local function _draw()
|
-- draw clues
|
||||||
cls()
|
for clue in all(clues) do
|
||||||
local x,y = board:draw_coords(1)
|
palt(0, false)
|
||||||
draw_animated_bg(x)
|
palt(5, true)
|
||||||
|
local x, y
|
||||||
|
if clue.type == "row" then
|
||||||
|
x, y = board:draw_coords((clue.pos - 1) * board:get_size() + 1)
|
||||||
|
x = -32
|
||||||
|
spr(19, x + clue.t % 144, y + 1 + sin(t()) * 2)
|
||||||
|
else
|
||||||
|
-- col
|
||||||
|
x, y = board:draw_coords(clue.pos)
|
||||||
|
y = -32
|
||||||
|
spr(19, x + 2 + sin(t()) * 2, y + clue.t % 144)
|
||||||
|
end
|
||||||
|
pset(x, y, 5)
|
||||||
|
clue.t += 1
|
||||||
|
end
|
||||||
|
palt()
|
||||||
|
end
|
||||||
|
|
||||||
board:draw()
|
return {
|
||||||
draw_selected_tile()
|
_enter = _enter,
|
||||||
|
_update = _update,
|
||||||
-- draw clues
|
_draw = _draw,
|
||||||
for clue in all(clues) do
|
_leave = _leave
|
||||||
palt(0,false)
|
}
|
||||||
palt(5,true)
|
|
||||||
local x,y
|
|
||||||
if clue.type == "row" then
|
|
||||||
x,y = board:draw_coords((clue.pos-1) * board:get_size()+1)
|
|
||||||
x=-32
|
|
||||||
spr(19, x+clue.t%144, y+1+sin(t())*2)
|
|
||||||
else -- col
|
|
||||||
x,y = board:draw_coords(clue.pos)
|
|
||||||
y=-32
|
|
||||||
spr(19, x+2+sin(t())*2, y+clue.t%144)
|
|
||||||
end
|
|
||||||
pset(x, y, 5)
|
|
||||||
clue.t += 1
|
|
||||||
end
|
|
||||||
palt()
|
|
||||||
end
|
|
||||||
|
|
||||||
return {
|
|
||||||
_enter = _enter,
|
|
||||||
_update = _update,
|
|
||||||
_draw = _draw,
|
|
||||||
_leave = _leave
|
|
||||||
}
|
|
||||||
end
|
end
|
|
@ -1,158 +1,160 @@
|
||||||
function state_loading()
|
function state_loading()
|
||||||
local board
|
local board
|
||||||
local size
|
local size
|
||||||
local og_rt
|
local og_rt
|
||||||
local removing_tile
|
local removing_tile
|
||||||
|
|
||||||
local spinner = split"-,\\,|,/"
|
local spinner = split "-,\\,|,/"
|
||||||
local loading_messages = {
|
local loading_messages = {
|
||||||
"rETICULATING SPLINES",
|
"rETICULATING SPLINES",
|
||||||
"aLLOCATING RESSOURCES",
|
"aLLOCATING RESSOURCES",
|
||||||
"eMULATING HARDWARE",
|
"eMULATING HARDWARE",
|
||||||
"uNCLOGGING MEMORY BUS",
|
"uNCLOGGING MEMORY BUS",
|
||||||
"sPINNING UP ai AGENT",
|
"sPINNING UP ai AGENT",
|
||||||
"sIDE-STEPPING VIRTUAL MACHINE",
|
"sIDE-STEPPING VIRTUAL MACHINE",
|
||||||
"iNSTALLING BACKTRACKING WIZARD",
|
"iNSTALLING BACKTRACKING WIZARD",
|
||||||
"eXFOLIATING PIXELS",
|
"eXFOLIATING PIXELS",
|
||||||
"sCAFFOLDING RAY-TRACING ALGORITHM",
|
"sCAFFOLDING RAY-TRACING ALGORITHM",
|
||||||
"sWEEPING PARTICLES",
|
"sWEEPING PARTICLES",
|
||||||
"pRESSURIZING USER INTERFACE",
|
"pRESSURIZING USER INTERFACE",
|
||||||
"sHAKING RED AND BLUE PAINT BUCKETS",
|
"sHAKING RED AND BLUE PAINT BUCKETS",
|
||||||
"gATHERING GRAVITY",
|
"gATHERING GRAVITY",
|
||||||
"sERIALIZING BOARD MATRIX",
|
"sERIALIZING BOARD MATRIX",
|
||||||
"bACKPORTING e2e ENCRYPTION",
|
"bACKPORTING e2e ENCRYPTION"
|
||||||
}
|
}
|
||||||
|
|
||||||
local message = ""
|
local message = ""
|
||||||
local messages_str = ""
|
local messages_str = ""
|
||||||
local messages_x = 128
|
local messages_x = 128
|
||||||
local loaded = false
|
local loaded = false
|
||||||
local done = {}
|
local done = {}
|
||||||
|
|
||||||
local create_board = function()
|
local create_board = function()
|
||||||
printh("creating")
|
printh("creating")
|
||||||
local start = time()
|
local start = time()
|
||||||
repeat
|
repeat
|
||||||
board:reset()
|
board:reset()
|
||||||
repeat
|
repeat
|
||||||
board:solve_step(true)
|
board:solve_step(true)
|
||||||
yield()
|
yield()
|
||||||
until board:is_complete()
|
until board:is_complete()
|
||||||
until board:is_valid()
|
until board:is_valid()
|
||||||
|
|
||||||
-- Remove tiles that can be removed
|
-- Remove tiles that can be removed
|
||||||
local previous = {board:get_tiles_copy()} -- initial state
|
local previous = { board:get_tiles_copy() }
|
||||||
done = {}
|
-- initial state
|
||||||
while true do
|
done = {}
|
||||||
|
while true do
|
||||||
|
board:set_tiles(previous[#previous])
|
||||||
|
-- remove a random tile
|
||||||
|
repeat
|
||||||
|
removing_tile += 1
|
||||||
|
if removing_tile > size then
|
||||||
|
removing_tile = 1
|
||||||
|
end
|
||||||
|
until removing_tile == size or board:get_tiles_copy()[removing_tile] ~= 0
|
||||||
|
if removing_tile == og_rt then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
board:set_tiles(previous[#previous])
|
board:fill(removing_tile, 0)
|
||||||
-- remove a random tile
|
add(done, removing_tile)
|
||||||
repeat
|
add(previous, board:get_tiles_copy())
|
||||||
removing_tile += 1
|
|
||||||
if removing_tile > size then
|
|
||||||
removing_tile = 1
|
|
||||||
end
|
|
||||||
until removing_tile == size or board:get_tiles_copy()[removing_tile] ~= 0
|
|
||||||
if removing_tile == og_rt then
|
|
||||||
break
|
|
||||||
end
|
|
||||||
|
|
||||||
board:fill(removing_tile, 0)
|
-- try to solve the board
|
||||||
add(done, removing_tile)
|
local solved = ""
|
||||||
add(previous, board:get_tiles_copy())
|
yield()
|
||||||
|
repeat
|
||||||
|
solved = board:solve_step()
|
||||||
|
if solved == "valid" then
|
||||||
|
amplitude -= .125
|
||||||
|
end
|
||||||
|
until board:is_complete() or solved == "invalid"
|
||||||
|
|
||||||
-- try to solve the board
|
if solved == "invalid" then
|
||||||
local solved = ""
|
deli(previous)
|
||||||
yield()
|
end
|
||||||
repeat
|
end
|
||||||
solved = board:solve_step()
|
-- end while
|
||||||
if solved == "valid" then
|
printh("board generated in " .. time() - start .. " seconds")
|
||||||
amplitude -= .125
|
startcoroutine(cocreate(function()
|
||||||
end
|
repeat
|
||||||
until board:is_complete() or solved == "invalid"
|
amplitude -= .5
|
||||||
|
yield()
|
||||||
|
until amplitude <= 0
|
||||||
|
end))
|
||||||
|
|
||||||
if solved == "invalid" then
|
board:set_tiles(previous[#previous])
|
||||||
deli(previous)
|
printh(board:tostring())
|
||||||
end
|
printh(count(board:get_tiles_copy(), 0) .. " zeroes")
|
||||||
end -- end while
|
|
||||||
printh("board generated in "..time()-start.." seconds")
|
|
||||||
startcoroutine(cocreate(function()
|
|
||||||
repeat
|
|
||||||
amplitude -= .5
|
|
||||||
yield()
|
|
||||||
until amplitude <= 0
|
|
||||||
end))
|
|
||||||
|
|
||||||
board:set_tiles(previous[#previous])
|
loaded = true
|
||||||
printh(board:tostring())
|
end
|
||||||
printh(count(board:get_tiles_copy(), 0).." zeroes")
|
|
||||||
|
|
||||||
loaded = true
|
local function draw_tiles(board)
|
||||||
end
|
local w = board:get_size()
|
||||||
|
local tiles = board:get_tiles_copy()
|
||||||
|
for k, v in ipairs(tiles) do
|
||||||
|
if v == 0 or contains(done, k) then
|
||||||
|
board:draw_tile(k)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local function draw_tiles(board)
|
local function _enter()
|
||||||
local w = board:get_size()
|
printh("enter loading")
|
||||||
local tiles = board:get_tiles_copy()
|
board = Board:new()
|
||||||
for k,v in ipairs(tiles) do
|
size = board:get_size() * board:get_size()
|
||||||
if v==0 or contains(done, k) then
|
og_rt = rnd(size) \ 1 + 1
|
||||||
board:draw_tile(k)
|
-- original removing tile
|
||||||
end
|
removing_tile = og_rt
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function _enter()
|
amplitude = 64
|
||||||
printh("enter loading")
|
loaded = false
|
||||||
board = Board:new()
|
done = {}
|
||||||
size = board:get_size()*board:get_size()
|
|
||||||
og_rt = rnd(size)\1+1 -- original removing tile
|
|
||||||
removing_tile = og_rt
|
|
||||||
|
|
||||||
amplitude = 64
|
|
||||||
loaded = false
|
|
||||||
done = {}
|
|
||||||
|
|
||||||
local copy_messages = copy(loading_messages)
|
local copy_messages = copy(loading_messages)
|
||||||
messages_str = ""
|
messages_str = ""
|
||||||
messages_x = 128
|
messages_x = 128
|
||||||
while #copy_messages > 0 do
|
while #copy_messages > 0 do
|
||||||
local m = rnd(copy_messages)
|
local m = rnd(copy_messages)
|
||||||
messages_str ..= m .. " "
|
messages_str ..= m .. " "
|
||||||
del(copy_messages, m)
|
del(copy_messages, m)
|
||||||
end
|
end
|
||||||
messages_str ..= "tHANK YOU FOR YOUR PATIENCE"
|
messages_str ..= "tHANK YOU FOR YOUR PATIENCE"
|
||||||
|
|
||||||
startcoroutine(cocreate(create_board))
|
startcoroutine(cocreate(create_board))
|
||||||
end
|
end
|
||||||
|
|
||||||
local function _update()
|
local function _update()
|
||||||
board:lock_tiles()
|
board:lock_tiles()
|
||||||
|
|
||||||
messages_x -= 4
|
messages_x -= 4
|
||||||
if loaded then
|
if loaded then
|
||||||
set_state(states.game, board)
|
set_state(states.game, board)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function _draw()
|
local function _draw()
|
||||||
cls()
|
cls()
|
||||||
local x,y = board:draw_coords(1)
|
local x, y = board:draw_coords(1)
|
||||||
draw_animated_bg(x)
|
draw_animated_bg(x)
|
||||||
-- board:draw_bg()
|
-- board:draw_bg()
|
||||||
draw_tiles(board)
|
draw_tiles(board)
|
||||||
local s = board:get_size()*board:get_size()
|
local s = board:get_size() * board:get_size()
|
||||||
local l = print(message, 0, -100)
|
local l = print(message, 0, -100)
|
||||||
local y = 118+(removing_tile/s)*100/8
|
local y = 118 + removing_tile / s * 100 / 8
|
||||||
local ci = removing_tile\20+1
|
local ci = removing_tile \ 20 + 1
|
||||||
-- if not loaded then
|
-- if not loaded then
|
||||||
-- rectfill2(0,y-2,127,10,0)
|
-- rectfill2(0,y-2,127,10,0)
|
||||||
-- print(messages_str, messages_x, y, 3, 0)
|
-- print(messages_str, messages_x, y, 3, 0)
|
||||||
-- -- print(spinner[t()\.25%4+1], 120, 120)
|
-- -- print(spinner[t()\.25%4+1], 120, 120)
|
||||||
-- end
|
-- end
|
||||||
end
|
end
|
||||||
|
|
||||||
return {
|
return {
|
||||||
_enter = _enter,
|
_enter = _enter,
|
||||||
_update = _update,
|
_update = _update,
|
||||||
_draw = _draw,
|
_draw = _draw
|
||||||
}
|
}
|
||||||
end
|
end
|
131
states/menu.lua
131
states/menu.lua
|
@ -1,78 +1,79 @@
|
||||||
function state_menu()
|
function state_menu()
|
||||||
local selected = 1
|
local selected = 1
|
||||||
|
|
||||||
local buttons = {}
|
local buttons = {}
|
||||||
-- local buttons = {
|
-- local buttons = {
|
||||||
-- make_button({x=10, y=10, w=30, text="pLAY", data={i=1},
|
-- make_button({x=10, y=10, w=30, text="pLAY", data={i=1},
|
||||||
-- on_click=function() set_state(states.loading) end,
|
-- on_click=function() set_state(states.loading) end,
|
||||||
-- on_hover=function(btn) selected=1 end,
|
-- on_hover=function(btn) selected=1 end,
|
||||||
-- }),
|
-- }),
|
||||||
-- }
|
-- }
|
||||||
|
|
||||||
local game_sizes = {
|
local game_sizes = {
|
||||||
{"mINI bOARD - 4X4", 4},
|
{ "mINI bOARD - 4X4", 4 },
|
||||||
{"sMALL bOARD - 6X6", 6},
|
{ "sMALL bOARD - 6X6", 6 },
|
||||||
{"mEDIUM bOARD - 8X8", 8},
|
{ "mEDIUM bOARD - 8X8", 8 },
|
||||||
{"lARGE bOARD - 10X10", 10}
|
{ "lARGE bOARD - 10X10", 10 }
|
||||||
}
|
}
|
||||||
for k, item in ipairs(game_sizes) do
|
for k, item in ipairs(game_sizes) do
|
||||||
add(buttons,
|
add(
|
||||||
make_button({
|
buttons,
|
||||||
x=10, y=10+k*10,
|
make_button({
|
||||||
selected_color=7,
|
x = 10, y = 10 + k * 10,
|
||||||
text=item[1],
|
selected_color = 7,
|
||||||
on_click=function() board_size=item[2] set_state(states.loading) end,
|
text = item[1],
|
||||||
on_hover=function() selected=k end,
|
on_click = function() board_size = item[2] set_state(states.loading) end,
|
||||||
})
|
on_hover = function() selected = k end
|
||||||
)
|
})
|
||||||
end
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
local rulesId = #buttons + 1
|
||||||
|
add(
|
||||||
|
buttons,
|
||||||
|
make_button({
|
||||||
|
x = 10, y = 20 + (#game_sizes + 1) * 10, w = 30, text = "rULES",
|
||||||
|
color = 13, selected_color = 12,
|
||||||
|
on_click = function() set_state(states.rules) end,
|
||||||
|
on_hover = function() selected = rulesId end
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
local rulesId = #buttons+1
|
local function _enter()
|
||||||
add(buttons,
|
-- mouse not bound to buttons
|
||||||
make_button({x=10, y=20+(#game_sizes+1)*10, w=30, text="rULES",
|
poke(0x5F2D, 1)
|
||||||
color=13, selected_color=12,
|
end
|
||||||
on_click=function() set_state(states.rules) end,
|
|
||||||
on_hover=function() selected=rulesId end,
|
|
||||||
})
|
|
||||||
)
|
|
||||||
|
|
||||||
local function _enter()
|
local function _draw()
|
||||||
-- mouse not bound to buttons
|
cls()
|
||||||
poke(0x5F2D, 1)
|
draw_bg_menu()
|
||||||
end
|
|
||||||
|
|
||||||
local function _draw()
|
print("pLAY", 10, 8, 8)
|
||||||
cls()
|
|
||||||
draw_bg_menu()
|
|
||||||
|
|
||||||
print("pLAY", 10, 8, 8)
|
|
||||||
|
|
||||||
for k,button in ipairs(buttons) do
|
for k, button in ipairs(buttons) do
|
||||||
button:draw(selected == k)
|
button:draw(selected == k)
|
||||||
end
|
end
|
||||||
print("pRESS ❎/X TO CONTINUE", 8, 120, 7)
|
print("pRESS ❎/X TO CONTINUE", 8, 120, 7)
|
||||||
end
|
end
|
||||||
|
|
||||||
return {
|
return {
|
||||||
_enter = _enter,
|
_enter = _enter,
|
||||||
|
|
||||||
_update = function()
|
_update = function()
|
||||||
for button in all(buttons) do
|
for button in all(buttons) do
|
||||||
button:update()
|
button:update()
|
||||||
end
|
end
|
||||||
|
|
||||||
if btnp(UP) then
|
if btnp(UP) then
|
||||||
selected -= 1
|
selected -= 1
|
||||||
elseif btnp(DOWN) then
|
elseif btnp(DOWN) then
|
||||||
selected += 1
|
selected += 1
|
||||||
elseif btnp(BTN_X) then
|
elseif btnp(BTN_X) then
|
||||||
buttons[selected]:on_click()
|
buttons[selected]:on_click()
|
||||||
end
|
end
|
||||||
selected = mid(1, selected, #buttons)
|
selected = mid(1, selected, #buttons)
|
||||||
|
end,
|
||||||
|
|
||||||
end,
|
_draw = _draw
|
||||||
|
}
|
||||||
_draw = _draw
|
|
||||||
}
|
|
||||||
end
|
end
|
150
states/rules.lua
150
states/rules.lua
|
@ -1,94 +1,94 @@
|
||||||
function state_rules()
|
function state_rules()
|
||||||
|
local fade = split "0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,4,9,10,9,4,2,1"
|
||||||
|
local color = 1
|
||||||
|
|
||||||
local fade = split"0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,4,9,10,9,4,2,1"
|
local function blink(x, y, w, h)
|
||||||
local color = 1
|
rect2(x, y, w, h, fade[color])
|
||||||
|
end
|
||||||
|
|
||||||
local function blink(x,y,w,h)
|
local function go_back()
|
||||||
rect2(x,y,w,h,fade[color])
|
set_state(states.menu)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function go_back()
|
local btn_back = make_button({
|
||||||
set_state(states.menu)
|
x = 1, y = 118, w = 30, h = 7, text = "🅾️/C mENU", color = 8,
|
||||||
end
|
on_click = function() go_back() end,
|
||||||
|
on_hover = function(btn) btn.color = 7 end
|
||||||
|
})
|
||||||
|
|
||||||
local btn_back = make_button({x=1, y=118, w=30, h=7, text="🅾️/C mENU", color=8,
|
return {
|
||||||
on_click=function() go_back() end,
|
_enter = function()
|
||||||
on_hover=function(btn) btn.color = 7 end})
|
end,
|
||||||
|
|
||||||
return {
|
_exit = function()
|
||||||
_enter = function()
|
-- standard_font()
|
||||||
end,
|
end,
|
||||||
|
|
||||||
_exit = function()
|
|
||||||
-- standard_font()
|
|
||||||
end,
|
|
||||||
|
|
||||||
_update=function()
|
|
||||||
-- custom_font()
|
|
||||||
if frame_count%8==0 then
|
|
||||||
color += 1
|
|
||||||
end
|
|
||||||
if color>#fade then
|
|
||||||
color = 1
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Back to the menu
|
_update = function()
|
||||||
if btnp(BTN_O) then
|
-- custom_font()
|
||||||
go_back()
|
if frame_count % 8 == 0 then
|
||||||
end
|
color += 1
|
||||||
|
end
|
||||||
|
if color > #fade then
|
||||||
|
color = 1
|
||||||
|
end
|
||||||
|
|
||||||
btn_back:update()
|
-- Back to the menu
|
||||||
end,
|
if btnp(BTN_O) then
|
||||||
|
go_back()
|
||||||
|
end
|
||||||
|
|
||||||
_draw=function()
|
btn_back:update()
|
||||||
cls()
|
end,
|
||||||
|
|
||||||
print("1) yOU CAN'T HAVE MORE THAN\n TWO (2) CONSECUTIVE TILES\n OF THE SAME COLOR", 2,2, 7)
|
_draw = function()
|
||||||
local x = 14
|
cls()
|
||||||
local y = 28
|
|
||||||
sspr(0,32, 12,12, x,y)
|
|
||||||
spr(2, x+14, y+1)
|
|
||||||
sspr(13,32, 12,12, x+26,y)
|
|
||||||
blink(x-1, y-1, 9, 3)
|
|
||||||
blink(x+25, y-1, 9, 3)
|
|
||||||
blink(x-1, y+8, 12, 3)
|
|
||||||
blink(x+25, y+8, 12, 3)
|
|
||||||
|
|
||||||
x = 75
|
print("1) yOU CAN'T HAVE MORE THAN\n TWO (2) CONSECUTIVE TILES\n OF THE SAME COLOR", 2, 2, 7)
|
||||||
sspr(26,32, 12,12, x,y)
|
local x = 14
|
||||||
spr(2, x+14, y+1)
|
local y = 28
|
||||||
sspr(39,32, 12,12, x+26,y)
|
sspr(0, 32, 12, 12, x, y)
|
||||||
blink(x+5, y+2, 3, 9)
|
spr(2, x + 14, y + 1)
|
||||||
blink(x+31, y+2, 3, 9)
|
sspr(13, 32, 12, 12, x + 26, y)
|
||||||
|
blink(x - 1, y - 1, 9, 3)
|
||||||
|
blink(x + 25, y - 1, 9, 3)
|
||||||
|
blink(x - 1, y + 8, 12, 3)
|
||||||
|
blink(x + 25, y + 8, 12, 3)
|
||||||
|
|
||||||
|
x = 75
|
||||||
|
sspr(26, 32, 12, 12, x, y)
|
||||||
|
spr(2, x + 14, y + 1)
|
||||||
|
sspr(39, 32, 12, 12, x + 26, y)
|
||||||
|
blink(x + 5, y + 2, 3, 9)
|
||||||
|
blink(x + 31, y + 2, 3, 9)
|
||||||
|
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
x = 44
|
x = 44
|
||||||
y = 50
|
y = 50
|
||||||
print("2) eACH LINE CONTAINS AN EQUAL\n NUMBER OF EACH COLOR", 2, y, 7)
|
print("2) eACH LINE CONTAINS AN EQUAL\n NUMBER OF EACH COLOR", 2, y, 7)
|
||||||
sspr(52,32, 12,12, x,y+20)
|
sspr(52, 32, 12, 12, x, y + 20)
|
||||||
spr(2, x+14, y+21)
|
spr(2, x + 14, y + 21)
|
||||||
sspr(65,32, 12,12, x+26,y+20)
|
sspr(65, 32, 12, 12, x + 26, y + 20)
|
||||||
blink(x+5, y+22, 6, 3)
|
blink(x + 5, y + 22, 6, 3)
|
||||||
blink(x+31, y+22, 6, 3)
|
blink(x + 31, y + 22, 6, 3)
|
||||||
blink(x-1, y+19, 3, 6)
|
blink(x - 1, y + 19, 3, 6)
|
||||||
blink(x+25, y+19, 3, 6)
|
blink(x + 25, y + 19, 3, 6)
|
||||||
|
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
x = 44
|
x = 44
|
||||||
y = 90
|
y = 90
|
||||||
print("3) aLL ROWS AND COLUMNS\n ARE DIFFERENT", 2, y, 7)
|
print("3) aLL ROWS AND COLUMNS\n ARE DIFFERENT", 2, y, 7)
|
||||||
sspr(78,32, 12,12, x,y+20)
|
sspr(78, 32, 12, 12, x, y + 20)
|
||||||
spr(2, x+14, y+21)
|
spr(2, x + 14, y + 21)
|
||||||
sspr(91,32, 12,12, x+26,y+20)
|
sspr(91, 32, 12, 12, x + 26, y + 20)
|
||||||
blink(x-1, y+25, 12, 6)
|
blink(x - 1, y + 25, 12, 6)
|
||||||
blink(x+25, y+25, 12, 6)
|
blink(x + 25, y + 25, 12, 6)
|
||||||
|
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
btn_back:draw()
|
btn_back:draw()
|
||||||
end,
|
end
|
||||||
}
|
}
|
||||||
end
|
end
|
8
tile.lua
8
tile.lua
|
@ -1,7 +1,7 @@
|
||||||
local Tile = {}
|
local Tile = {}
|
||||||
|
|
||||||
function Tile.new(color)
|
function Tile.new(color)
|
||||||
return {
|
return {
|
||||||
color=color
|
color = color
|
||||||
}
|
}
|
||||||
end
|
end
|
77
ui.lua
77
ui.lua
|
@ -1,42 +1,43 @@
|
||||||
function make_button(options)
|
function make_button(options)
|
||||||
local state = 0 -- 0 = normal, 1 = hovered, 2 = pressed
|
local state = 0
|
||||||
local w = print(options.text, 0, -100)
|
-- 0 = normal, 1 = hovered, 2 = pressed
|
||||||
return {
|
local w = print(options.text, 0, -100)
|
||||||
x = options.x,
|
return {
|
||||||
y = options.y,
|
x = options.x,
|
||||||
w = options.w or w,
|
y = options.y,
|
||||||
h = options.h or 6,
|
w = options.w or w,
|
||||||
data = options.data,
|
h = options.h or 6,
|
||||||
text = options.text,
|
data = options.data,
|
||||||
on_click = options.on_click,
|
text = options.text,
|
||||||
on_hover = options.on_hover,
|
on_click = options.on_click,
|
||||||
ogColor = options.color or 5,
|
on_hover = options.on_hover,
|
||||||
selected_color = options.selected_color or 5,
|
ogColor = options.color or 5,
|
||||||
color = options.color or 5,
|
selected_color = options.selected_color or 5,
|
||||||
|
color = options.color or 5,
|
||||||
|
|
||||||
draw=function(self, selected)
|
draw = function(self, selected)
|
||||||
standard_font()
|
standard_font()
|
||||||
local color = selected and self.selected_color or self.color
|
local color = selected and self.selected_color or self.color
|
||||||
print(self.text, self.x, self.y, color)
|
print(self.text, self.x, self.y, color)
|
||||||
-- rect(self.x, self.y, self.x+self.w, self.y+self.h, color)
|
-- rect(self.x, self.y, self.x+self.w, self.y+self.h, color)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
update=function(self)
|
update = function(self)
|
||||||
self.color = self.ogColor
|
self.color = self.ogColor
|
||||||
if mouse_x >= self.x and mouse_x <= self.x + self.w and
|
if mouse_x >= self.x and mouse_x <= self.x + self.w
|
||||||
mouse_y >= self.y and mouse_y <= self.y + self.h then
|
and mouse_y >= self.y and mouse_y <= self.y + self.h then
|
||||||
if stat(34)&1 == 0 and state == 2 and self.on_click then
|
if stat(34) & 1 == 0 and state == 2 and self.on_click then
|
||||||
self.on_click(self)
|
self.on_click(self)
|
||||||
end
|
end
|
||||||
if stat(34)&1 == 1 then
|
if stat(34) & 1 == 1 then
|
||||||
state = 2
|
state = 2
|
||||||
else
|
else
|
||||||
if self.on_hover then self:on_hover() end
|
if self.on_hover then self:on_hover() end
|
||||||
state = 1
|
state = 1
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
state = 0
|
state = 0
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
end
|
end
|
65
utils.lua
65
utils.lua
|
@ -1,63 +1,62 @@
|
||||||
local oldprint = print
|
local oldprint = print
|
||||||
function print(t,x,y,col1,col2)
|
function print(t, x, y, col1, col2)
|
||||||
if col2 then
|
if col2 then
|
||||||
for i=-1,1 do
|
for i = -1, 1 do
|
||||||
for j=-1,1 do
|
for j = -1, 1 do
|
||||||
oldprint(t, x+i, y+j, col2)
|
oldprint(t, x + i, y + j, col2)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return oldprint(t, x, y, col1)
|
return oldprint(t, x, y, col1)
|
||||||
end
|
end
|
||||||
|
|
||||||
function str_width(str)
|
function str_width(str)
|
||||||
return print(str,0,-8)
|
return print(str, 0, -8)
|
||||||
end
|
end
|
||||||
|
|
||||||
function print_shade(t,x,y,col1,col2)
|
function print_shade(t, x, y, col1, col2)
|
||||||
print(t,x,y+1,col2)
|
print(t, x, y + 1, col2)
|
||||||
print(t,x+1,y+1,col2)
|
print(t, x + 1, y + 1, col2)
|
||||||
print(t,x,y,col1)
|
print(t, x, y, col1)
|
||||||
end
|
end
|
||||||
|
|
||||||
function set_state(state, ...)
|
function set_state(state, ...)
|
||||||
local args = {...}
|
local args = { ... }
|
||||||
if gs and gs._leave then gs._leave() end
|
if gs and gs._leave then gs._leave() end
|
||||||
gs = state
|
gs = state
|
||||||
if gs and gs._enter then gs._enter(unpack(args)) end
|
if gs and gs._enter then gs._enter(unpack(args)) end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Returns the indices of found occurences of `o` within `tbl`
|
-- Returns the indices of found occurences of `o` within `tbl`
|
||||||
--
|
--
|
||||||
function find(tbl, o)
|
function find(tbl, o)
|
||||||
local indices = {}
|
local indices = {}
|
||||||
for k,v in ipairs(tbl) do
|
for k, v in ipairs(tbl) do
|
||||||
if v == o then add(indices, k) end
|
if v == o then add(indices, k) end
|
||||||
end
|
end
|
||||||
return indices
|
return indices
|
||||||
end
|
end
|
||||||
|
|
||||||
function contains(tbl, o)
|
function contains(tbl, o)
|
||||||
for v in all(tbl) do
|
for v in all(tbl) do
|
||||||
if v == o then return true end
|
if v == o then return true end
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
--
|
--
|
||||||
-- Makes a shallow table copy
|
-- Makes a shallow table copy
|
||||||
--
|
--
|
||||||
function copy(tbl)
|
function copy(tbl)
|
||||||
return map(tbl, function (o) return o end)
|
return map(tbl, function(o) return o end)
|
||||||
end
|
end
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Table equality - shallow comparison
|
-- Table equality - shallow comparison
|
||||||
--
|
--
|
||||||
function equal(tbl1, tbl2)
|
function equal(tbl1, tbl2)
|
||||||
for k, _ in ipairs(tbl1) do
|
for k, _ in ipairs(tbl1) do
|
||||||
if tbl1[k] ~= tbl2[k] then return false end
|
if tbl1[k] ~= tbl2[k] then return false end
|
||||||
end
|
end
|
||||||
return true
|
return true
|
||||||
end
|
end
|
62
visuals.lua
62
visuals.lua
|
@ -1,39 +1,41 @@
|
||||||
local overlays = {}
|
local overlays = {}
|
||||||
|
|
||||||
function get_main_color(tint)
|
function get_main_color(tint)
|
||||||
if tint == BLUE then
|
if tint == BLUE then
|
||||||
return 12
|
return 12
|
||||||
elseif tint == YELLOW then
|
elseif tint == YELLOW then
|
||||||
return 9
|
return 9
|
||||||
else
|
else
|
||||||
return 1
|
return 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function get_shade_color(tint)
|
function get_shade_color(tint)
|
||||||
if tint == BLUE then
|
if tint == BLUE then
|
||||||
return 13
|
return 13
|
||||||
elseif tint == YELLOW then
|
elseif tint == YELLOW then
|
||||||
return 4
|
return 4
|
||||||
else
|
else
|
||||||
return 1
|
return 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function spawn_tile_transition(x, y, w, h, from_tint, to_tint)
|
function spawn_tile_transition(x, y, w, h, from_tint, to_tint)
|
||||||
local p = #patterns
|
local p = #patterns
|
||||||
local from_color = get_main_color(from_tint)
|
local from_color = get_main_color(from_tint)
|
||||||
local to_color = get_main_color(to_tint)
|
local to_color = get_main_color(to_tint)
|
||||||
add(overlays, {
|
add(
|
||||||
_draw = function(self)
|
overlays, {
|
||||||
fillp()
|
_draw = function(self)
|
||||||
rectfill(x, y, x + w, y + h, from_color)
|
fillp()
|
||||||
fillp(patterns[p\1]+0b0.1)
|
rectfill(x, y, x + w, y + h, from_color)
|
||||||
rectfill(x, y, x + w, y + h, to_color)
|
fillp(patterns[p \ 1] + 0b0.1)
|
||||||
p -= 1
|
rectfill(x, y, x + w, y + h, to_color)
|
||||||
if p < 1 then
|
p -= 1
|
||||||
del(overlays, self)
|
if p < 1 then
|
||||||
end
|
del(overlays, self)
|
||||||
end
|
end
|
||||||
})
|
end
|
||||||
end
|
}
|
||||||
|
)
|
||||||
|
end
|
Loading…
Reference in New Issue
Block a user