Ultima attività 1738990209

capitalex's Avatar capitalex ha revisionato questo gist 1738990209. Vai alla revisione

2 files changed, 322 insertions

main.lua(file creato)

@@ -0,0 +1,230 @@
1 + local PathBag = require "path-bag"
2 + local the_eye = require "the-eye"
3 + local pprint = require "pprint"
4 + -- knowledge base
5 + local kb = PathBag.new()
6 +
7 + for _, pixel in ipairs(the_eye) do
8 + kb:insert { "image", "eye", pixel[4], pixel[5], pixel[1], pixel[2], pixel[3] }
9 + end
10 +
11 + math.randomseed(os.time())
12 + local function uuid()
13 + local template ='xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'
14 + return string.gsub(template, '[xy]', function (c)
15 + local v = (c == 'x') and math.random(0, 0xf) or math.random(8, 0xb)
16 + return string.format('%x', v)
17 + end)
18 + end
19 +
20 + local function io_add(kb)
21 + local node, b = kb:get_and_bind {
22 + "@add", "eval", "$id", "$x", "$y"
23 + }
24 + if not node then return false end
25 +
26 + kb:remove_node(node)
27 + kb:insert { "@add", "success", b.id, b.x + b.y }
28 + return true
29 + end
30 +
31 + local function io_put_pixel(kb)
32 + local node, b = kb:get_and_bind {
33 + "@put", "pixel", "$r", "$g", "$b", "$x", "$y"
34 + }
35 + if not node then return false end
36 + kb:remove_node(node)
37 +
38 + love.graphics.setColor(b.r, b.g, b.b, 1.0)
39 + love.graphics.points(b.x, b.y)
40 + return true
41 + end
42 +
43 + local function put_pixel(kb)
44 + local put_pixel, b1 = kb:get_and_bind {
45 + "put", "pixel", "$r", "$g", "$b", "at", "$px_result", "$py_result"
46 + }
47 + if not put_pixel then return false end
48 +
49 + local px, b2 = kb:get_and_bind {
50 + "@add", "success", b1.px_result, "$px"
51 + }
52 + if not px then return false end
53 +
54 +
55 + local py, b3 = kb:get_and_bind {
56 + "@add", "success", b1.py_result, "$py"
57 + }
58 + if not py then return false end
59 +
60 + kb:remove_node(put_pixel)
61 + kb:remove_node(px)
62 + kb:remove_node(py)
63 +
64 + kb:insert { "@put", "pixel", b1.r, b1.g, b1.b, b2.px, b3.py }
65 + return true
66 + end
67 +
68 + local function next_cursor_down_1(kb)
69 + local next_cursor, b1 = kb:get_and_bind {
70 + "next", "cursor", "down", "$down_id"
71 + }
72 + if not next_cursor then return false end
73 +
74 + local add_success, b2 = kb:get_and_bind {
75 + "@add", "success", b1.down_id, "$cy"
76 + }
77 + if not add_success then return false end
78 +
79 + kb:remove_node(next_cursor)
80 + kb:remove_node(add_success)
81 +
82 + kb:insert { "cursor", 0, b2.cy }
83 + return true
84 + end
85 +
86 + local function next_cursor_right_1(kb)
87 + local next_cursor, b1 = kb:get_and_bind {
88 + "next", "cursor", "right", "$right_id", "$cy"
89 + }
90 + if not next_cursor then return false end
91 +
92 + local add_success, b2 = kb:get_and_bind {
93 + "@add", "success", b1.right_id, "$cx"
94 + }
95 + if not add_success then return false end
96 +
97 + kb:remove_node(next_cursor)
98 + kb:remove_node(add_success)
99 +
100 + kb:insert { "cursor", b2.cx, b1.cy }
101 + return true
102 + end
103 +
104 + local function draw_image_1(kb)
105 + local draw_image, b1 = kb:get_and_bind {
106 + "draw", "image", "$image", "$x", "$y"
107 + }
108 + if not draw_image then return end
109 +
110 + local cursor, b2 = kb:get_and_bind {
111 + "cursor", "$cx", "$cy"
112 + }
113 + if not cursor then return end
114 +
115 + local image, b3 = kb:get_and_bind {
116 + "image", "$image", b2.cx, b2.cy, "$r", "$g", "$b"
117 + }
118 + if not image then return end
119 +
120 + kb:remove_node(cursor)
121 +
122 + local px_id = uuid()
123 + local py_id = uuid()
124 +
125 + kb:insert { "put", "pixel", b3.r, b3.g, b3.b, "at", px_id, py_id }
126 + kb:insert { "advance", "cursor", b2.cx, b2.cy }
127 + kb:insert { "@add", "eval", px_id, b1.x, b2.cx }
128 + kb:insert { "@add", "eval", py_id, b1.y, b2.cy }
129 + return true
130 + end
131 +
132 + local function advance_cursor_1(kb)
133 + local node, b = kb:get_and_bind { "advance", "cursor", 249, 165 }
134 + if not node then return false end
135 +
136 + kb:remove_node(node)
137 + return true
138 + end
139 +
140 + local function advance_cursor_2(kb)
141 + local node, b = kb:get_and_bind { "advance", "cursor", 249, "$cy" }
142 + if not node then return false end
143 +
144 + kb:remove_node(node)
145 +
146 + local down_id = uuid()
147 + kb:insert { "next", "cursor", "down", down_id }
148 + kb:insert { "@add", "eval", down_id, 1, b.cy }
149 + return true
150 + end
151 +
152 + local function advance_cursor_3(kb)
153 + local node, b = kb:get_and_bind { "advance", "cursor", "$cx", "$cy" }
154 + if not node then return false end
155 +
156 +
157 + kb:remove_node(node)
158 +
159 + local right_id = uuid()
160 + kb:insert { "next", "cursor", "right", right_id, b.cy }
161 + kb:insert { "@add", "eval", right_id, 1, b.cx }
162 + return true
163 + end
164 +
165 + local function draw_image_2(kb)
166 + local node, b = kb:get_and_bind { "draw", "image", "$image", "$x", "$y" }
167 + if not node then return false end
168 +
169 + kb:remove_node(node)
170 +
171 + return true
172 + end
173 +
174 + local function tick(kb)
175 + local node, b = kb:get_and_bind { "tick", "$dt" }
176 + if not node then return false end
177 +
178 + kb:remove_node(node)
179 +
180 + kb:insert { "draw", "image", "eye", 0, 0 }
181 + kb:insert { "cursor", 0, 0 }
182 + return true
183 + end
184 +
185 + local rules =
186 + { io_add
187 + , io_put_pixel
188 + , put_pixel
189 + , next_cursor_down_1
190 + , next_cursor_right_1
191 + , draw_image_1
192 + , advance_cursor_1, advance_cursor_2, advance_cursor_3
193 + , draw_image_2
194 + , tick
195 + }
196 +
197 + local screen = love.graphics.newCanvas()
198 +
199 +
200 + function love.draw()
201 + love.graphics.setColor(1, 1, 1)
202 + love.graphics.draw(screen, 0, 0)
203 + love.graphics.setColor(1, 0, 0)
204 + love.graphics.print(tostring(love.timer.getFPS()) .. " fps", 0, 0)
205 + end
206 +
207 + function love.update(dt)
208 + local dt_fact = tostring(dt)
209 + local now = os.time()
210 + love.graphics.setCanvas(screen)
211 + love.graphics.clear(0, 0, 0, 0)
212 + kb:insert { "tick", dt }
213 + local rewrite = true
214 + -- pprint("--- START ---")
215 + -- pprint(kb)
216 + while rewrite do
217 + rewrite = false
218 + for i, rule in ipairs(rules) do
219 + if rule(kb) then
220 + -- print("--- MATCH ---")
221 + -- pprint(kb)
222 + rewrite = true
223 + break
224 + end
225 + end
226 + end
227 + love.graphics.setCanvas()
228 + local later = os.time()
229 + print(later - now)
230 + end

