forked from OpenPrograms/Sangar-Programs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
gol-tiny.lua
102 lines (96 loc) · 2.22 KB
/
gol-tiny.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
local component = require("component")
local event = require("event")
local keyboard = require("keyboard")
local term = require("term")
local unicode = require("unicode")
print("Left click: mark a cell as 'alive'.")
print("Right click: mark a cell as 'dead'.")
print("Space: toggle pause of the simulation.")
print("Q: exit the program.")
print("Press any key to begin.")
os.sleep(0.1)
event.pull("key")
local off = " "
local off2on = unicode.char(0x2593)
local on = unicode.char(0x2588)
local on2off = unicode.char(0x2592)
local gpu = component.gpu
local ow, oh = gpu.getResolution()
gpu.setResolution(27, 15)
local w, h = gpu.getResolution()
gpu.setBackground(0x000000)
gpu.setForeground(0xFFFFFF)
gpu.fill(1, 1, w, h, off)
local function isAlive(x, y)
x = (x + w - 1) % w + 1
y = (y + h - 1) % h + 1
local char = gpu.get(x, y)
return char == on or char == on2off
end
local function setAlive(x, y, alive)
if isAlive(x, y) == alive then
return
end
if alive then
gpu.set(x, y, off2on)
else
gpu.set(x, y, on2off)
end
end
local function flush()
for y = 1, h do
local row = ""
for x = 1, w do
row = row .. gpu.get(x, y)
end
local final = row:gsub(on2off, off):gsub(off2on, on)
if final ~= row then
gpu.set(1, y, final)
end
end
end
local function count(x, y)
local n = 0
for rx = -1, 1 do
local nx = x + rx
for ry = -1, 1 do
local ny = y + ry
if (rx ~= 0 or ry ~= 0) and isAlive(nx, ny) then
n = n + 1
end
end
end
return n
end
local function map(x, y)
local n = count(x, y)
return n == 2 and isAlive(x, y) or n == 3
end
local function step()
for y = 1, h do
for x = 1, w do
setAlive(x, y, map(x, y))
end
end
flush()
end
local running = false
while true do
local e = table.pack(event.pull(0.25))
if e[1] == "key_down" then
local _, _, _, code = table.unpack(e)
if code == keyboard.keys.space then
running = not running
elseif code == keyboard.keys.q then
gpu.setResolution(ow, oh)
term.clear()
return
end
elseif e[1] == "touch" then
local _, _, x, y, button = table.unpack(e)
gpu.set(x, y, button == 0 and on or off)
end
if running then
step()
end
end