Sorry, I should have been more clear. LUCA is the name of this ship
LUCA stands for Last universal common ancestor. It is named that way because it is the foundation of 48 speeds of ship in the rule. I am looking for something that will function like a gliderStdin symmetry.
I modified Nbsearch2a to do it, although it only works for synths without dust.
Code: Select all
import golly as g
import math
from random import *
from timeit import default_timer as timer
from glife.text import make_text
from glife import getminbox, rect
autoRAB=True #automatically detect rule, algorithm and border
group_by_period=True
auto_exclude=5 #maximal number of oscillators of specific period (if group_by_period)
show_periods=True #print list of periods (if group_by_period)
auto_stop=True #stop if no more oscillators can be added (if group_by_period)
max_period=1000
result_spacing=200
stab_step=3000
#x=1
#main_fill=50
count_update=1000
if autoRAB:
rule=g.getrule()
algo=g.getalgo()
if ":" in rule:
rule,bound=rule.split(":")
bound=":"+bound
else: bound=""
else:
rule=g.getstring("Rule:","B3/S23")
algo=g.getstring("Algorithm:","QuickLife")
bound=g.getstring("Bound:","T32,32")
if not (bound=="" or bound.startswith(":")): bound=":"+bound
s=g.getstring("Symmetry","All")
symm=0
if s!="All":
symm=s
#symm can be either C1, C2_1, C2_2, C2_4, D2_x, D2_+1, D2_+2, C4_1, C4_4, D4_x1, D4_x4, D4_+1, D4_+2, D4_+4, D8_1, D8_4, All, Rot
max_period+=1
oc=[0]*max_period
exclude_periods=[]
def all_periods(q):
if not show_periods: return ""
gmin = gmax = 0
text = "["
for i in q+[0]:
if i==0: text += str(gmin) + ("-"+str(gmax)+"]" if gmax>gmin else "]")
elif gmin==0: gmin = gmax = i
elif i-gmax==1: gmax = i
else:
text += str(gmin) + ("-"+str(gmax)+"," if gmax>gmin else ",")
gmin = gmax = i
return text
def osc_test():
global exclude_periods
if g.empty():
return False
testcells=g.getcells(g.getrect())
testpop=g.getpop() # String representation
testhash=g.hash(g.getrect())
for i in range(1,max_period):
g.run(1)
if g.empty():
return False
if g.getpop()==testpop and g.hash(g.getrect())==testhash:
if g.getcells(g.getrect())!=testcells:
if i not in exclude_periods:
if auto_exclude==1: exclude_periods+=[i]
return i
return 0
return 0
def put_symm(cell_list,x0=0,y0=0,axx=1,axy=0,ayx=0,ayy=1,mode="or"):
global symm
if s=="All":
symm=["C1", "C2_1", "C2_2", "C2_4", "D2_x", "D2_+1", "D2_+2", "C4_1", "C4_4", "D4_x1", "D4_x4", "D4_+1", "D4_+2", "D4_+4", "D8_1", "D8_4"][randrange(16)]
if s=="Shipnod":
symm=["C1", "D2_+1", "D2_+2"][randrange(3)]
if s=="Ship+":
symm=["D2_+1", "D2_+2"][randrange(2)]
# g.putcells(cell_list,x0,y0,axx,axy,ayx,ayy,mode)
if symm=="C2_1" or symm=="C4_1" or symm=="D4_+1" or symm=="D8_1" or symm=="D4_x1":
g.putcells(cell_list,-x0,-y0,-axx,-axy,-ayx,-ayy,mode)
if symm=="C4_1" or symm=="D8_1":
g.putcells(cell_list,y0,-x0,ayx,ayy,-axx,-axy,mode)
g.putcells(cell_list,-y0,x0,-ayx,-ayy,axx,axy,mode)
if symm=="C2_2" or symm=="D4_+2":
g.putcells(cell_list,-x0-1,-y0,-axx,-axy,-ayx,-ayy,mode)
if symm=="C2_4" or symm=="C4_4" or symm=="D4_+4" or symm=="D8_4" or symm=="D4_x4":
g.putcells(cell_list,-x0-1,-y0-1,-axx,-axy,-ayx,-ayy,mode)
if symm=="D2_+1" or symm=="D8_1" or symm=="D4_+1":
g.putcells(cell_list,-x0,y0,-axx,-axy,ayx,ayy,mode)
if symm=="D4_+1" or symm=="D8_1" or symm=="D4_+2":
g.putcells(cell_list,x0,-y0,axx,axy,-ayx,-ayy,mode)
if symm=="D2_+2" or symm=="D4_+2" or symm=="D4_+4" or symm=="D8_4":
g.putcells(cell_list,-x0-1,y0,-axx,-axy,ayx,ayy,mode)
if symm=="D4_+4" or symm=="D8_4":
g.putcells(cell_list,x0,-y0-1,axx,axy,-ayx,-ayy,mode)
if symm=="C4_4" or symm=="D8_4":
g.putcells(cell_list,y0,-x0-1,ayx,ayy,-axx,-axy,mode)
g.putcells(cell_list,-y0-1,x0,-ayx,-ayy,axx,axy,mode)
if symm=="D8_4":
g.putcells(cell_list,-y0-1,-x0-1,-ayx,-ayy,-axx,-axy,mode)
if symm=="D2_x" or symm=="D8_1" or symm=="D8_4" or symm=="D4_x1" or symm=="D4_x4":
g.putcells(cell_list,y0,x0,ayx,ayy,axx,axy,mode)
if symm=="D4_x1" or symm=="D8_1":
g.putcells(cell_list,-y0,-x0,-ayx,-ayy,-axx,-axy,mode)
if symm=="D4_x4" or symm=="D8_4":
g.putcells(cell_list,-y0-1,-x0-1,-ayx,-ayy,-axx,-axy,mode)
def clear_layer():
r = g.getrect()
if r:
g.select(r)
g.clear(0)
return
ship1 = g.parse("""
bo$obo!
""")
ship2 = g.parse("""
obo$bo!
""")
shipa=[]
shipb=[]
clear_layer()
g.putcells(ship2,0,0)
for i in range(800):
shipb.append(g.getcells(g.getrect()))
g.run(1)
def main():
global oc
g.new("RandOsc")
g.setrule(rule+bound)
g.setalgo(algo)
g.setbase(2)
test_layer=g.getlayer()
if g.numlayers()<g.maxlayers():
results_layer=g.addlayer()
g.setname('OscResults')
g.setrule(rule)
for i in range(max_period-1):
t = make_text(str(i+1), "mono")
t.put((i+1)*result_spacing,0)
g.setlayer(test_layer)
else:
resultslayer=-1
results=0
count=0
prevcount=0
t_start=timer()
t_prev=t_start
vr=0
ad=-20
while True:
clear_layer()
#g.select([0,0,x,x])
#g.randfill(main_fill)
g.putcells(ship1,0,0)
g.putcells(shipb[randrange(800)],randint(0,40),randint(35,70))
cell_list=g.getcells(g.getrect())
put_symm(cell_list)
g.run(stab_step)
test=osc_test()
if test>0:
osc = g.getcells(g.getrect())
if group_by_period:
if oc[test]==0: results+=1
if oc[test]<auto_exclude:
if results_layer>=0:
oc[test]+=1
g.setlayer(results_layer)
g.putcells(cell_list, result_spacing*test, result_spacing*oc[test])
g.setname('OscResults (%d)' % results)
g.fit()
g.update()
g.setlayer(test_layer)
g.setname('RandOsc (%d)' % results)
else:
return True
else:
results+=1
if results_layer>=0:
g.setlayer(results_layer)
g.putcells(cell_list, result_spacing*results, 0)
g.setname('OscResults (%d)' % results)
g.fit()
g.update()
g.setlayer(test_layer)
g.setname('RandOsc (%d)' % results)
else:
return True
count+=1
if count%count_update==0:
t_end=timer()
g.show("%d results found after %d soups tested (%d/sec current, %d/sec overall)" % (results, count, (count-prevcount)/(t_end-t_prev), (count)/(t_end-t_start))+" "+all_periods([i for i in range(max_period) if oc[i]>0]))
g.select([])
g.update()
g.new("")
g.setbase(2)
t_prev=t_end
prevcount=count
if auto_stop and auto_exclude>0:
if sum(oc)==(max_period-1-len([i for i in exclude_periods if i<max_period]))*auto_exclude: break
main()
This only looks for 2 ship 180 degree synths, and even though this covers most all possible configurations, it may be useful to reduce the number of gens of ship2 to pick from and reduce the possible x offset