File: heisenburp.lua

package info (click to toggle)
golly 3.3-1.1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 20,176 kB
  • sloc: cpp: 72,638; ansic: 25,919; python: 7,921; sh: 4,245; objc: 3,721; java: 2,781; xml: 1,362; makefile: 530; javascript: 279; perl: 69
file content (477 lines) | stat: -rwxr-xr-x 25,165 bytes parent folder | download | duplicates (3)
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
-- Stable pseudo-Heisenburp device.
-- Show several views of a multi-stage signal-processing circuit.
-- Author: Dave Greene, 27 February 2007.  Lua version 1 April 2016.

local g = golly()
local gp = require "gplus"
local split = gp.split

local clock = os.clock
local ticks=0
local tickstep=5
local last_signal=-99999
local viewport_speed=16
local sel_speed=0
local delta_sel=0
local delay=-1
local run_flag=0
local ch=""
local selx=600
local sely=365
local place_signal=3
local helpstring=[[
Use ENTER and SPACE to run or halt the pattern;
use + and - to change the step size or delay value;
use arrow keys and mouse tools to pan and zoom in any pane;
T toggles between a tiled view and a single-pane view;
S creates another signal fleet near the detection mechanism;
R resets the Heisenburp device to its initial state;
Q quits out of the script and restores original settings.]]
local instr="Press H for help. "

-------------------------------------------------------

local function sleep(n) -- n is seconds (with precision in hundredths of a second)
    local t0 = clock()
    while clock() - t0 <= n do
        g.doevent("")   -- no-op, but allows user to abort script here
    end
end

-------------------------------------------------------

local function show_status_text(s, d, t)
    if d==-1 then
        if t==1 then g.show(s.."Speed is "..t.." tick per step.")
        else g.show(s.."Speed is "..t.." ticks per step.")
        end
    else g.show(s.."Delay between ticks is "..d.." seconds.")
    end
end

-------------------------------------------------------

