Add wireworld!
parent
212948b1c4
commit
1ffa545f60
|
@ -80,14 +80,6 @@ function love.load(args)
|
||||||
drawGlider(80, 80)
|
drawGlider(80, 80)
|
||||||
end
|
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 function neighbors(x, y)
|
||||||
local lowX = x - UNITS
|
local lowX = x - UNITS
|
||||||
local highX = x + UNITS
|
local highX = x + UNITS
|
||||||
|
|
8
util.lua
8
util.lua
|
@ -21,3 +21,11 @@ end
|
||||||
function round2even(num)
|
function round2even(num)
|
||||||
return 2 * math.floor(num / 2)
|
return 2 * math.floor(num / 2)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function wrap(n, high)
|
||||||
|
n = n % high
|
||||||
|
if n < 0 then
|
||||||
|
n = n + high
|
||||||
|
end
|
||||||
|
return n
|
||||||
|
end
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
function love.conf(t)
|
||||||
|
t.window.highdpi = true
|
||||||
|
t.window.vsync = true
|
||||||
|
t.window.title = "wireworld"
|
||||||
|
end
|
|
@ -0,0 +1,222 @@
|
||||||
|
require "util"
|
||||||
|
|
||||||
|
local function initColors()
|
||||||
|
local colorbrewer = require("colorbrewer")
|
||||||
|
COLORS = colorbrewer.random(4)
|
||||||
|
BLACK = { 0, 0, 0, 1 }
|
||||||
|
end
|
||||||
|
|
||||||
|
local function initScreen()
|
||||||
|
local width, height = love.graphics.getDimensions()
|
||||||
|
WIDTH, HEIGHT = round2even(width), round2even(height)
|
||||||
|
local color = COLORS[#COLORS]
|
||||||
|
color[4] = 0.9
|
||||||
|
love.graphics.setBackgroundColor(color)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function initFont()
|
||||||
|
FONT = love.graphics.newFont(16)
|
||||||
|
love.graphics.setFont(FONT)
|
||||||
|
FONT_HEIGHT = FONT:getHeight()
|
||||||
|
PLAYING_WIDTH = FONT:getWidth("playing")
|
||||||
|
PAUSED_WIDTH = FONT:getWidth("paused")
|
||||||
|
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
|
||||||
|
|
||||||
|
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
|
||||||
|
setmetatable(grid[x], grid[x].mt)
|
||||||
|
end
|
||||||
|
setmetatable(grid, grid.mt)
|
||||||
|
return grid
|
||||||
|
end
|
||||||
|
|
||||||
|
function love.load(args)
|
||||||
|
UNITS = args[1] or 16
|
||||||
|
STEPS_PER_FRAME = args[2] or 1
|
||||||
|
PAUSED = false
|
||||||
|
initColors()
|
||||||
|
initScreen()
|
||||||
|
initFont()
|
||||||
|
initGrid()
|
||||||
|
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] == 2 then
|
||||||
|
count = count + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return count
|
||||||
|
end
|
||||||
|
|
||||||
|
local function clear(grid, x, y)
|
||||||
|
grid[x][y] = 1
|
||||||
|
end
|
||||||
|
|
||||||
|
local function setHead(grid, x, y)
|
||||||
|
grid[x][y] = 2
|
||||||
|
end
|
||||||
|
|
||||||
|
local function setTail(grid, x, y)
|
||||||
|
grid[x][y] = 3
|
||||||
|
end
|
||||||
|
|
||||||
|
local function setConductor(grid, x, y)
|
||||||
|
grid[x][y] = 4
|
||||||
|
end
|
||||||
|
|
||||||
|
local function setSpark(grid, x, y)
|
||||||
|
local n = neighbors(x, y)
|
||||||
|
if n == 1 or n == 2 then
|
||||||
|
setHead(grid, x, y)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function updater(state)
|
||||||
|
local match = {
|
||||||
|
-- noop
|
||||||
|
[1] = function(x, y) end,
|
||||||
|
[2] = setTail,
|
||||||
|
[3] = setConductor,
|
||||||
|
[4] = setSpark,
|
||||||
|
}
|
||||||
|
return match[state]
|
||||||
|
end
|
||||||
|
|
||||||
|
local function stepCell(grid, x, y)
|
||||||
|
local state = GRID[x][y]
|
||||||
|
local update = updater(state)
|
||||||
|
update(grid, x, y)
|
||||||
|
end
|
||||||
|
|
||||||
|
function love.keypressed(key, _, isrepeat)
|
||||||
|
if key == "space" and not isrepeat then
|
||||||
|
PAUSED = not PAUSED
|
||||||
|
if PAUSED then
|
||||||
|
print("pausing")
|
||||||
|
else
|
||||||
|
print("unpausing")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function love.mousepressed(x, y, button)
|
||||||
|
x = (x - (x % UNITS))
|
||||||
|
y = (y - (y % UNITS))
|
||||||
|
local state = GRID[x][y]
|
||||||
|
if button == 1 then
|
||||||
|
if state == 1 then
|
||||||
|
print("setting conductor")
|
||||||
|
setConductor(GRID, x, y)
|
||||||
|
else
|
||||||
|
print("clearing")
|
||||||
|
clear(GRID, x, y)
|
||||||
|
end
|
||||||
|
elseif button == 2 then
|
||||||
|
if state == 4 then
|
||||||
|
print("setting head")
|
||||||
|
setHead(GRID, x, y)
|
||||||
|
elseif state == 2 then
|
||||||
|
print("setting conductor")
|
||||||
|
setConductor(GRID, x, y)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
FRAMELOCK_COUNTER = 0
|
||||||
|
FRAMELOCK_FPS = 10
|
||||||
|
function love.update(dt)
|
||||||
|
pcall(function()
|
||||||
|
require("lurker").update()
|
||||||
|
end)
|
||||||
|
if not PAUSED then
|
||||||
|
FRAMELOCK_COUNTER = FRAMELOCK_COUNTER + dt
|
||||||
|
if FRAMELOCK_COUNTER < (1 / FRAMELOCK_FPS) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
FRAMELOCK_COUNTER = 0
|
||||||
|
local grid = cloneGrid()
|
||||||
|
for x = 0, WIDTH, UNITS do
|
||||||
|
for y = 0, HEIGHT, UNITS do
|
||||||
|
local state = GRID[x][y]
|
||||||
|
if state ~= 1 then
|
||||||
|
stepCell(grid, x, y)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
GRID = grid
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function paintPlayPause()
|
||||||
|
local status, width
|
||||||
|
if PAUSED then
|
||||||
|
status, width = "paused", PAUSED_WIDTH
|
||||||
|
else
|
||||||
|
status, width = "playing", PLAYING_WIDTH
|
||||||
|
end
|
||||||
|
love.graphics.setColor(COLORS[1])
|
||||||
|
love.graphics.rectangle("fill", -10, HEIGHT - FONT_HEIGHT - 20, width + 30, FONT_HEIGHT + 10, 5, 5)
|
||||||
|
love.graphics.setColor(BLACK)
|
||||||
|
love.graphics.print(status, 10, HEIGHT - FONT_HEIGHT - 15)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function paintFPS()
|
||||||
|
local fps = tostring(love.timer.getFPS()) .. " FPS"
|
||||||
|
local width = FONT:getWidth(fps)
|
||||||
|
love.graphics.setColor(COLORS[1])
|
||||||
|
love.graphics.rectangle("fill", WIDTH - width - 10, HEIGHT - FONT_HEIGHT - 20, width + 30, FONT_HEIGHT + 10,
|
||||||
|
5, 5)
|
||||||
|
love.graphics.setColor(BLACK)
|
||||||
|
love.graphics.print(fps, WIDTH - width - 5, HEIGHT - FONT_HEIGHT - 15)
|
||||||
|
end
|
||||||
|
|
||||||
|
function love.draw()
|
||||||
|
for x, v in pairs(GRID) do
|
||||||
|
if x ~= "mt" then
|
||||||
|
for y, state in pairs(v) do
|
||||||
|
if y ~= "mt" then
|
||||||
|
local color = COLORS[#COLORS - state + 1]
|
||||||
|
love.graphics.setColor(color)
|
||||||
|
love.graphics.rectangle("fill", x, y, UNITS, UNITS)
|
||||||
|
if state ~= 1 then
|
||||||
|
love.graphics.setColor(BLACK)
|
||||||
|
love.graphics.rectangle("line", x, y, UNITS, UNITS)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
paintFPS()
|
||||||
|
paintPlayPause()
|
||||||
|
end
|
Loading…
Reference in New Issue