Download
89 lines 1.9 KiBLuaModified 2026-04-05 raw
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889

local btui = require("btui")

local W, H

local screen = {}
local function draw(bt, cells)
    for y = 1,H do
        for x = 1,W do
            local alive = cells[x][y]
            local key = tostring(x)..","..tostring(y)
            if screen[key] ~= alive then
                bt:move((x-1)*2, y-1)
                bt:withbg(alive, alive, alive, function()
                    bt:write("  ")
                end)
                screen[key] = alive
            end
        end
    end
end

local function get(cells, x, y)
    x = ((x-1)%W) + 1 
    y = ((y-1)%H) + 1 
    return cells[x][y]
end

local function count_neighbors(cells, x, y)
    local n = 0
    for dx=-1,1 do
        for dy=-1,1 do
            if dx ~= 0 or dy ~= 0 then
                n = n + get(cells, x+dx, y+dy)
            end
        end
    end
    return n
end

local function update(cells)
    local new = {}
    for x = 1,W do
        new[x] = {}
        for y = 1,H do
            local n = count_neighbors(cells, x, y)
            if (get(cells, x, y) == 0 and n == 3) or (get(cells, x, y) == 1 and (n == 2 or n == 3)) then
                new[x][y] = 1
            else
                new[x][y] = 0
            end
        end
    end
    return new
end

btui(function(bt)
    W = bt:width()
    H = bt:height()

    local cells = {}
    for x = 1,W do
        cells[x] = {}
        for y = 1,H do
            cells[x][y] = 0
        end
    end

    local key = nil
    local paused = false
    while key ~= "q" and key ~= "Ctrl-c" do
        draw(bt, cells)
        if not paused then
            cells = update(cells)
        end

        local mouse_x, mouse_y
        key, mouse_x, mouse_y = bt:getkey(1)
        if mouse_x and mouse_y then
            cells[math.floor(mouse_x/2)][mouse_y] = 1
            paused = true
        else
            paused = false
        end
    end
    if key == "Ctrl-c" then
        error("Interrupt received!")
    end
end)