local function prepare_burp()
    while g.numlayers()>1 do g.dellayer() end
    local highway_robber=g.parse([[143bo$143b3o$146bo$145b2o2$126bo42bo$126b3o38b3o$129bo36bo$128b2o11b2o
    23b2o7b2o$141b2o32bo$108bo64bobo$108b3o6b2o54b2o$111bo5b2o$110b2o3$
    111b2o$111b2o3b2o$116b2o35b2o23bo$154bo22bobo$151b3o8b2o14bo$151bo11bo
    $98bo7bo53b3o$86bo11b3o5b3o51bo$84b3o14bo7bo32b2o$68bo14bo16b2o6b2o32b
    obo30b2o$68b3o12b2o59bo30bobo$71bo72b2o31bo$70b2o105b2o$159bob2o$159b
    2obo$71b2o$71b2o17b2o76b2o$90b2o76b2o5$104b2o$87b2o14bobo$87bo15bo74b
    2o$88b3o11b2o74bo$90bo85bobo$84b2o90b2o$84bo$85b3o$87bo2$158b2o$159bo$
    68b2o89bobo$67bobo90b2o$67bo25b2o$66b2o25bo$74b2o15bobo$74b2o15b2o98b
    2o6bo$187bobo2bo4b3o$185b3ob2o5bo$184bo11b2o$185b3ob2o$177b2o8bob2o$
    177b2o2$161b2o32b2o3b2o$161b2o32b2o3b2o$153b2o$88b2o2b2ob2o57bo18b2ob
    2o$73b2o13bobo2bobo58bobo16b2obo$72bobo16b2o3bo58b2o21bo26bo$72bo19bob
    2o76bob5o25bobo$71b2o16bo2bobo77b2o31bo$88bobobobo80b2o$89b2ob2o82bo$
    173b3o$173bo33bo$171bobo31b3o$171b2o31bo$187b2o14bobo$187b2o15bo$83b2o
    $83b2o$202b2o$202b2o2$175b2o$175b2o$72b2o123b2o$73bo19b2o102bo$73bobo
    17bo76b2o26b3o$74b2o15bobo60b2o14b2o28bo$86bo4b2o62bo$85bobo64b3o$54bo
    30bobo64bo$54b3o17b2o10bo$57bo15bobo$56b2o15bo116b2o$72b2o116bo$36b2o
    49b2o102b3o$29b2o5b2o49bo105bo$29b2o57b3o6bo$90bo4b3o$94bo$31b2o17b2o
    29b2o11b2o14b2o$31b2o17bo30b2o27b2o$25b2o21bobo$25b2o21b2o$116b2o$116b
    2o36b2o$112b2o41bo$112b2o41bobo$156b2o$56b2o122b2o$56b2o11b2o109b2o$
    69bo47b2o$70b3o44b2o$72bo2$22bo$22b3o55b2o96b2o$25bo53bobo96bo$24b2o
    47b2o4bo99b3o$73b2o3b2o101bo$179b2o$76b4o99bo$75bo3bo97bobo$75b2o100b
    2o$53b2o33bo22b2o$19b2o32b2o33b3o20bo$20bo70bo20b3o$20bobo67b2o22bo44b
    o$21b2o136b3o$162bo$115bo45b2o$35b2o28b2o46b3o$35bobo27b2o45bo$37bo41b
    2o6b2o23b2o$37b2o40b2o6bo2b2o$83b2o3b2obo$83b2o4bo89b2o$17bob2o68bo89b
    o$17b2obo67b2obob2o18b2o62bobo$87bo2b2ob2o18bobo61b2o$26b2o60bo26bo$
    26b2o33b2o26b3ob2o20b2o$60bo2bo27bobo66b2o$61bobo29bo66b2o15b2o$62bo
    29b2ob2o80bobo$94bobo82bo$94bo84b2o$93b2o3$160b2o$160bo$158bobo$158b2o
    2$16bo$16b3o$19bo33bo121b2obo$18b2o33b3o53b2o64bob2o$56bo52b2o$11bo43b
    obo110b2o$11b3o42bo111b2o$14bo123bo$13b2o121b3o$57b2o19bo56bo$57b2o17b
    3o19b2o20bo14b2o$75bo23bo19bobo$75b2o22bobo17bobo$100b2o15bobobobo34b
    2o$10b2o19b2o79bo4b2o3b2o10bo24bo$10b2o19b2o47b2o29bobo19bobo23bobo$
    80b2o29bobo19bobo24b2o$4bo95b2o10bo21bo4b2o$4b3o25b2o65bobo20b2o15bobo
    $2o5bo24bo57b2o7bo21bobo17bo$bo4b2o25b3o54bo7b2o21bo19b2o36bo$bobo31bo
    52bobo22b2o5b2o55b3o$2b2o29b2o53b2o23bo62bo$33bo17b2o61b3o28b2o29b2o$
    31bobo4bo11bobo63bo28bo$31b2o3b3o11bo92bobo$35bo13b2o92b2o$35b2o94b2o$
    61b2o68b2o$61b2o$b2o178b2o$b2o178bo$36b2o141bobo$36b2o141b2o3$27b2o37b
    2o97b2o$27b2o36bobo51b2o43bobo$65bo54bo43bo$64b2o54bobo40b2o$121b2o2$
    181b2obo$181bob2o2$40bo133b2o$38b3o133b2o$37bo$37b2o$138b2o$138b2o$42b
    2o$42b2o78b2o$122b2o$114b2o$52b2o61bo18b2ob2o$52bo62bobo16b2obo$50bobo
    63b2o21bo$50b2o81bob5o$13b2o118b2o$12bobo121b2o$12bo124bo$11b2o99bobo
    19b3o$112b2obo18bo$23b2o90b3o$23b2o87b2o4bo$112bob5o$114bo$113bo3b2o$
    108bo3bo3bobo$106b3o3b2o3bo$105bo$28b2o75b2o29b2o39b2o$27bobo106b2o38b
    o2bo$27bo149b2o$26b2o2$131b2o$131b2o$135b2o$14b2o119b2o$14b2o35bo$49b
    3o$48bo80b2o$48b2o63b2o14b2o$79bo33bo$68b2o7b3o34b3o$69bo6bo39bo$69bob
    o4b2o$70b2o$109b2o$109bobo$111bo$111b2o7$103b2o$103bo$104b3o$106bo$13b
    o19b2o$12bobo10b2o6bo5b2o41b2o$11bo2bo10bo8b3obobo41bo$12b2o9bobo10bob
    o7b2o28b2obo3b3o$23b2o12b2o7b2o28b2ob4o2bo$82bo$64b2o6b2o2b2ob2o$63bob
    o6bo4bobo$63bo9b4o2bo$62b2o7bobo2bobo$71b2o4bo!]])
    local connecting_neck=g.parse([[24bo$22b3o$21bo$21b2o$6b2o$7bo$7bobo$8b2o10bo$19bobo$19bobo$20bo4b2o$
    8b2o15bobo$7bobo17bo$7bo19b2o$6b2o6$17b2o$17b2o7$23b2ob2o$22bobobobo$
    5b2o16bo2bobo$6bo19bob2o$6bobo16b2o3bo$7b2o13bobo2bobo$22b2o2b2ob2o11$
    8b2o15b2o$8b2o15bobo$2o25bo$bo25b2o$bobo$2b2o4$21bo107bo$19b3o106bobo$
    18bo109bobo$18b2o106b3ob2o$24bo100bo$22b3o12bo84bo2b4ob2o$21bo15b3o82b
    3o3bob2o$21b2o17bo84bo$39b2o83b2o26b2o$152bo$150bobo$150b2o2$24b2o$5b
    2o17b2o76bo$5b2o95b3o6b2o$105bo5b2o41b2obo$104b2o48bob2o$4b2o$5bo141b
    2o$2b3o12b2o86b2o40b2o$2bo14bo16b2o6b2o61b2o3b2o$18b3o14bo7bo66b2o$20b
    o11b3o5b3o$32bo7bo$78bo51b2o3b2o$76b3o13bo38bo3bo$75bo16b3o33b3o5b3o$
    50b2o23b2o18bo32bo9bo$45b2o3b2o42b2o42bobo$45b2o92b2o3$44b2o76b2o$45bo
    5b2o69b2o$42b3o6b2o104b2o$42bo41b2o71bo$84b2o69bobo$61b2o92b2o$60bobo
    62bo$60bo62b3o$59b2o10b2o49bo$72bo48bobo$69b3o9b2o39bo43b2o$69bo11bo
    19b2o56b2o6bo$82bo17bobo56bo6bo$81b2o17bo19b2o35bobo6b2o$99b2o19b2o35b
    2o$116b2o$116bo$117b3o24b2o$119bo23bobo$143bo25b2o$142b2o25b2o4$146b2o
    $145bobo$145bo4b2o$144b2o5bo$148b3o5bo$148bo6bobo$156bo!]])
    local transmitter2c3=g.parse([[180b2o$180b2o$219bo$219b3o$178b2o42bo$116bo61b2o41b2o$115bobo47b2o99b
    2o14bo$116bo49bo74b2o24bo14b3o$166bobo73bo13b2o6b3o18bo$167b2o73bobo
    11b2o6bo19b2o12bo$110b2o51b2o78b2o53b3o$110b2o23b2o26b2o136bo$102b2o
    31bo164b2o$103bo29bobo$103bobo27b2o$104b2o4b2o$110b2o162b2o$274b2o$
    144b2o30b2o$102b2o40bo31b2o$102bo39bobo$104bob2o34b2o43b2o144b2o$103b
    2ob2o78bo2bo143b2o$124b2o60bobo23b2o57b2o$103b2ob2o16b2o61bo20bo3b2o
    57bo20b2o$104bobo100bobo26b2o14b2o3b2o13bo20bo$104bobo99bobo21b2o5bo
    15bo3bo13b2o17b3o61b2o$105bo100bo23bobob3o13b3o5b3o29bo63b2o5b2o$205b
    2o16b2o7bobo15bo9bo100b2o$223b2o7b2o152b2o6bo$169b2o125b2o84bobo2bo4b
    3o$169b2o124bobo61b2o19b3ob2o5bo$295bo63b2o18bo11b2o$294b2o69b2o13b3ob
    2o$365b2o15bob2o$131b2o151bo$131b2o149b3o12b2o$281bo16bo91b2o3b2o$271b
    2o8b2o12b3o92b2o3b2o$272bo22bo$272bobo27b2o30b2o$273b2o28bo17b2o11b2o$
    39bo82bo136bo27b2o11b3o19bo77bo$38bobo79b3o136b3o25b2o11bo18b3o77bobo$
    39bo79bo142bo56bo80bo$108bo10b2o140b2o$37b5o65bobo228b2o$37bo4bo64bobo
    177b2o50bo28b2o$40bo2bo61b3ob2o20bo155b2o47b3o29bo$12bo27b2obo60bo24b
    3o204bo29bobo$12b3o10b2o10bo5bob2obo49bo6b3ob2o17bo104bo132b2o$15bo9b
    2o9bobo4bobob2o49b3o6bob2o17b2o103b3o146b2o$4b2o8b2o20bo2bo2b2obo30b2o
    23bo134bo145b2o$5bo31b2o6bo31bo6b2o14b2o133b2o11b2o13b2o$5bobo37b3o29b
    obo4b2o39b2o121b2o13b2o$6b2o40bo23b2o4b2o44bo2bo87bo73b2o$47b2o23bobo
    50b2o88b3o5b2o64bo$70bobob3o141bo4b2o62bobo$66b2o2b2o5bo139b2o68b2o81b
    2o$4bob2o58b2o8b2o292b2o$2b3ob2o384b2o$bo216b2o172bo$2b3ob2o80b2o128b
    2o3b2o123b2o15b2o26b3o$4bobo30b2o49b2o23b2o108b2o122bobo15b2o28bo$4bob
    o30b2o74bo233bo$5bo108b3o229b2o$116bo77b2o7b2o$100b2o24b2o66b2o7bobo$
    28b2o66bo3b2o24bo30b2o42bobob3o$28b2o65bobo29b3o2b2o24bo42b2o5bo40b2o
    18b2obo112b2o$34b2o58bobo32bo3bo13b2o6b3o49b2o40bobo17bob2o112bo$34bo
    19b2o38bo38bobo11b2o6bo95bo134b3o$30bo5bo16bobo37b2o24b2o13b2o115b2o
    135bo$29bobo3b2o16bo65b2o164b2obo$30bo21b2o231bob2o$31b3o$33bo79b2o
    163b2o$113b2o163b2o$117b2o46b2o$66b2o49b2o46b2o$66b2o$349b2o$350bo$71b
    2o39b2o98b2o136bobo$70bobo39b2o99bo54b2o81b2o$70bo91b2o46b3o56bo105b2o
    $69b2o91bo47bo58bobo103b2o$143b2o3b2o13bo106b2o$82b2o60bo3bo13b2o$82b
    2o57b3o5b3o$141bo9bo40b2o$193bo$27bo162b3o180b2o$26bobo161bo182bo$26bo
    2bo262b2o80b3o$27b2o263bo83bo$118b2o22bo147bobo81b2o$119bo20b3o99bo18b
    o28b2ob2o79bo$116b3o20bo102b3o7b2o5b3o31bobo76bobo$116bo22b2o104bo6b2o
    4bo34bobo76b2o$5b2o237b2o12b2o10b2o20b2ob2o$5b2o264bo24bo$9b2o104bo
    155bobo18b2obo$9b2o104b3o139b2o13b2o18b2obobo56bo$23b2o93bo133b2o3b2o
    37b2o56b3o$23b2o92b2o23b2o108b2o103bo$139b2o2bo212b2o28b2o$139bob2o71b
    2o56b2o112bo$141bo71bobo55bobo110bobo$141bo71bo49bo7bo108b2o2b2o$116b
    2o18b2obob2o69b2o47b3o5b3o108b2o$35b2o78bobo18b2ob2o2bo116bo7bo$35b2o
    78bo26bo117b2o6b2o$13b2o99b2o20b2ob3o$14bo122bobo239b2o4b2o$11b3o123bo
    241b2o4b2o$11bo90b2o30b2ob2o$102bo31bobo$100bobo5b2o26bo$99bobo6b2o26b
    2o140b2o$95b2o3bo177b2o72b2o35bo$95b2o254bobo33b3o$20b2o69b2o194b2o62b
    o34bo$21bo70bo194bo62b2o34b2o$18b3o71bobo193b3o63b2o$18bo74b2o195bo63b
    2o3bo$233bo47b2o75bobo6b2o$233b3o46bo76bobo5b2o$236bo44bo79bo$235bobo
    43b2o78b2o$120b2o4b2o108bo30bo$120b2o4b2o139b3o$270bo$237b2o30b2o8b2o
    74bo$237b2o40bo61bo13b3o35b2o$121b2o154bobo59b3o16bo34b2o$121b2o2b2o
    150b2o59bo18b2o$125bobo93bo41b2o73b2o$127bo92bobo40b2o26b2o$97b2o28b2o
    91bobo68bo23bo72b2o$98bo119b3ob2o65bobo23b3o70b2o$95b3o119bo71b2o27bo
    73b2o$95bo118bo2b4ob2o39b2o52b2o73b2o$214b3o3bob2o39b2o$217bo130b2o$
    175bo40b2o26b2o102b2o36b2o$113b2o60b3o66bo126b2o13b2o$113bobo46b2o3b2o
    9bo14b2o47bobo126bobo$77bo37bo2bo2bo40b2o3b2o8b2o15bo47b2o43b2o84bo$
    77b3o35b7o71bo93b2o72b2o10b2o$80bo112b2o113b2o51bo$38b2o39b2o36b5o33b
    2o151b2o41b2o9b3o$38b2o77bo4bo2b2o29bo174b2o19bo11bo$120bo2bo2bo29bobo
    87b2obo81bobo17bo$120b2obobo31b2o87bob2o83bo17b2o$117bo5bob2o194b2o10b
    2o$105b2o9bobo4bo72b2o41b2o80bo$105b2o9bo2bo2b2o72b2o41b2o70b2o9b3o$
    117b2o193bo11bo$96b2obo211bo$96bob2o211b2o$160b2o$61b2o98bo60b2o3b2o$
    61b2o8b2o85b3o28b2o32bo3bo$72bo85bo31bo15b2o12b3o5b3o29b2o$69b3o117bo
    17bo12bo9bo28bobo$47b2o20bo119b2o13b3o23bobo26bo$48bo155bo26b2o25b2o
    14b2o$10b2o33b3o70b2o153bo2bo$10b2o33bo29b2o41b2o154b2o$6bo50b2o15bobo
    $6b3o48bo16bo98b2o$9bo48b3o12b2o98b2o54b2o$8b2o11bo38bo103b2o64bo$20bo
    bo7b2o131bobo51b2o11bobo$20bobo7b2o44b2o85bo54bo12b2o$21bo55bo84b2o54b
    obo$74b3o142b2o2b2o$74bo148b2o$81b2o34b2o$82bo34bobo$18b2o59b3o37bo$
    18b2o59bo39b2o97b2o4b2o$4b2o212b2o4b2o$4b2o$2o$2o162bo$107bob2o3b2o48b
    3o$105b3ob2o3bo52bo$104bo10b3o48b2o$105b3ob2o6bo101b2o$107b2o2bo106bob
    o$110b2o106bo$217b2o2$164b2o$164b2o$188b2o$188bobo$190bo$24b2o164b2o$
    23bobo$24bo4$132bo4b2o$131bobo2bobo7b2o$130bo2b4o9bo$26b2obo100bobo4bo
    6bobo$26bob2o99b2ob2o2b2o6b2o$127bo$19b2o103bo2b4ob2o$19b2o103b3o3bob
    2o$127bo40b2o$126b2o39bobo$52b2o103bo9bo$52b2o49b2o52b3o5b3o54b2o$104b
    o55bo3bo57b2o$91bo11bo55b2o3b2o$9b2o39b2o39b3o9b2o$10bo39b2o42bo$10bob
    o24b2o42b2o10b2o$11b2o25bo43bo150b2o$38bobo41bobo91b2o55bo$39b2o42b2o
    91b2o53bobo$35b2o69b2o123b2o$35b2o69b2o75bob2o$29b2o152b2obo$29bo188b
    2o$27bobo187bobo$27b2o109b2o77bo$132b2o4bobo75b2o$133bo6bo38b2o$48b2o
    66b2o12b3o7b2o37bobo$48b2o47b2o18bo12bo50bo$97bo16b3o36b2o26b2o$59b2o
    37b3o13bo39bo$58bo2bo38bo50b3o3bob2o59b2o$58bobo23b2o65bo2b4ob2o58bobo
    $59bo20bo3b2o68bo64bo$79bobo73b3ob2o57b2o$7b2o69bobo76b2o2bo$7b2o17b2o
    50bo81b2o84bo$26b2o49b2o165b3o$243bo$41b2o200b2o$41b2o2$219bo$219b3o$
    222bo$221b2o23b2o$243b2o2bo$243bob2o$245bo$245bo$220b2o18b2obob2o$219b
    obo18b2ob2o2bo$219bo26bo$218b2o20b2ob3o$241bobo$51bo189bo$12b2o35b3o
    186b2ob2o$12b2o34bo189bobo$48b2o190bo$81bo158b2o$81b3o$17b2o65bo$17b2o
    64b2o$13b2o$13b2o2$57b2o159b2o$19b2o36b2o158bobo$19b2o13b2o181bo$33bob
    o180b2o$33bo181bo$32b2o10b2o74bo94b3o$45bo72b3o97bo$42b3o9b2o61bo99b2o
    $42bo11bo20b2o40b2o17bo39bo$55bo20bo59b3o37b3o$54b2o17b3o63bo39bo$73bo
    64b2o38b2o12bo$192b3o$159bo35bo19b2o$79b2o78b3o32b2o19b2o$78bobo81bo
    76b2o$78bo82b2o11b2o63bobo$77b2o95b2o65bo$241b2o2$80b2o$81bo$78b3o$78b
    o$85b2o30b2o$86bo17b2o11b2o$83b3o19bo80b2o$83bo18b3o82bo$102bo81b3o$
    184bo2$153b2o$147b2o5bo20b2o13b2o$147bobob3o21bobo11bobo$140b2o7bobo
    25bo11bo$140b2o7b2o26b2o9b2o3$191b2o$192bo$189b3o19b2o21b2o$189bo20bob
    o21b2o$196b2o12bo17b2o$197bo11b2o17b2o$194b3o$194bo$230b2o$223b2o5b2o$
    223b2o5$89b2o$89b2o8$63bo$62bobo$62bobo$61b2ob2o16b2o$82b2o$61b2ob2o$
    62bob2o34b2o$60bo39bobo$60b2o40bo$102b2o2$68b2o$62b2o4b2o$61bobo27b2o$
    61bo29bobo$60b2o31bo$68b2o23b2o$68b2o$86b2o$82bo3b2o$74bo6bobo$73bobo
    4bobo$74bo5bo$79b2o!]])
    local head2c3=g.parse("8b2o$3bo2bo2bo$3b6o2$3b6o$2bo6bo$2bo2b5o$obobo$2o2bo$4bo$3b2o!")
    local body2c3=g.parse("6bo$b6o$o$o2b6o$obo6bo$obo2b5o$b2obo$4bo$4bo$3b2o!")
    local tail2c3=g.parse("5b2o$5b2o2$b6o$o5bo$o2b3o$obo$o2bo$b2o!")
    local wire2c3=g.join(g.transform(head2c3,625,388), g.transform(tail2c3,2143,1905))
    -- 251 body segments, first one at (631, 395)
    for i=631,2142,6 do wire2c3=g.join(wire2c3,g.transform(body2c3,i,i-236)) end 
    local receiver2c3=g.parse([[208bo$207bobo$208bo3$213b2o$188b2o23b2o$189bo31b2o$189bobo29bo$190b2o
    27bobo$213b2o4b2o$213b2o2$179b2o$180bo40b2o$180bobo39bo$181b2o34b2obo$
    217b2ob2o$199b2o$199b2o16b2ob2o$218bobo$218bobo$219bo8$192b2o$192b2o8$
    55b2o$48b2o5b2o$48b2o$85bo$83b3o$50b2o17b2o11bo$50b2o17bo12b2o$44b2o
    21bobo20bo$44b2o21b2o19b3o$87bo$87b2o3$90b2o9b2o26b2o7b2o$90bo11bo25bo
    bo7b2o$88bobo11bobo21b3obobo$88b2o13b2o20bo5b2o39bo$125b2o45b3o$175bo
    14bo$95bo78b2o12b3o$41bo51b3o91bo$41b3o48bo94b2o$44bo47b2o$43b2o$186b
    2o$167b2o17b2o$167b2o3$61b2o$61bo$59bobo42b2o$59b2o43b2o11b2o51b2o$
    117bo53bo$84b2o32b3o48bo$42b2o40bo35bo48b2o$42b2o15b2o24b3o85b2o$59bob
    o25bo12b2o38b2o32bo$61bo38bo39bo30b3o$61b2o38b3o37b3o27bo$103bo39bo3$
    42b2o$42bo$40bobo$40b2o4$57b2obo$57bob2o2$50b2o$50b2o122b2o$173bobo$
    173bo29b2o$172b2o29bobo$205bo$178b2o25b2o$177bobo4b2o$40b2o135bo7bo$
    41bo134b2o4b3o$41bobo138bo$42b2o146b2o$189bobo$189bo$188b2o$61bo$59b3o
    $58bo$58b2o$206b2o$182bo23bobo$63b2o117b3o23bo$63b2o120bo22b2o$184b2o
    14b2o$200b2o$73b2o$73bo$71bobo$71b2o$34b2o$33bobo$33bo$32b2o2$44b2o$
    44b2o$160b2o7b2o30b2o$92b2o66b2o7bobo29bobo$92b2o45bo27bobob3o29bo$
    139b3o25b2o5bo28b2o$142bo30b2o$90b2o49b2o$49b2o39b2o$48bobo26b2o43bo$
    48bo29bo43b3o$47b2o29bobo44bo$79b2o43b2o11b2o$75b2o60b2o$75b2o4$177b2o
    21b2o$66b2o108bobo21b2o$66bo109bo17b2o$64bobo21b2o85b2o17b2o$48b2o14b
    2o22b2o$48b2o93b2o$52bo46b2o39b2o2bo2b2o47b2o$48b2o2b3o43bo2bo38b2obo
    3bo41b2o5b2o$48b2o5bo42bobo23b2o17bobobo10b2o29b2o$54b2o43bo20bo3b2o
    14b2obob2o12bo$119bobo12b2o4bo2bo12b3o$118bobo13b2o6b2o12bo$67b2o49bo$
    66bobo48b2o$67bo$81b2o$81b2o4$47b2o$47b2o5$49bo$19b2o28b3o$12b2o5b2o
    31bo92bo$12b2o37b2o90b3o11bo$47b2o93bo14b3o$47bo94b2o16bo14bo$14b2o33b
    o109b2o12b3o$14b2o32b2o69bo52bo$8b2o109b3o50b2o$8b2o112bo$121b2o$171b
    2o$152b2o17b2o$45b2o105b2o$45b2o17b2o$64b2o3$65b2o$65bo89b2o$52b2o12b
    3o41bo23b2o20bo$35b2o16bo14bo40bobo22bo19bo$35bo14b3o57bo14b2o8b3o16b
    2o$28bo7b3o11bo74bo11bo20b2o$26b3o9bo87b3o30bo$25bo102bo27b3o$25b2o
    129bo$17b2o93b2o$17b2o92bobo$111bo$110b2o62b2o$126b2obo44bobo$126bob2o
    46bo$176b2o$34b2o83b2o$34bo84b2o$32bobo$32b2o3$166b2o$166b2o2$157b2obo
    $157bob2o2$36b2o$36bobo$38bo91b2o44b2o$38b2o90bo44bobo$28b2o98bobo44bo
    $28b2o98b2o44b2o$9bob2o$9b2obo2$18b2o135b2o$18b2o136bo$156bobo$157b2o
    15b2o$114b2o58b2o$114bo2b2o$115b2obo$116bo40b2o$28b2o86bobo4b2o31bobo$
    28bo88b2o5bo31bo$26bobo94bo31b2o$26b2o68b2o25b2o$70bo25bo$58bo11b3o21b
    obo$56b3o14bo20b2o$40bo14bo16b2o$40b3o12b2o70b2o44b2o$43bo58b2o24bo44b
    o$4b2o36b2o59bo13b2o6b3o46b3o$5bo97bobo11b2o6bo50bo$5bobo96b2o$3b2ob2o
    35b2o$2bobo38b2o17b2o$2bobo57b2o$b2ob2o20b2o$bo24bo$2bob2o18bobo108b2o
    $obob2o18b2o109b2o$2o$59b2o32b2o$59bo20b2o11b2o$24b2o35bo19bo67b2o21b
    2o$24bobo33b2o16b3o67bobo21b2o$26bo29b2o20bo53b2o14bo17b2o$26b3o27bo
    75bo14b2o17b2o$29bo27b3o37b2o14b2o3b2o13bo$28b2o29bo38bo15bo3bo13b2o$
    95b3o13b3o5b3o46b2o$95bo15bo9bo39b2o5b2o$161b2o4$18b2o$18b2o2$9b2o$10b
    o$7b3o45b2o$7bo47b2o$15b2o32b2o$15bo33b2o$16bo$15b2o$51b2o$44b2o5b2o$
    44b2o!]])

    local inserter2c3=g.parse([[51bo$49b3o$23b2o23bo$24bo23b2o$24bobo$25b2o2b2o37bo$29b2o35b3o15bo9bo$
    65bo18b3o5b3o$52b2o11b2o20bo3bo$52b2o32b2o3b2o8$23b2o52b2o$22bobo16b2o
    34b2o$22bo18bobo45b2o$21b2o20bo44bo2bo$37b2o4b2o44b2o4b2o$37bo2bo54bob
    o$39b2o56bo$30b2o65b2o$30b2o20b2o33b2o$53bo34bo$50b3o32b3o$50bo34bo2$
    19bo$19b3o$22bo$21b2o2$85b2o$85bo$86b3o$88bo2$40b2o$40bo$38bobo$38b2o
    12$20b2o15b2o$19bobo15b2o$19bo$18b2o6$25bo$25b3o$28bo$27b2o28b2o$57bo$
    55bobo$51b2o2b2o$51b2o4$50b2o4b2o$50b2o4b2o5$23b2o35bo$22bobo33b3o$22b
    o34bo$21b2o34b2o$25b2o$25b2o3bo$29bobo6b2o$30bobo5b2o$32bo$32b2o$24b2o
    $25bo$25bobo$26b2o2b2o$30b2o32b2o$64b2o4$59b2o$59b2o$63b2o$63b2o3$24b
    2o31b2o$23bobo16b2o13b2o$23bo18bobo$22b2o20bo$38b2o4b2o$38bo2bo$40b2o$
    31b2o$31b2o7$21b2o$22bo$22bobo$23b2o$39bo$37b3o$36bo$36b2o3$10b2o$10b
    2o7$43b2o$43b2o4$38b2o$38b2o$2o40b2o$2o40b2o3$36b2o$21b2o13b2o$21bobo$
    23bo$23b2o!]])

    local all = g.join(g.transform(highway_robber,86,0),
          g.join(g.transform(connecting_neck,195,262),
          g.join(g.transform(transmitter2c3,347,219),
          g.join(wire2c3,
          g.join(g.transform(receiver2c3,2103,1763),
                 g.transform(inserter2c3,2024,2042))))))

    g.new("Stable Pseudo-Heisenburp Device")
    -- ??? g.setalgo("HashLife")
    g.setrule("B3/S23")
    g.putcells(all)
    g.setmag(0)
    g.setpos("120","200")

    g.setname("Highway Robber")
    g.clone()
    g.setname("2c/3 Transmitter")
    g.setpos("500","400")
    g.clone()
    g.setname("2c/3 Receiver")
    g.setpos("2175","2000")
    g.clone()
    g.setname("Stable Pseudo-Heisenburp Device")
    g.clone()
    g.setname("Glider Fleet")
    g.setpos("330","290")

    -- since the tiles change size depending on how many layers have been created,
    -- have to create all five layers before checking visibility of components --
    -- now go back and check that the critical areas are all visible.
    -- Could instead select each key rectangle, use g.fitsel(), then unselect.
    g.setlayer(0)
    while not g.visrect( {100,100,150,175} ) do g.setmag(g.getmag()-1) end
    g.setlayer(1)
    while not g.visrect( {350,225,400,350} ) do g.setmag(g.getmag()-1) end
    g.setlayer(2)
    while not g.visrect( {2100,1750,225,300} ) do g.setmag(g.getmag()-1) end
    g.setlayer(3)
    g.fit()
    g.setlayer(4)
    while not g.visrect( {0,200,300,400} ) do g.setmag(g.getmag()-1) end
    g.update()
