From c0870b4831d8d408ea6bf00d3d4be9016051a3eb Mon Sep 17 00:00:00 2001 From: Simon Cambier Date: Sat, 28 May 2022 11:44:09 +0200 Subject: [PATCH] First commit --- 0hh1.p8 | 11 +++ main.lua | 267 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 278 insertions(+) create mode 100644 0hh1.p8 create mode 100644 main.lua diff --git a/0hh1.p8 b/0hh1.p8 new file mode 100644 index 0000000..c8c0a96 --- /dev/null +++ b/0hh1.p8 @@ -0,0 +1,11 @@ +pico-8 cartridge // http://www.pico-8.com +version 36 +__lua__ +#include main.lua +__gfx__ +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00700700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00700700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 diff --git a/main.lua b/main.lua new file mode 100644 index 0000000..8de3035 --- /dev/null +++ b/main.lua @@ -0,0 +1,267 @@ +-- +-- constants +-- + +local BLUE = 1 +local YELLOW = 2 + +-- +-- Utils +-- + +local a = BLUE + +function idx_xy(idx, width) + return (idx - 1) % width + 1, (idx - 1) \ width + 1 +end + +function xy_idx(x, y, width) + return ((y - 1) * width) + x +end + +function map(tbl, f) + local t = {} + for k, v in pairs(tbl) do + t[k] = f(v) + end + return t +end + +function filter(tbl, f, keepindex) + local ret = {} + for k, v in pairs(tbl) do + if f(v) then + if keepindex + then ret[k] = v + else add(ret, v) + end + end + end + return ret +end + +function slice(tbl, first, last, step) + local sliced = {} + for i = (first or 1), (last or #tbl), (step or 1) do + sliced[(#sliced + 1)] = tbl[i] + end + return sliced +end + +local _rectfill = rectfill +function rectfill(x, y, w, h, col) + _rectfill(x, y, x+w, y+h, col) +end + +local _count = count +function count(tbl, p) + if type(p) != "function" then return _count(tbl, p) end + local c = 0 + for v in all(tbl) do + if p(v) then c+=1 end + end + return c +end + +-- +-- Board +-- + +local Board = {} +function Board.new() + local width = 6 + local t = [[ + 0, 0, 0, 0, 1, 0, + 2, 0, 0, 0, 1, 2, + 0, 0, 2, 0, 0, 0, + 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 2 + ]] + local tiles = split(t) + + return { + getTile = function(self, idx) + return tiles[idx] + end, + + idx_xy = function(self, idx) + return idx_xy(idx, width) + end, + + xy_idx = function(self, x, y) + return xy_idx(x, y, width) + end, + + fill = function(self, idx, color, invert) + if invert then + color = color == YELLOW and BLUE or YELLOW + end + tiles[idx] = color + end, + + getRows = function(self) + local ret = {} + for i = 1, width do + add(ret, slice(tiles, ((i - 1) * width) + 1, i * width)) + end + return ret + end, + + getCols = function(self) + local ret = {} + local rows = self.getRows(self) + for i = 1, width do + add(ret, map(rows, function(v) return v[i] end)) + end + return ret + end, + + solve = function(self) + self:surroundDoubles() + self:splitTriples() + self:fillLines() + self:noIdenticalLines() + end, + + surroundDoubles = function(self) + for idx,v in ipairs(tiles) do + local x,y = self:idx_xy(idx) + if v == 0 then + local neighbors = {} + -- 2 tiles on the left + if x >= 3 then + add(neighbors, {idx, idx-1, idx-2}) + end + -- 2 tiles on the right + if x <= width-2 then + add(neighbors, {idx, idx+1, idx+2}) + end + -- 2 tiles on top + if y >= 3 then + add(neighbors, {idx, idx-width, idx - width*2}) + end + -- 2 tiles under + if y <= width-2 then + add(neighbors, {idx, idx+width, idx + width*2}) + end + + -- 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) + + -- do the surrounding + for item in all(neighbors) do + if item[1] then + printh("Surrounding at " .. item[1]) + self:fill(item[1], tiles[item[2]], true) + end + end + end + end + end, + + splitTriples = function(self) + for idx, col in ipairs(tiles) do + local x,y = self:idx_xy(idx) + 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 + printh("Splitting at " .. idx) + self:fill(idx, prev, true) + end + end + + if y>1 and y < width then + -- check vertical + local prev = tiles[idx-width] + local next = tiles[idx+width] + if prev ~= 0 and prev == next then + printh("Splitting at " .. idx) + self:fill(idx, prev, true) + end + end + end + end + end, + + fillLines = function(self) + local rows = self:getRows() + local cols = self:getCols() + + -- rows + for y,row in ipairs(rows) do + local a = count(row, function (a) return a == BLUE end) + local b = count(row, function (a) return a == YELLOW end) + if a ~= b then + if a == width/2 then self:fillRow(y, YELLOW) end + if b == width/2 then self:fillRow(y, BLUE) end + end + end + + -- columns + for x,col in ipairs(cols) do + local a = count(col, function (a) return a == BLUE end) + local b = count(col, function (a) return a == YELLOW end) + if a ~= b then + if a == width/2 then self:fillCol(x, YELLOW) end + if b == width/2 then self:fillCol(x, BLUE) end + end + end + end, + + fillRow = function(self, y, color) + printh("Filling line " .. y .. " in " .. color == BLUE and "blue" or "yellow") + local idx = self:xy_idx(1, y) + for i = idx, (idx+width-1) do + if self:getTile(i) == 0 then + self:fill(i, color) + end + end + end, + + fillCol = function(self, x, color) + printh("Filling column " .. x .. " in " .. color == BLUE and "blue" or "yellow") + local idx = self:xy_idx(x, 1) + for i = idx, #tiles, width do + if self:getTile(i) == 0 then + self:fill(i, color) + end + end + end, + + noIdenticalLines = function(self) + end, + + draw = function(self) + for k,v in ipairs(tiles) do + local x,y = self:idx_xy(k) + local color = v == BLUE and 12 or v == YELLOW and 10 or 1 + rectfill((x-1)*10 + x*8 + 4, (y-1)*10 + y*8 + 4, 12, 12, color) + end + end + } +end + +-- +-- main loop +-- + +local board = Board.new() + +function _init() +end + +function _update() +end + +function _draw() + cls() + if time() % 1 == 0 then + board:solve() + end + board:draw() +end