capitalex a révisé ce gist . Aller à la révision
3 files changed, 272 insertions
deque.lua(fichier créé)
@@ -0,0 +1,55 @@ | |||
1 | + | local Deque = {} | |
2 | + | Deque.__mt = {} | |
3 | + | ||
4 | + | function Deque.new() | |
5 | + | local obj = | |
6 | + | { first = 1 | |
7 | + | , last = 0 | |
8 | + | , size = 0 | |
9 | + | } | |
10 | + | return setmetatable(obj, {__index = Deque.__mt}) | |
11 | + | end | |
12 | + | ||
13 | + | function Deque.__mt:right() | |
14 | + | return self[self.last] | |
15 | + | end | |
16 | + | ||
17 | + | function Deque.__mt:left() | |
18 | + | return self[self.first] | |
19 | + | end | |
20 | + | ||
21 | + | function Deque.__mt:push_left(value) | |
22 | + | local first = self.first - 1 | |
23 | + | self.first = first | |
24 | + | self[first] = value | |
25 | + | self.size = self.size + 1 | |
26 | + | end | |
27 | + | ||
28 | + | function Deque.__mt:push_right(value) | |
29 | + | local last = self.last + 1 | |
30 | + | self.last = last | |
31 | + | self[last] = value | |
32 | + | self.size = self.size + 1 | |
33 | + | end | |
34 | + | ||
35 | + | function Deque.__mt:pop_left() | |
36 | + | local first = self.first | |
37 | + | if self.size == 0 then error("deque is empty") end | |
38 | + | local value = self[first] | |
39 | + | self[first] = nil | |
40 | + | self.first = first + 1 | |
41 | + | self.size = self.size - 1 | |
42 | + | return value | |
43 | + | end | |
44 | + | ||
45 | + | function Deque.__mt:pop_right() | |
46 | + | local last = self.last | |
47 | + | if self.size == 0 then error("deque is empty") end | |
48 | + | local value = self[last] | |
49 | + | self[last] = nil | |
50 | + | self.last = last - 1 | |
51 | + | self.size = self.size - 1 | |
52 | + | return value | |
53 | + | end | |
54 | + | ||
55 | + | return Deque |
main.lua(fichier créé)
@@ -0,0 +1,182 @@ | |||
1 | + | local pprint = require "pprint" | |
2 | + | local QueueMap = require "queue-map" | |
3 | + | local the_eye = require "the-eye" | |
4 | + | ||
5 | + | -- knowledge base | |
6 | + | local kb = QueueMap.new() | |
7 | + | ||
8 | + | for _, pixel in ipairs(the_eye) do | |
9 | + | kb:enqueue("image $image $x $y $r $g $b", {"eye", pixel[4], pixel[5], pixel[1], pixel[2], pixel[3]}) | |
10 | + | end | |
11 | + | ||
12 | + | local function io_add(kb) | |
13 | + | local tuple = kb:peek "@add" | |
14 | + | if not tuple then return false end | |
15 | + | ||
16 | + | kb:poll "@add" | |
17 | + | kb:enqueue(tuple[1], tuple[2] + tuple[3]) | |
18 | + | return true | |
19 | + | end | |
20 | + | ||
21 | + | local function io_put_pixel(kb) | |
22 | + | local tuple = kb:peek "@put pixel $r $g $b $x $y" | |
23 | + | if not tuple then return false end | |
24 | + | kb:poll "@put pixel $r $g $b $x $y" | |
25 | + | ||
26 | + | love.graphics.setColor(tuple[1] / 255, tuple[2] / 255, tuple[3] / 255, 1.0) | |
27 | + | love.graphics.points(tuple[4], tuple[5]) | |
28 | + | return true | |
29 | + | end | |
30 | + | ||
31 | + | local function put_pixel(kb) | |
32 | + | local put_pixel = kb:peek "put pixel $r $g $b" | |
33 | + | if not put_pixel then return false end | |
34 | + | ||
35 | + | local px = kb:peek "pixel x is $x" | |
36 | + | if not px then return false end | |
37 | + | ||
38 | + | ||
39 | + | local py = kb:peek "pixel y is $y" | |
40 | + | if not py then return false end | |
41 | + | ||
42 | + | kb:poll "put pixel $r $g $b" | |
43 | + | kb:poll "pixel x is $x" | |
44 | + | kb:poll "pixel y is $y" | |
45 | + | ||
46 | + | kb:enqueue("@put pixel $r $g $b $x $y", { put_pixel[1], put_pixel[2], put_pixel[3], px, py }) | |
47 | + | return true | |
48 | + | end | |
49 | + | ||
50 | + | local function next_cursor(kb) | |
51 | + | local cx = kb:peek "next cursor x is $x" | |
52 | + | if not cx then return false end | |
53 | + | ||
54 | + | local cy = kb:peek "next cursor y is $y" | |
55 | + | if not cy then return false end | |
56 | + | ||
57 | + | kb:poll "next cursor x is $x" | |
58 | + | kb:poll "next cursor y is $y" | |
59 | + | ||
60 | + | kb:enqueue("cursor $x $y", {cx, cy}) | |
61 | + | end | |
62 | + | ||
63 | + | local function draw_image_1(kb) | |
64 | + | local draw_image = kb:peek "draw image $image $x $y" | |
65 | + | if not draw_image then return end | |
66 | + | ||
67 | + | local cursor = kb:peek "cursor $x $y" | |
68 | + | if not cursor then return end | |
69 | + | ||
70 | + | local image = kb:peek "image $image $x $y $r $g $b" | |
71 | + | if not image then return end | |
72 | + | ||
73 | + | kb:poll "draw image $image $x $y" | |
74 | + | kb:poll "cursor $x $y" | |
75 | + | kb:poll "image $image $x $y $r $g $b" | |
76 | + | ||
77 | + | kb:enqueue("put pixel $r $g $b", {image[4], image[5], image[6]}) | |
78 | + | kb:enqueue("advance cursor $x $y", {cursor[1], cursor[2]}) | |
79 | + | kb:enqueue("@add", {"pixel x is $x", draw_image[2], image[2]}) | |
80 | + | kb:enqueue("@add", {"pixel y is $y", draw_image[3], image[3]}) | |
81 | + | kb:enqueue("next draw $image $x $y", draw_image) | |
82 | + | kb:enqueue("image $image $x $y $r $g $b", image) | |
83 | + | return true | |
84 | + | end | |
85 | + | ||
86 | + | local function advance_cursor_1(kb) | |
87 | + | local tuple = kb:peek "advance cursor $x $y" | |
88 | + | if not tuple or tuple[1] ~= 249 or tuple[2] ~= 165 then return false end | |
89 | + | ||
90 | + | kb:poll "advance cursor $x $y" | |
91 | + | return true | |
92 | + | end | |
93 | + | ||
94 | + | local function advance_cursor_2(kb) | |
95 | + | local advance = kb:peek "advance cursor $x $y" | |
96 | + | if not advance or advance[1] ~= 249 then return false end | |
97 | + | ||
98 | + | local next_draw_image = kb:peek "next draw $image $x $y" | |
99 | + | if not next_draw_image then return false end | |
100 | + | ||
101 | + | kb:poll "advance cursor $x $y" | |
102 | + | kb:poll "next draw $image $x $y" | |
103 | + | ||
104 | + | kb:enqueue("draw image $image $x $y", next_draw_image) | |
105 | + | kb:enqueue("next cursor x is $x", 0) | |
106 | + | kb:enqueue("@add", {"next cursor y is $y", 1, advance[2]}) | |
107 | + | return true | |
108 | + | end | |
109 | + | ||
110 | + | local function advance_cursor_3(kb) | |
111 | + | local tuple = kb:peek "advance cursor $x $y" | |
112 | + | if not tuple then return false end | |
113 | + | ||
114 | + | local next_draw_image = kb:peek "next draw $image $x $y" | |
115 | + | if not next_draw_image then return false end | |
116 | + | ||
117 | + | kb:poll "advance cursor $x $y" | |
118 | + | kb:poll "next draw $image $x $y" | |
119 | + | ||
120 | + | kb:enqueue("draw image $image $x $y", next_draw_image) | |
121 | + | kb:enqueue("@add", {"next cursor x is $x", 1, tuple[1]}) | |
122 | + | kb:enqueue("next cursor y is $y", tuple[2]) | |
123 | + | return true | |
124 | + | end | |
125 | + | ||
126 | + | local function draw_image_2(kb) | |
127 | + | local tuple = kb:peek "draw image $image $x $y" | |
128 | + | if not tuple then return false end | |
129 | + | ||
130 | + | kb:poll "draw image $image $x $y" | |
131 | + | return true | |
132 | + | end | |
133 | + | ||
134 | + | local function tick(kb) | |
135 | + | local tuple = kb:peek "tick $dt" | |
136 | + | if not tuple then return false end | |
137 | + | ||
138 | + | kb:poll "tick $dt" | |
139 | + | ||
140 | + | kb:enqueue("draw image $image $x $y", {"eye", 0, 0}) | |
141 | + | kb:enqueue("cursor $x $y", {0, 0}) | |
142 | + | return true | |
143 | + | end | |
144 | + | ||
145 | + | local rules = | |
146 | + | { io_add | |
147 | + | , io_put_pixel | |
148 | + | , put_pixel | |
149 | + | , next_cursor | |
150 | + | , draw_image_1 | |
151 | + | , advance_cursor_1, advance_cursor_2, advance_cursor_3 | |
152 | + | , draw_image_2 | |
153 | + | , tick | |
154 | + | } | |
155 | + | ||
156 | + | local screen = love.graphics.newCanvas() | |
157 | + | ||
158 | + | ||
159 | + | function love.draw() | |
160 | + | love.graphics.setColor(1, 1, 1) | |
161 | + | love.graphics.draw(screen, 0, 0) | |
162 | + | love.graphics.setColor(1, 0, 0) | |
163 | + | love.graphics.print(tostring(love.timer.getFPS()) .. " fps", 0, 0) | |
164 | + | end | |
165 | + | ||
166 | + | function love.update(dt) | |
167 | + | local dt_fact = tostring(dt) | |
168 | + | love.graphics.setCanvas(screen) | |
169 | + | love.graphics.clear(0, 0, 0, 0) | |
170 | + | kb:enqueue("tick $dt", dt) | |
171 | + | local rewrite = true | |
172 | + | while rewrite do | |
173 | + | rewrite = false | |
174 | + | for i, rule in ipairs(rules) do | |
175 | + | if rule(kb) then | |
176 | + | rewrite = true | |
177 | + | break | |
178 | + | end | |
179 | + | end | |
180 | + | end | |
181 | + | love.graphics.setCanvas() | |
182 | + | end |
queue-map.lua(fichier créé)
@@ -0,0 +1,35 @@ | |||
1 | + | local Deque = require "deque" | |
2 | + | ||
3 | + | local QueueMap = {} | |
4 | + | QueueMap.__mt = {} | |
5 | + | ||
6 | + | function QueueMap.new() | |
7 | + | local obj = { | |
8 | + | queues = {} | |
9 | + | } | |
10 | + | print(QueueMap.__mt.enqueue) | |
11 | + | return setmetatable(obj, {__index = QueueMap.__mt}) | |
12 | + | end | |
13 | + | ||
14 | + | function QueueMap.__mt:peek(where) | |
15 | + | if self.queues[where] then | |
16 | + | return self.queues[where]:left() | |
17 | + | end | |
18 | + | end | |
19 | + | ||
20 | + | ||
21 | + | function QueueMap.__mt:poll(where) | |
22 | + | if self.queues[where] then | |
23 | + | self.queues[where]:pop_left() | |
24 | + | end | |
25 | + | end | |
26 | + | ||
27 | + | function QueueMap.__mt:enqueue(where, what) | |
28 | + | if not self.queues[where] then | |
29 | + | self.queues[where] = Deque.new() | |
30 | + | end | |
31 | + | self.queues[where]:push_right(what) | |
32 | + | end | |
33 | + | ||
34 | + | ||
35 | + | return QueueMap |