end

-------------------------------------------------------

function burp()
    local test_signal=g.parse([[40bo$41bo$39b3o17$40bo4bo4bo4bo4bo$41bo4bo4bo4bo4bo$39b3o2b3o2b3o2b3o
    2b3o3$40bo4bo4bo4bo4bo$41bo4bo4bo4bo4bo$39b3o2b3o2b3o2b3o2b3o3$40bo4bo
    4bo4bo4bo$41bo4bo4bo4bo4bo$39b3o2b3o2b3o2b3o2b3o3$40bo4bo4bo4bo4bo$41b
    o4bo4bo4bo4bo$39b3o2b3o2b3o2b3o2b3o3$bo38bo4bo4bo4bo4bo18bo$2bo38bo4bo
    4bo4bo4bo18bo$3o36b3o2b3o2b3o2b3o2b3o16b3o37$40bo$41bo$39b3o!]])

    prepare_burp()

    g.show(instr..tickstep)
    g.select( {selx,sely,50,50} )

    -- keyboard handling
    local ch = ""
    while ch~="q" do
        if place_signal>0 then
            if ticks-last_signal>1846 then
                g.putcells(test_signal,-150,60)
                last_signal=ticks
                place_signal=place_signal-1
            end
        end
        local status_text=instr
        if place_signal>0 and run_flag==1 then
            status_text="Next signal placement in "..(1847 - ticks + last_signal).." ticks. "
            local plural="s"
            if place_signal==2 then plural="" end
            if place_signal>1 then status_text=status_text..(place_signal-1).." more signal"..plural.." requested after that. " end
            status_text=status_text..instr
        end
        show_status_text(status_text,delay,tickstep)
        local event = g.getevent()
        if event:find("key") == 1 then
            _, ch, _ = split(event)
        else
            ch = ""
        end
        if ch=="r" then
            prepare_burp()
            ticks=0
            last_signal=-99999
            viewport_speed=16
            sel_speed=0
            run_flag=0
            selx=600.0
            sely=365.0
            place_signal=3
            g.select({selx,sely,50,50})

        elseif ch=="h" then g.note(helpstring)
        elseif ch=="t" then g.setoption("tilelayers",1-g.getoption("tilelayers"))

        elseif ch=="=" or ch=="+" then
            if delay>.01 then delay=delay/2
            elseif delay==.01 then delay=-1
            else
                if tickstep==1 then tickstep=3
                elseif tickstep<250 then tickstep=(tickstep-1)*2+1
                end
            end
        elseif ch=="-" or ch=="_" then
            if delay==-1 then
                if tickstep==1 then delay=.01
                else
                    if tickstep==3 then tickstep=1 else tickstep=math.floor((tickstep-1)/2)+1 end
                end
            else
                if delay<1 then delay=delay*2 end
            end

        elseif ch=="space" then run_flag=0
        elseif ch=="return" then run_flag=1-run_flag
        elseif ch=="s" then
            place_signal=place_signal+1
            if run_flag==0 then run_flag=1 end
        else g.doevent(event)
        end

        -- generation and selection speed handling
        if ch=="space" or run_flag==1 then
            g.run(tickstep)

            currlayer = g.getlayer()
            if currlayer ~= 4 then
                -- user has switched layer so temporarily change it back
                -- so we only change location of bottom right layer
                g.check(false)
                g.setlayer(4)
            end

            x, y = g.getpos()
            x, y = tonumber(x), tonumber(y)
            
            oldticks=ticks
            ticks=ticks+tickstep
            delta_view=math.floor(ticks/viewport_speed) - math.floor(oldticks/viewport_speed)
            if delta_view ~= 0 then g.setpos(tostring(x + delta_view), tostring(y + delta_view)) end
            sel = g.getselrect()
            if #sel ~= 0 then
                x, y, w, h = table.unpack(sel)
                if math.floor(selx)~=x then selx,sely=x,y
                else
                    selx=selx+sel_speed*tickstep
                    sely=sely+sel_speed*tickstep
                    g.select( {math.floor(selx), math.floor(sely), w, h} )
                end
            else g.select({math.floor(selx), math.floor(sely), 50, 50})
            end

            if currlayer ~= 4 then
                g.setlayer(currlayer)
                g.check(true)
            end

            -- change viewport speed at appropriate times to follow the action
            if oldticks<4570 and ticks>=4570 then
                sel_speed=.666667
                -- one-time correction to catch up with the signal at high sim speeds
                g.select( {math.floor(600+(ticks-4570)*1.5), math.floor(365+(ticks-4570)*1.5), w, h} )
                end
            if selx>2125 then
                sel_speed=0
                g.select( {2125, math.floor(sely+2125-selx), w, h} )
            end
            if oldticks<4750 and ticks>=4750 then viewport_speed=1.5 end
            if oldticks<6125 and ticks>=6125 then viewport_speed=16 end
            if oldticks>=11995 then viewport_speed=99999.9 end

            -- stop automatically after the last signal passes through the device
            if oldticks-last_signal<8705 and ticks-last_signal>=8705 then run_flag=0 end
            
            if run_flag==1 and delay>0 then sleep(delay) end

        g.update()
        end
    end
end

-------------------------------------------------------

-- if there's more than one existing layer, the layout won't work correctly
if g.numlayers() > 1 then
    local answer = g.getstring("All existing layers will be removed. OK?")
    if string.lower(string.sub(answer,1,1)) == "n" then g.exit() end
end
local oldswitch = g.setoption("switchlayers", 1) -- allow user to switch layers
local oldtile = g.setoption("tilelayers", 1)

local status, err = xpcall(burp, gp.trace)
if err then g.continue(err) end
-- the following code is executed even if error occurred or user aborted script

-- remove the cloned layers added by the script
while g.numlayers() > 1 do g.dellayer() end
g.setname("Stable Pseudo-Heisenburp Device")
g.setoption("tilelayers", oldtile)
g.setoption("switchlayers", oldswitch)
g.show("")