diff --git a/ants/main.lua b/ants/main.lua index ed2769b..7b668d1 100644 --- a/ants/main.lua +++ b/ants/main.lua @@ -4,10 +4,6 @@ require("util") -local function round2even(num) - return 2 * math.floor(num / 2) -end - local function rotate(direction, clockwise) local match if clockwise then @@ -31,8 +27,6 @@ end local function initColors(rules) rules = rules:lower() local colorbrewer = require("colorbrewer") - -- set a specific random seed to avoid picking the same palette every time - math.randomseed(os.time()) local scheme = colorbrewer.random(#rules) COLORS = {} for i, color in pairs(scheme) do @@ -133,7 +127,7 @@ local function nextColor(ant) return c end -function love.mousepressed(x, y, _, _) +function love.mousepressed(x, y) spawnAnt(x, y) end diff --git a/colorbrewer.lua b/colorbrewer.lua index 1a6f32e..cf161bf 100644 --- a/colorbrewer.lua +++ b/colorbrewer.lua @@ -525,4 +525,6 @@ function colorbrewer.random(length) return scheme[length] end +-- set a specific random seed to avoid picking the same palette every time +math.randomseed(os.time()) return colorbrewer diff --git a/life/conf.lua b/life/conf.lua new file mode 100644 index 0000000..3655b64 --- /dev/null +++ b/life/conf.lua @@ -0,0 +1,5 @@ +function love.conf(t) + t.window.highdpi = true + t.window.vsync = true + t.window.title = "life" +end diff --git a/life/main.lua b/life/main.lua new file mode 100644 index 0000000..39b8c60 --- /dev/null +++ b/life/main.lua @@ -0,0 +1,183 @@ +require("util") + +local function initRules(pattern) + local b, s = pattern:match("B(.+)/S(.+)") + B = {} + for c in b:gmatch(".") do + B[tonumber(c)] = true + end + S = {} + for c in s:gmatch(".") do + S[tonumber(c)] = true + end +end + +local function initColors() + local colorbrewer = require("colorbrewer") + local scheme = colorbrewer.random(2) + ON = scheme[1] + OFF = scheme[2] +end + +local function initScreen() + local width, height = love.graphics.getDimensions() + WIDTH, HEIGHT = round2even(width), round2even(height) + love.graphics.setBackgroundColor(OFF[1], OFF[2], OFF[3], 0.9) +end + +local function initFont() + FONT = love.graphics.newFont(16) + love.graphics.setFont(FONT) + FPS_WIDTH = FONT:getWidth("120 FPS") + FPS_HEIGHT = FONT:getHeight() +end + +local function initGrid() + GRID = {} + GRID.mt = {} + setmetatable(GRID, GRID.mt) + GRID.mt.__index = function(table, key) + table[key] = {} + return table[key] + end +end + +local function cloneGrid() + local grid = {} + for x, v in pairs(GRID) do + grid[x] = {} + for y, set in pairs(v) do + grid[x][y] = set + end + end + setmetatable(grid, grid.mt) + return grid +end + +local function drawGlider(x, y) + GRID[x][y] = true + x = x + UNITS + y = y + UNITS + GRID[x][y] = true + x = x + UNITS + GRID[x][y] = true + y = y - UNITS + GRID[x][y] = true + y = y - UNITS + GRID[x][y] = true +end + +function love.load(args) + local pattern = args[1] or "B3/S23" + UNITS = args[2] or 8 + STEPS_PER_FRAME = args[3] or 1 + DRAGGING = false + initRules(pattern) + initColors() + initScreen() + initFont() + initGrid() + drawGlider(80, 80) +end + +local function wrap(n, high) + n = n % high + if n < 0 then + n = n + high + end + return n +end + +local function neighbors(x, y) + local lowX = x - UNITS + local highX = x + UNITS + local lowY = y - UNITS + local highY = y + UNITS + local count = 0 + for i = lowX, highX do + for j = lowY, highY do + i = wrap(i, WIDTH) + j = wrap(j, HEIGHT) + if (i ~= x or j ~= y) and GRID[i][j] then + count = count + 1 + end + end + end + return count +end + +function love.mousepressed(x, y, button) + if button == 1 then + DRAGGING = true + elseif button == 2 then + x = (x - (x % UNITS)) + y = (y - (y % UNITS)) + drawGlider(x, y) + end +end + +function love.mousereleased() + DRAGGING = false +end + +function love.mousemoved(x, y) + if DRAGGING then + x = (x - (x % UNITS)) + y = (y - (y % UNITS)) + GRID[x][y] = true + end +end + +FRAMELOCK_COUNTER = 0 +FRAMELOCK_FPS = 30 +function love.update(dt) + require("lurker").update() + FRAMELOCK_COUNTER = FRAMELOCK_COUNTER + dt + if FRAMELOCK_COUNTER < (1 / FRAMELOCK_FPS) then + return + end + FRAMELOCK_COUNTER = 0 + for _ = 1, STEPS_PER_FRAME do + local grid = cloneGrid() + for x = 0, WIDTH, UNITS do + for y = 0, HEIGHT, UNITS do + local current = GRID[x][y] + local n = neighbors(x, y) + if current then + if not S[n] then + grid[x][y] = false + end + else + if B[n] then + grid[x][y] = true + end + end + end + end + GRID = grid + end +end + +local function paintFPS() + local fps = tostring(love.timer.getFPS()) .. " FPS" + love.graphics.setColor(ON) + love.graphics.rectangle("fill", WIDTH - FPS_WIDTH - 10, HEIGHT - FPS_HEIGHT - 20, FPS_WIDTH + 30, FPS_HEIGHT + 10, 5, 5) + love.graphics.setColor(OFF) + love.graphics.print(fps, WIDTH - FPS_WIDTH - 5, HEIGHT - FPS_HEIGHT - 15) +end + +function love.draw() + for x, v in pairs(GRID) do + if x ~= "mt" then + for y, on in pairs(v) do + if on then + love.graphics.setColor(ON) + else + love.graphics.setColor(OFF) + end + love.graphics.rectangle("fill", x, y, UNITS, UNITS) + end + end + end + paintFPS() +end diff --git a/util.lua b/util.lua index f384f8c..7141a30 100644 --- a/util.lua +++ b/util.lua @@ -18,4 +18,6 @@ function printt(t, prefix, maxdepth) end end -color = require("colorbrewer") +function round2even(num) + return 2 * math.floor(num / 2) +end