path-bag.lua(file creato)

@@ -0,0 +1,92 @@
1 + love = love or {}
2 + local pprint = require "pprint"
3 +
4 + --[[
5 + If you are familiar with jargon, then a "path bag" is
6 + a muliset that is implemented as a prefix tree.
7 +
8 + this is a path
9 + this is another path
10 + this is a final path
11 + this is a path
12 + |
13 + V
14 + this <-> is <-> a <-> path {2}
15 + | |
16 + | + <-> final path {1}
17 + |
18 + + <-> another <-> path {1}
19 + --]]
20 + local PathBag = {}
21 + PathBag.__mt = {}
22 +
23 + function PathBag.new()
24 + local obj = { root = {children = {}, child_count = 0, count = 0} }
25 + return setmetatable(obj, {__index = PathBag.__mt})
26 + end
27 +
28 + function PathBag.__mt:insert(path)
29 + local root = self.root
30 + for _, step in ipairs(path) do
31 + if not root.children[step] then
32 + root.children[step] = { value = step, children = {}, child_count = 0, count = 0, parent = root }
33 + root.child_count = root.child_count + 1
34 + end
35 + root = root.children[step]
36 + end
37 + root.count = root.count + 1
38 + end
39 +
40 + function PathBag.__mt:get(path)
41 + local root = self.root
42 + for _, step in ipairs(path) do
43 + if step == "*" then
44 + _, root = next(root.children)
45 + if not root then return end
46 + elseif not root.children[step] then
47 + return nil
48 + else
49 + root = root.children[step]
50 + end
51 + end
52 +
53 + return root.count ~= 0 and root or nil
54 + end
55 +
56 + function PathBag.__mt:remove_node(node)
57 + local leaf = node
58 + while leaf.parent do
59 + leaf.count = leaf.count - 1
60 + if leaf.count <= 0 and leaf.child_count <= 0 then
61 + local path = leaf.value
62 + leaf = leaf.parent
63 + leaf.children[path] = nil
64 + leaf.child_count = leaf.child_count - 1
65 + else
66 + return
67 + end
68 + end
69 + end
70 +
71 + function PathBag.__mt:get_and_bind(path)
72 + local bindings, root = {}, self.root
73 + for _, step in ipairs(path) do
74 + if type(step) == "string" and step:find("^%$") then
75 + key, root = next(root.children)
76 + if not root then return end
77 + bindings[step:sub(2)] = key
78 + elseif not root.children[step] then
79 + return nil
80 + else
81 + root = root.children[step]
82 + end
83 + end
84 +
85 + if root.count ~= 0 then
86 + return root, bindings
87 + end
88 + end
89 +
90 +
91 +
92 + return PathBag
Più nuovi Più vecchi