It's more a script problem statement rather than actual construction, but I cannot quite get Goldtiger997's scripts in this thread to work with my Golly 4.1b1 and Python 3.9.5 (both 64-bit).
1) For
this script, the variables
on line 108, 110 and 112 are float instead of integer despite having zero after the decimal point, causing a TypeError with g.putcells. If I add this after line 100...
Code: Select all
bend_delay = int(bend_delay)
snark_space = int(snark_space)
...then the provided example input will lead to a broken output with track too long and patterns superimposed on each other:
2) For
these two scripts, using the latter non-automatic one as an example, it will give a similar TypeError on line 125. The
x and
y both refer to a
delay/4 which may not be an integer. I thought it has something to do with how different divisions are handled in Python, and then I tried using
delay//4 on line 123, 124, 131 and 132. This way it worked.
EDIT: Thanks for reminding, dvgrn! The updated scripts are shown below.
Code: Select all
#place-edgeshooters-automatic.py
#Goldtiger997 February 2020
#Replaced a few divisions for Python 3 compatibility, August 2020
import golly as g
gap_size = int(g.getstring("Please enter the diagonal spacing between the edgeshooters","50"))
flip_mode = int(g.getstring("Which mode?\n\n1) gliders are preferred to inserted from alternating sides\n2) gliders are preferred to be inserted all from the same side","1"))
safe_space = int(g.getstring("How much additional spacing do you want between the gliders and the edgeshooters? Increase this parameter if the script places gliders too close to the edgeshooters","50"))
edgeshooter_preference = g.getstring("Please enter your order of preference of the following four edgshooter types by entering the numbers that correspond to those edgeshooters in order of preference (most preferred to least preferred) separated by commas.\n Omit a number if you wish the corresponding edgeshooter to be banned\n\n1: NW31\n2: BNE14T30\n3: RNE-19T84\n4: Fx119\n\nFor example the input '1,4,2' would indicate that NW31 edgeshooters are most preferred, Fx199s are second-most preferred, BNE14T30s are least preferred and RNE-19T84s are outright banned from being used.\n\nAlternatively just enter 'n' for the default settings (equivalent to '1,2,3,4')","n").split(",")
sel_desc = g.getselrect()
selection = g.getcells(g.getselrect())
glider_phases = [g.parse("3o$2bo$bo!"),g.parse("bo$b2o$obo!"),g.parse("b2o$obo$2bo!"),g.parse("2o$b2o$o!")]
gliders = []
gliders_sorted = []
gliders_lanes = []
the_numbers = ["1","2","3","4","5"] #full list ["1","2","3","4","5","6","7","8","9","0"]
#edgeshooters
#format is [rle, output glider lane adjustment, input glider lane adjustment, input glider positioning adjustment,delay of edgeshooter,flip_adjust,flip_time_adjust]
edgeshooter1 = [g.parse("18bb$17b2b$16b3b$15b4b$14b4b$13b4b$12b4b$11b4b$10b4b$9b4b$8b4b$8b4b$7b5b$4b9b$4b9b$4b9b$4b10b$3b12b$2b13b8b2o$3b11b9bo$4b12b4bbobo$4b15bbb2o13b2o$4b17b14bb2ob$4b17b15b2b$bbb17b17b2b3bb$2o19b15b4bbb2o$2obb19b11b8b2o$bb4b20b2b2b2b6b2obbb$6b32b2o$6b9bb24b$7b7b2b28b$7b7b2b28b$7b6b4b26b2o$7b7b10b4bb14b2o$7b6b12b4b2b11bbb$6b7b13b4b2b10b$7b6b14b14b$8b5b15b14b$8b6b14b13b$10b4b14b13b$9bb2o2b2b2ob2o2b2o3b8bb4b$10b2o5bobo2bobo3b8b$17bo2b2obb4b8b$18bobo2b2b3b10b$17b2obobbo2bb7b2b2o$20bobobo9b2bo$17b4o2bob8b4b3o$17bo3b2o3b7b6bo$19bobb6b6b$18b2ob2ob3b7b$21b2obb8b$18b2o3b10b$18bo4b6b2o3b$19bo3b6b2o2b5b2o$18b2o3b10b5bo$22b11b2bbobo$22b12bbb2o$21b15b$20b16b$17b2bb16b$16b2o18b$16b2obb17b$17bbb4bb8b2b4b$24b7b4b4b$25b6b5b4b$27b4b6b4b$29b3bo5b4b$30bbobo5b3b$31bobo6b2b$32bo8bb$33b3o$35bo!"),18,0,27,1,19,-100]
edgeshooter2 = [g.parse("22b4b$21b4b$20b4b$19b4b$18b4b5b2o$17b6b3bo2bo$16b8bbbbobo$16b10b2o2b2o$15b11b2b2o2bo$15b11b2o3b2o$15b10b2bo$15b9b2bo$10b14b3b3o$9b13b7bo$9b14b$9b14b$9b13b$10b11b$9b14b$9b2b2o11b$10bb2o11b$10b14b$10b4bb8b$11b2bb9b3b2o$14b8b3bobo$14b8b3bo$14b9bb2o$13b11b$12b12b$12b12b$5b2o6b10b$6bo7b11b$6bobobb14b$7b2obb13b2o$9b15b2o$8b15bbb$9b14b$7b2obb11b$6bobob3b9b$6bo8b8b$5b2o9b7b$13b11b$12b12b$12b12b$12b11b$2ob2o2b2o3b8bb4b$bobo2bobo3b7b4b2o$bo2b2obb4b7b4bo$2bobo2b2bbbb6b6b3o$b2obobbo10b8bo$4bobobo9b$b4o2bob8b$bo3b2o4b6b$3bobb6b6b$2b2ob2ob3b7b$5b2obb8b$2b2o3b10b$2bo4b6b2o3b$3bo3b6b2o2b5b2o$2b2o3b10b5bo$6b11b2bbobo$6b12bbb2o$5b15b$4b16b$b2bb16b$2o18b$2obb17b$bbb4bb8b2b4b$8b7b4b4b$9b6b5b4b$11b4b6b4b$13b3bo5b4b$14bbobo5b4b$15bobo$16bo$17b3o$19bo!"),22,12,48,39,23,-184]
edgeshooter3 = [g.parse("18b4b$17b4b$16b4b$15b4b$14b6b7b2o$13b7b7bo$13b9b2bbobo$9bb2b11bbb2o$9b2bb9bo3b$9b3bb7bobo2b$9b11bobo2b$10b4bbb2b3bo3b$11b4b4b6b$12b4b4b6b$13b4b3b6b$14b4b2b5b$15b14b$16b14b$17b13b$10b2o5b13b$11bo5b11bbb2o$11bobob2b10b2bbobo$12b2obb9b7bo$14b11b7b2o$14b13b$14b9bbb2obo$15b7b2bb2ob3o$14b8b4bb4bo$15b8b2b2ob3o$16b7b3bobo$13b11b2bobo$12b11b4bo$12b11b$12b11b$2ob2o2b2o3b8b2bb2o$bobo2bobo3b7b3bbobo$bo2b2obb4b7b6bo$2bobo2b2b3b6b7b2o$b2obobbob2b7b$4bobobo2b7b$b4o2bo4b5b$bo3b2o4b6b$3bobb6b6b$2b2ob2ob3b7b$5b2obb8b$2b2o3b10b$2bo4b6b2o3b$3bo3b6b2o2b5b2o$2b2o3b10b5bo$6b11b2bbobo$6b12bbb2o$5b15b$4b16b$b2bb16b$2o18b$2obb17b$bbb4bb8b2b4b$8b7b4b4b$9b6b5b4b$11b4b6b4b$13b3bo5b4b$14bbobo5b4b$15bobo6b4b$16bo8b4b$17b3o6b4b$19bo7b4b$28b4b!"),18,4,37,14,19,-140]
edgeshooter4 = [g.parse("17b4b$16b4b$15b4b$14b4b$13b4b$12b4b$11b4b$10b4b$9b7b$9b9b$8b11b$5b13b$4b14b$3b16b$3b17b$2b18b$2b19b$b20b19bo$20b20b3o$b21b21bo$b21b20b2o$3b19b20bb8bo$2bbb17b19b3b6b3o$4b18b16b6b4bo$4b20b11b10b3b2o$5b22b2b2b3b16b$5b34b2o7b$7b32b2o9b$8b42b$8b42b$8b44b$8b13b4b4bb13bb9b$8b6b4b3b5b3b5bbb19b$7b7b5b4b4b4b12b14b$8b6b7b2o6b2o11b15b$9b6b6bo7bo12b14b$9b6b7b3o5b3o9b13b$8b8b8bo7bo6b15b$9b6b17bobob2b15b$8b7b18b2obb17b$6b11b18b19b$4b9b2o2bbb15b19b$4b9b2o3b2o15b20b2b2o$4b14b2o13b2obb16b2obobo$5b14b13bobob2b13bbb2obo$5b3bb2b2bb2b5b11bo6b11b4bb2bo$5b2o5b3b4b2o10b2o7b11b2b2ob2o$6bo5bb2ob3bo17b14b3bobo$3b3o7b2o5b3o13b16b2bobo$3bo18bo4b2o7b13bbb2ob2o$26bo2bo2b2o2b13bbbobo$27b2o2bobo2b8bb2b6bo$29b2obb3b7b10b2o$29bo2b2b2b7b$26b2obobbo2bb6b$26bob2obobo8b$30bobob8b$27b2o2bo2b7b$25b3ob2o4b6b$24bo4bb6b6b$25b3ob2ob3b7b$27bob2obb8b$31b10b$31b6b2o3b$31b6b2o2b5b2o$31b10b5bo$30b11b2bbobo$30b12bbb2o$29b15b$28b16b$25b2bb16b$24b2o18b$24b2obb17b$25bbb4bb8b2b4b$32b7b4b4b$33b6b5b4b$35b4b6b4b$37b3bo5b4b$38bbobo5b4b$39bobo6b4b$40bo8b3b$41b3o6bb$43bo!"),17,0,30,87,18,-112]
edgeshooters_unordered = [edgeshooter1,edgeshooter2,edgeshooter3,edgeshooter4]
#order edgeshooters according to preferences
if edgeshooter_preference[0] == "n":
edgeshooters = edgeshooters_unordered
else:
edgeshooters = []
for i in edgeshooter_preference:
try:
edgeshooters.append(edgeshooters_unordered[(int(i)-1)%4])
except ValueError:
g.note("Your edgeshooter preferences cannot be understood so the default preferences will be used")
edgeshooters = edgeshooters_unordered
break
if g.getrule() != "B3/S23":
g.warn("Please change the rule to life.")
g.exit()
if g.getselrect() == []:
g.warn("Please select some northeast heading gliders")
g.exit()
g.shrink()
#crude glider detection
def find_glider(phase_num):
count = 0
size = ((sel_desc[2]-2)*(sel_desc[3]-2))
for i in range(0,sel_desc[2]-2):
for j in range(0,sel_desc[3]-2):
x = sel_desc[0]+i
y = sel_desc[1]+j
g.select([x,y,3,3])
old_patt = g.getcells(g.getselrect()) #for restoration
g.putcells(glider_phases[phase_num],x,y,1,0,0,1,"xor")
if len(g.getcells(g.getselrect())) == 0:
gliders.append([phase_num,x,y])
g.clear(0)
g.putcells(old_patt,0,0,1,0,0,1,"or")
count += 1
g.show(str(25*phase_num + count*25/size) + "% glider detection done")
for i in range(0,4):
find_glider(i)
if len(gliders) == 0:
g.warn("Your selection has no (detectable) gliders")
g.exit()
g.setrule("B3/S23")
#now convert into format of [[lane,point on that lane]...]
for glid in gliders:
if glid[0] == 0:
gliders_lanes.append([glid[2]+glid[1],glid[1]*4])
elif glid[0] == 1:
gliders_lanes.append([glid[2]+glid[1] + 1,glid[1]*4 + 1])
elif glid[0] == 2:
gliders_lanes.append([glid[2]+glid[1] + 1,glid[1]*4 + 2])
elif glid[0] == 3:
gliders_lanes.append([glid[2]+glid[1],glid[1]*4 - 1])
gliders_lanes_sorted = sorted(gliders_lanes, key = lambda x: x[0])[::-1]
for e in gliders_lanes_sorted:
gliders_sorted.append(gliders[gliders_lanes.index(e)])
last_selected_glider = 0
completed_gliders = []
for blah_blah_blah in gliders:
completed_gliders.append(False)
last_selected_glider = 0
g.putcells(selection,-(186 + safe_space) - gap_size*len(gliders),(186 + safe_space) + gap_size*len(gliders),1,0,0,1,"or")
g.update()
edgeshooter_gap = 150
edgeshooters_placed_count = 0
edgeshooter_storage = [] #to facilitate deletion
def place_edgeshooter(num,gap,count):
if flipped%2 == 0:
edge_x = -gap-edgeshooters[num][1] + edgeshooters[num][2] + sel_desc[0]
edge_y = gliders_lanes_sorted[last_selected_glider%len(gliders)][0]+gap - edgeshooters[num][2] - sel_desc[0]
g.putcells(edgeshooters[num][0],edge_x,edge_y,1,0,0,1,"or")
delay = edgeshooters[num][4] + gliders_lanes_sorted[last_selected_glider%len(gliders)][1] - 4*safe_space - 4*sel_desc[0]
x = edge_x - delay//4 + gap_size*(len(gliders) - count)
y = edge_y + edgeshooters[num][3] - delay//4 + gap_size*(len(gliders) - count)
g.putcells(g.evolve(g.parse("$b3o$bo$2bo!"),delay%4),x-1,y-1,1,0,0,1,"copy")
else:
edge_x = -gap-edgeshooters[num][1] + edgeshooters[num][2] + edgeshooters[num][5] + sel_desc[0]
edge_y = gliders_lanes_sorted[last_selected_glider%len(gliders)][0]+gap - edgeshooters[num][2] + edgeshooters[num][5] + 1 - sel_desc[0]
g.putcells(edgeshooters[num][0],edge_x,edge_y,0,-1,-1,0,"or")
delay = edgeshooters[num][4] + gliders_lanes_sorted[last_selected_glider%len(gliders)][1] + edgeshooters[num][6] - 4*safe_space - 4*sel_desc[0]
x = edge_x + delay//4 - gap_size*(len(gliders) + count) + 1 + 2*gap_size*count
y = edge_y + edgeshooters[num][3] + delay//4 - gap_size*(len(gliders) + count) + 2*gap_size*count
g.putcells(g.evolve(g.parse("$b3o$bo$2bo!"),delay%4),x-1,y-1,-1,0,0,-1,"copy")
#remove the comparison glider
g.putcells(glider_phases[gliders_sorted[last_selected_glider%len(gliders)][0]],gliders_sorted[last_selected_glider%len(gliders)][1] - (186 + safe_space) - gap_size*len(gliders),gliders_sorted[last_selected_glider%len(gliders)][2] + (186 + safe_space) + gap_size*len(gliders),1,0,0,1,"xor")
g.update()
edgeshooter_storage.append([edge_x,edge_y,x,y,num,last_selected_glider%len(gliders),flipped%2])
def remove_edgeshooter(e):
g.putcells(edgeshooters[e[4]][0],e[0],e[1],1-e[6],-e[6],-e[6],1-e[6],"xor")
g.select([e[2]-1-e[6]*3,e[3]-1-e[6]*3,4,4])
g.clear(0)
completed_gliders[e[5]] = False
glid = gliders_sorted[e[5]]
g.putcells(glider_phases[glid[0]],glid[1],glid[2],1,0,0,1,"copy")
g.putcells(glider_phases[gliders_sorted[e[5]][0]],gliders_sorted[e[5]][1] - (186 + safe_space) - gap_size*len(gliders),gliders_sorted[e[5]][2] + (186 + safe_space) + gap_size*len(gliders),1,0,0,1,"or")
edgeshooter_storage.pop()
flipped = 0
prev_flipped = 1
flip_fix = 0
no_successes_count = -1
i = 0
while edgeshooters_placed_count < len(gliders):
if flip_mode == 2 or prev_flipped == 1:
a = 1
else:
a = -1
last_selected_glider = (a*i)%len(gliders)
g.show(str(edgeshooters_placed_count) + " gliders done. " + str(len(gliders)-edgeshooters_placed_count) + " gliders remain.")
if completed_gliders[(a*i)%len(gliders)] != True:
for x in range(0,len(edgeshooters)):
place_edgeshooter(x%4,edgeshooter_gap,edgeshooters_placed_count)
edgeshooters_placed_count += 1
edgeshooter_gap += gap_size
g.run(744 +4*safe_space + 4*gap_size*len(gliders))
if g.getcells(sel_desc) == selection:
g.reset()
completed_gliders[last_selected_glider%len(gliders)] = True
prev_flipped = flipped
flipped = (flip_mode - flipped)%2
no_successes_count = -1
break
else:
g.reset()
remove_edgeshooter(edgeshooter_storage[-1])
edgeshooters_placed_count -= 1
edgeshooter_gap -= gap_size
no_successes_count += 1
i += 1
if no_successes_count == (len(gliders)-edgeshooters_placed_count) and edgeshooters_placed_count != len(gliders):
flipped = (prev_flipped)%2
elif no_successes_count > 2*(len(gliders)-edgeshooters_placed_count) and edgeshooters_placed_count != len(gliders):
g.warn("No method of inserting the remaining gliders could be found")
g.exit("")
g.show("Success!")
Code: Select all
#place-edgeshooters-v2.py
#Goldtiger997 February 2020
#Replaced a few divisions for Python 3 compatibility, August 2020
import golly as g
gap_size = int(g.getstring("Please enter the diagonal spacing between the edgeshooters","50"))
safe_space = int(g.getstring("How much additional spacing do you want between the gliders and the edgeshooters? Increase this parameter if the script places gliders too close to the edgeshooters","50"))
sel_desc = g.getselrect()
selection = g.getcells(g.getselrect())
glider_phases = [g.parse("3o$2bo$bo!"),g.parse("bo$b2o$obo!"),g.parse("b2o$obo$2bo!"),g.parse("2o$b2o$o!")]
glider_phases_lh1 = [g.parse("3A$2.A$.A!"),g.parse(".A$.2A$A.A!"),g.parse(".2A$A.A$2.A!"),g.parse("2A$.2A$A!")]
glider_phases_lh2 = [g.parse("3C$2.C$.C!"),g.parse(".C$.2C$C.C!"),g.parse(".2C$C.C$2.C!"),g.parse("2C$.2C$C!")]
glider_phases_lh3 = [g.parse("3D$2.D$.D!"),g.parse(".D$.2D$D.D!"),g.parse(".2D$D.D$2.D!"),g.parse("2D$.2D$D!")]
gliders = []
gliders_sorted = []
gliders_lanes = []
the_numbers = ["1","2","3","4","5"] #full list ["1","2","3","4","5","6","7","8","9","0"]
#edgeshooters
#format is [rle, output glider lane adjustment, input glider lane adjustment, input glider positioning adjustment,delay of edgeshooter,flip_adjust,flip_time_adjust]
edgeshooter1 = [g.parse("18.B$17.2B$16.3B$15.4B$14.4B$13.4B$12.4B$11.4B$10.4B$9.4B$8.4B$8.4B$7.5B$4.9B$4.9B$4.9B$4.10B$3.12B$2.13B8.2A$3.11B9.A$4.12B4.BA.A$4.15B.B2A13.2A$4.17B14.B2AB$4.17B15.2B$.B.17B17.2B3.B$2A19B15.4B.B2A$2AB.19B11.8B2A$.B4.20B2.2B2.6B2AB.B$6.32B2A$6.9B.24B$7.7B2.28B$7.7B2.28B$7.6B4.26B2A$7.7B10.4B.14B2A$7.6B12.4B2.11B.B$6.7B13.4B2.10B$7.6B14.14B$8.5B15.14B$8.6B14.13B$10.4B14.13B$9.B2A2B2.2A.2A2.2A3.8B.4B$10.2A5.A.A2.A.A3.8B$17.A2.2A.B4.8B$18.A.A2.2B3.10B$17.2A.A.BA2B.7B2.2A$20.A.A.A9B2.A$17.4A2.A.8B4.3A$17.A3.2A3.7B6.A$19.A.B6.6B$18.2AB2AB3.7B$21.2AB.8B$18.2A3.10B$18.A4.6B2A3B$19.A3.6B2A2B5.2A$18.2A3.10B5.A$22.11B2.BA.A$22.12B.B2A$21.15B$20.16B$17.2B.16B$16.2A18B$16.2AB.17B$17.B.4B.8B2.4B$24.7B4.4B$25.6B5.4B$27.4B6.4B$29.3BA5.4B$30.BA.A5.3B$31.ABA6.2B$32.A8.B$33.3A$35.A!"),18,0,27,1,19,-100]
edgeshooter2 = [g.parse("22.4B$21.4B$20.4B$19.4B$18.4B5.2A$17.6B3.A2.A$16.8B.B.A.A$16.10B2A2.2A$15.11B2.2A2.A$15.11B2A3.2A$15.10B2.A$15.9B2.A$10.14B3.3A$9.13B7.A$9.14B$9.14B$9.13B$10.11B$9.14B$9.2B2A11B$10.B2A11B$10.14B$10.4B.8B$11.2B.9B3.2A$14.8B3.A.A$14.8B3.A$14.9B.2A$13.11B$12.12B$12.12B$5.2A6.10B$6.A7.11B$6.A.AB.14B$7.2AB.13B2A$9.15B2A$8.15B.B$9.14B$7.2AB.11B$6.A.AB3.9B$6.A8.8B$5.2A9.7B$13.11B$12.12B$12.12B$12.11B$2A.2A2.2A3.8B.4B$.A.A2.A.A3.7B4.2A$.A2.2A.B4.7B4.A$2.A.A2.2B.B.6B6.3A$.2A.A.BA10B8.A$4.A.A.A9B$.4A2.A.8B$.A3.2A4.6B$3.A.B6.6B$2.2AB2AB3.7B$5.2AB.8B$2.2A3.10B$2.A4.6B2A3B$3.A3.6B2A2B5.2A$2.2A3.10B5.A$6.11B2.BA.A$6.12B.B2A$5.15B$4.16B$.2B.16B$2A18B$2AB.17B$.B.4B.8B2.4B$8.7B4.4B$9.6B5.4B$11.4B6.4B$13.3BA5.4B$14.BA.A5.4B$15.ABA$16.A$17.3A$19.A!"),22,12,48,39,23,-184]
edgeshooter3 = [g.parse("18.4B$17.4B$16.4B$15.4B$14.6B7.2A$13.7B7.A$13.9B2.BA.A$9.B2.11B.B2A$9.2B.9BA3B$9.3B.7BABA2B$9.11BABA2B$10.4B.B2.3BA3B$11.4B4.6B$12.4B4.6B$13.4B3.6B$14.4B2.5B$15.14B$16.14B$17.13B$10.2A5.13B$11.A5.11B.B2A$11.A.AB2.10B2.BA.A$12.2AB.9B7.A$14.11B7.2A$14.13B$14.9B.B2A.A$15.7B2.B2AB3A$14.8B4.B4.A$15.8B2.2A.3A$16.7B3.A.A$13.11B2.A.A$12.11B4.A$12.11B$12.11B$2A.2A2.2A3.8B2.B2A$.A.A2.A.A3.7B3.BA.A$.A2.2A.B4.7B6.A$2.A.A2.2B3.6B7.2A$.2A.A.BAB2.7B$4.A.A.A2.7B$.4A2.A4.5B$.A3.2A4.6B$3.A.B6.6B$2.2AB2AB3.7B$5.2AB.8B$2.2A3.10B$2.A4.6B2A3B$3.A3.6B2A2B5.2A$2.2A3.10B5.A$6.11B2.BA.A$6.12B.B2A$5.15B$4.16B$.2B.16B$2A18B$2AB.17B$.B.4B.8B2.4B$8.7B4.4B$9.6B5.4B$11.4B6.4B$13.3BA5.4B$14.BA.A5.4B$15.A.A6.4B$16.A8.4B$17.3A6.4B$19.A7.4B$28.4B!"),18,4,37,14,19,-140]
edgeshooter4 = [g.parse("17.4B$16.4B$15.4B$14.4B$13.4B$12.4B$11.4B$10.4B$9.7B$9.9B$8.11B$5.13B$4.14B$3.16B$3.17B$2.18B$2.19B$.20B19.A$20B20.3A$.21B21.A$.21B20.2A$3.19B20.B8.A$2.B.17B19.3B6.3A$4.18B16.6B4.A$4.20B11.10B3.2A$5.22B2.2B3.16B$5.34B2A7B$7.32B2A9B$8.42B$8.42B$8.44B$8.13B4.4B.13B.9B$8.6B4.3B5.3B5.B.19B$7.7B5.4B4.4B12.14B$8.6B7.2A6.2A11.15B$9.6B6.A7.A12.14B$9.6B7.3A5.3A9.13B$8.8B8.A7.A6.15B$9.6B17.A.AB2.15B$8.7B18.2AB.17B$6.11B18.19B$4.9B2A2B.B15.19B$4.9B2A3B2A15.20B2.2A$4.14B2A13.2AB.16B2A.A.A$5.14B13.A.AB2.13B.B2ABA$5.3B.2B2.B2.5B11.A6.11B4.B2.A$5.2A5.3B4.2A10.2A7.11B2.2A.2A$6.A5.B2AB3.A17.14B3.A.A$3.3A7.2A5.3A13.16B2.A.A$3.A18.A4.2A7.13B.B2A.2A$26.A2.A2.2A2.13B.BA.A$27.2A2.A.A2.8B.2B6.A$29.2A.B3.7B10.2A$29.A2.2B2.7B$26.2A.A.BA2B.6B$26.A.2A.A.A8B$30.A.A.8B$27.2A2.A2.7B$25.3A.2A4.6B$24.A4.B6.6B$25.3AB2AB3.7B$27.A.2AB.8B$31.10B$31.6B2A3B$31.6B2A2B5.2A$31.10B5.A$30.11B2.BA.A$30.12B.B2A$29.15B$28.16B$25.2B.16B$24.2A18B$24.2AB.17B$25.B.4B.8B2.4B$32.7B4.4B$33.6B5.4B$35.4B6.4B$37.3BA5.4B$38.BA.A5.4B$39.ABA6.4B$40.A8.3B$41.3A6.B$43.A!"),17,0,30,87,18,-112]
edgeshooter5 = [g.parse("23.4B$22.4B$21.4B$20.4B$19.4B$18.4B$17.4B$16.4B$3.2A10.4B$4.A9.4B$2.A10.4B$2.5A5.4B5.2A$7.A4.4B5.A$4.3AB2.7B.BA.A$3.A.2B3.7B.B2A$3.4A12B$.2A2.BA3B2A7B$A2.3AB.2B2A7B$2A.A.B3.10B$3.A8.8B$3.2A7.9B$13.3B2.4B$11.5B3.4B$11.2A7.4B$12.A8.3B$9.3A10.2B$9.A13.B!"),23,-14,2,-76,24,0]
edgeshooters = [edgeshooter1,edgeshooter2,edgeshooter3,edgeshooter4,edgeshooter5]
if g.getselrect() == []:
g.warn("Please select some northeast heading gliders")
g.exit()
g.shrink()
#crude glider detection
def find_glider(phase_num):
count = 0
size = ((sel_desc[2]-2)*(sel_desc[3]-2))
for i in range(0,sel_desc[2]-2):
for j in range(0,sel_desc[3]-2):
x = sel_desc[0]+i
y = sel_desc[1]+j
g.select([x,y,3,3])
old_patt = g.getcells(g.getselrect()) #for restoration
g.putcells(glider_phases[phase_num],x,y,1,0,0,1,"xor")
if len(g.getcells(g.getselrect())) == 0:
gliders.append([phase_num,x,y])
g.clear(0)
g.putcells(old_patt,0,0,1,0,0,1,"or")
count += 1
g.show(str(25*phase_num + count*25/size) + "% glider detection done")
for i in range(0,4):
find_glider(i)
if len(gliders) == 0:
g.warn("Your selection has no (detectable) gliders")
g.exit()
g.setrule("LifeHistory")
#now convert into format of [[lane,point on that lane]...]
for glid in gliders:
if glid[0] == 0:
gliders_lanes.append([glid[2]+glid[1],glid[1]*4])
elif glid[0] == 1:
gliders_lanes.append([glid[2]+glid[1] + 1,glid[1]*4 + 1])
elif glid[0] == 2:
gliders_lanes.append([glid[2]+glid[1] + 1,glid[1]*4 + 2])
elif glid[0] == 3:
gliders_lanes.append([glid[2]+glid[1],glid[1]*4 - 1])
gliders_lanes_sorted = sorted(gliders_lanes, key = lambda x: x[0])[::-1]
for e in gliders_lanes_sorted:
gliders_sorted.append(gliders[gliders_lanes.index(e)])
#g.note(str(gliders_lanes_sorted))
last_selected_glider = 0
completed_gliders = []
for blah_blah_blah in gliders:
completed_gliders.append(False)
last_selected_glider = -1
#highlight gliders in the white LifeHistory state
def select_glider(num):
global last_selected_glider
glid = gliders_sorted[num%len(gliders)]
g.putcells(glider_phases_lh2[glid[0]],glid[1],glid[2],1,0,0,1,"copy")
#revert previous selected glider to its previous state
if completed_gliders[last_selected_glider%len(gliders)] == False:
old_glid = gliders_sorted[last_selected_glider%len(gliders)]
g.putcells(glider_phases_lh1[old_glid[0]],old_glid[1],old_glid[2],1,0,0,1,"copy")
else:
old_glid = gliders_sorted[last_selected_glider%len(gliders)]
g.putcells(glider_phases_lh3[old_glid[0]],old_glid[1],old_glid[2],1,0,0,1,"copy")
last_selected_glider = num
select_glider(0)
g.putcells(selection,-(186 + safe_space) - gap_size*len(gliders),(186 + safe_space) + gap_size*len(gliders),1,0,0,1,"or")
g.update()
def find_glider_from_click(x,y):
answer = ""
for i in range(0,len(gliders)):
if gliders_sorted[i][1] - x >= -4 and gliders_sorted[i][1] - x <= 1 and gliders_sorted[i][2] - y >= -4 and gliders_sorted[i][2] - y <= 1:
answer = i
break
return answer
edgeshooter_gap = 150
edgeshooters_placed_count = 0
edgeshooter_storage = [] #to facilitate deletion
def place_edgeshooter(num,gap,count):
if flipped%2 == 0:
edge_x = -gap-edgeshooters[num][1] + edgeshooters[num][2] + sel_desc[0]
edge_y = gliders_lanes_sorted[last_selected_glider%len(gliders)][0]+gap - edgeshooters[num][2] - sel_desc[0]
g.putcells(edgeshooters[num][0],edge_x,edge_y,1,0,0,1,"or")
delay = edgeshooters[num][4] + gliders_lanes_sorted[last_selected_glider%len(gliders)][1] - 4*safe_space - 4*sel_desc[0]
x = edge_x - delay//4 + gap_size*(len(gliders) - count)
y = edge_y + edgeshooters[num][3] - delay//4 + gap_size*(len(gliders) - count)
g.putcells(g.evolve(g.parse("$b3o$bo$2bo!"),delay%4),x-1,y-1,1,0,0,1,"copy")
else:
edge_x = -gap-edgeshooters[num][1] + edgeshooters[num][2] + edgeshooters[num][5] + sel_desc[0]
edge_y = gliders_lanes_sorted[last_selected_glider%len(gliders)][0]+gap - edgeshooters[num][2] + edgeshooters[num][5] + 1 - sel_desc[0]
g.putcells(edgeshooters[num][0],edge_x,edge_y,0,-1,-1,0,"or")
delay = edgeshooters[num][4] + gliders_lanes_sorted[last_selected_glider%len(gliders)][1] + edgeshooters[num][6] - 4*safe_space - 4*sel_desc[0]
x = edge_x + delay//4 - gap_size*(len(gliders) + count) + 1 + 2*gap_size*count
y = edge_y + edgeshooters[num][3] + delay//4 - gap_size*(len(gliders) + count) + 2*gap_size*count
g.putcells(g.evolve(g.parse("$b3o$bo$2bo!"),delay%4),x-1,y-1,-1,0,0,-1,"copy")
#remove the comparison glider
g.putcells(glider_phases[gliders_sorted[last_selected_glider%len(gliders)][0]],gliders_sorted[last_selected_glider%len(gliders)][1] - (186 + safe_space) - gap_size*len(gliders),gliders_sorted[last_selected_glider%len(gliders)][2] + (186 + safe_space) + gap_size*len(gliders),1,0,0,1,"xor")
g.update()
edgeshooter_storage.append([edge_x,edge_y,x,y,num,last_selected_glider%len(gliders),flipped%2])
def remove_edgeshooter(e):
g.putcells(edgeshooters[e[4]][0],e[0],e[1],1-e[6],-e[6],-e[6],1-e[6],"xor")
g.select([e[2]-1-e[6]*3,e[3]-1-e[6]*3,4,4])
g.clear(0)
g.update()
completed_gliders[e[5]] = False
glid = gliders_sorted[e[5]]
g.putcells(glider_phases_lh1[glid[0]],glid[1],glid[2],1,0,0,1,"copy")
select_glider(last_selected_glider%len(gliders))
g.putcells(glider_phases[gliders_sorted[e[5]][0]],gliders_sorted[e[5]][1] - (186 + safe_space) - gap_size*len(gliders),gliders_sorted[e[5]][2] + (186 + safe_space) + gap_size*len(gliders),1,0,0,1,"or")
g.update()
edgeshooter_storage.pop()
flipped = 0
while True:
event = g.getevent()
if event.startswith("key h"):
g.note("Commmands:\n\n- press the up and down arrows to toggle between the gliders\n- alternatively, click on a glider to select it\n- press the number keys to place one of the five supported edgeshooters\n- press d to delete the most recently placed edgeshooter\n- press t to test the current pattern\n- press r to return from the testing to generation 0\n- press f to fit the entire pattern into the viewport\n- press x to copy the current pattern to the clipboard\n- press k to toggle between inserting the gliders from the NE and the SW\n- press [ to zoom out\n- press ] to zoom in\n - press v view the gliders")
if event.startswith("key f"):
g.fit()
g.update()
if event.startswith("key v"):
g.select(sel_desc)
g.fitsel()
g.update()
if event.startswith("key ["):
g.setmag(g.getmag() - 1)
g.update()
if event.startswith("key ]"):
g.setmag(g.getmag() + 1)
g.update()
if event.startswith("key x"):
g.select(g.getrect())
g.copy()
g.select([])
if g.getgen() == "0":
if flipped%2 == 0:
g.show("Press <h> for help. Press <esc> to quit the script with the current edgeshooters. Currently inserting from the SE")
else:
g.show("Press <h> for help. Press <esc> to quit the script with the current edgeshooters. Currently inserting from the NW")
if event.startswith("click"):
ans = find_glider_from_click(int(event.split()[1]),int(event.split()[2]))
if ans != "":
select_glider(ans)
g.update()
elif event.startswith("key up"):
select_glider(last_selected_glider+1)
g.update()
elif event.startswith("key down"):
select_glider(last_selected_glider-1)
g.update()
elif event.startswith("key k"):
flipped += 1
elif event.startswith("key t"):
g.run(744 + 4*safe_space + 4*gap_size*len(gliders))
g.update()
elif event.startswith("key d"):
if edgeshooter_storage != []:
remove_edgeshooter(edgeshooter_storage[-1])
edgeshooters_placed_count -= 1
edgeshooter_gap -= gap_size
elif event.startswith("key ") and event[4] in the_numbers:
if completed_gliders[last_selected_glider%len(gliders)]:
g.note("this glider has already had an edgeshooter constructed")
else:
place_edgeshooter(the_numbers.index(event[4]),edgeshooter_gap,edgeshooters_placed_count)
edgeshooter_gap += gap_size
edgeshooters_placed_count += 1
completed_gliders[last_selected_glider%len(gliders)] = True
else:
g.show("Advanced pattern to generation " + str(744 + 4*safe_space + 4*gap_size*len(gliders)) + ". Press <r> to return to generation 0")
if event.startswith("key r"):
g.reset()
g.update()
1444th post