-- based on -- https://github.com/healeYcodes/virtual-ants/blob/main/index.html require("util") local function round2even(num) return 2 * math.floor(num / 2) end local function rotate(direction, clockwise) local match if clockwise then match = { u = "r", r = "d", d = "l", l = "u", } else match = { u = "l", l = "d", d = "r", r = "u" } end return match[direction] end local function initColors(rules) rules = rules:lower() local colorbrewer = require("colorbrewer") local scheme = colorbrewer.random() local variant = scheme[#rules] COLORS = {} for i = 1, #rules do COLORS[i] = { clockwise = rules:sub(i, i) == "r", rgba = variant[i] } end end local function initScreen(width, height) love.window.setMode(width, height, { highdpi = true }) WIDTH, HEIGHT = round2even(width), round2even(height) CANVAS = love.graphics.newCanvas(WIDTH, HEIGHT) CANVAS:renderTo(function() local color = COLORS[1].rgba color[4] = 0.9 love.graphics.setColor(color) love.graphics.rectangle("fill", 0, 0, WIDTH, HEIGHT) end) UNITS = 8 end local function initAnt() ANT = { x = (WIDTH / 2) - ((WIDTH / 2) % UNITS), y = (HEIGHT / 2) - ((HEIGHT / 2) % UNITS), direction = "u", } end local function initGrid() GRID = {} GRID.mt = {} setmetatable(GRID, GRID.mt) GRID.mt.__index = function(table, key) table[key] = {} table[key].mt = {} setmetatable(table[key], table[key].mt) table[key].mt.__index = function(innerTable, innerKey) innerTable[innerKey] = 1 return innerTable[innerKey] end return table[key] end end function love.load(args) local width = args[1] or 800 local height = args[2] or 600 local rules = args[3] or "RL" initColors(rules) initScreen(width, height) initAnt() initGrid() end local function color(x, y) return GRID[x][y] end local function current() return color(ANT.x, ANT.y) end local function setCurrent(index) GRID[ANT.x][ANT.y] = index end local function updateCurrent() local val = current() if val == #COLORS then val = 1 else val = val + 1 end setCurrent(val) end local function nextColor() local c = COLORS[current()] updateCurrent() return c end function love.update() require("lurker").update() local c = nextColor() ANT.direction = rotate(ANT.direction, c.clockwise) CANVAS:renderTo(function() love.graphics.setBlendMode("alpha") love.graphics.setColor(c.rgba) love.graphics.rectangle("fill", ANT.x, ANT.y, UNITS, UNITS) end) if ANT.direction == "u" then ANT.y = ANT.y - UNITS elseif ANT.direction == "r" then ANT.x = ANT.x + UNITS elseif ANT.direction == "d" then ANT.y = ANT.y + UNITS else ANT.x = ANT.x - UNITS end if ANT.x >= WIDTH then ANT.x = 0 elseif ANT.x < 0 then ANT.x = (WIDTH - 1) - ((WIDTH - 1) % UNITS) end if ANT.y >= HEIGHT then ANT.y = 0 elseif ANT.y < 0 then ANT.y = (HEIGHT - 1) - ((HEIGHT - 1) % UNITS) end end function love.draw() love.graphics.setBlendMode("screen", "premultiplied") love.graphics.setColor(COLORS[1].rgba) love.graphics.draw(CANVAS, 0, 0) end