I improved the script and here it is!
Code: Select all
# Solid.py
# Makes soups and runs oscar until a ship is found
# Seemingly stupid but actually very useful and fast
# Mainly used for searching "Solid" ships in LTL since soups of the right size
# produce only 1 object and separation is not needed so oscar can be run.
# Best fit for solid LTL rules that have lower period oscs that stabilize quicker but can also be used for larger ranges.
# Beeps when a ship is found.
# By Saka with oscar.py code from Andrew Trevorrow.
import golly as g
if len(g.getselrect()) == 0:
g.exit("No selection!")
else:
selection = g.getselrect()
g.new("Solid")
g.select(selection)
g.fitsel()
result = "Soup"
#maxGen = int(g.getstring("Maximum gens (To avoid expanding soups)")) # Maximum gens and population to avoid expanding soups
maxPop = (selection[2]*selection[3])*10 #This is much, much better
n = -1
while result != "S": #Old and not used anymore but whatever.
#g.setgen('0')
n += 1
if n % 100==0:
g.show(str(n)+" soups searched")
g.update()
g.reset()
g.randfill(50)
# The entire code of oscar.py :)
# Oscar is an OSCillation AnalyzeR for use with Golly.
# Author: Andrew Trevorrow (andrew@trevorrow.com), March 2006.
from glife import rect, pattern
from time import time
# --------------------------------------------------------------------
# initialize lists
hashlist = [] # for pattern hash values
genlist = [] # corresponding generation counts
poplist = [] # corresponding population counts
boxlist = [] # corresponding bounding boxes
# --------------------------------------------------------------------
def show_spaceship_speed(period, deltax, deltay):
# we found a moving oscillator
if (deltax == deltay) or (deltax == 0) or (deltay == 0):
speed = ""
if (deltax == 0) or (deltay == 0):
# orthogonal spaceship
if (deltax > 1) or (deltay > 1):
speed += str(deltax + deltay)
else:
# diagonal spaceship (deltax == deltay)
if deltax > 1:
speed += str(deltax)
if period == 1:
g.show("S")
g.exit("Found ship with speed " + speed + "c"+" after "+str(n)+" soups.")
else:
g.show("S")
g.exit("Found ship with speed " + speed + "c/" +str(period)+" after "+str(n)+" soups.")
else:
# deltax != deltay and both > 0
speed = str(deltay) + "," + str(deltax)
if period == 1:
g.show("S")
g.exit("Found knightship with speed " + speed + "c"+" after "+str(n)+" soups.")
else:
g.show("S")
g.exit("Found knightship with speed " + speed + "c/" + str(period)+" after "+str(n)+" soups.")
# --------------------------------------------------------------------
def oscillating():
# return True if the pattern is empty, stable or oscillating
# first get current pattern's bounding box
prect = g.getrect()
pbox = rect(prect)
if pbox.empty:
#g.show("The pattern is empty.")
return True
# get current pattern and create hash of "normalized" version -- ie. shift
# its top left corner to 0,0 -- so we can detect spaceships and knightships
h = g.hash(prect)
# check if outer-totalistic rule has B0 but not S8
rule = g.getrule().split(":")[0]
hasB0notS8 = rule.startswith("B0") and (rule.find("/") > 1) and not rule.endswith("8")
# determine where to insert h into hashlist
pos = 0
listlen = len(hashlist)
while pos < listlen:
if h > hashlist[pos]:
pos += 1
elif h < hashlist[pos]:
# shorten lists and append info below
del hashlist[pos : listlen]
del genlist[pos : listlen]
del poplist[pos : listlen]
del boxlist[pos : listlen]
break
else:
# h == hashlist[pos] so pattern is probably oscillating, but just in
# case this is a hash collision we also compare pop count and box size
if (int(g.getpop()) == poplist[pos]) and \
(pbox.wd == boxlist[pos].wd) and \
(pbox.ht == boxlist[pos].ht):
period = int(g.getgen()) - genlist[pos]
if hasB0notS8 and (period % 2 > 0) and (pbox == boxlist[pos]):
# ignore this hash value because B0-and-not-S8 rules are
# emulated by using different rules for odd and even gens,
# so it's possible to have identical patterns at gen G and
# gen G+p if p is odd
return False
if pbox == boxlist[pos]:
# pattern hasn't moved
if period == 1:
pass
#g.show("SL")
else:
pass
#g.show("OSC")
else:
deltax = abs(boxlist[pos].x - pbox.x)
deltay = abs(boxlist[pos].y - pbox.y)
show_spaceship_speed(period, deltax, deltay)
return True
else:
# look at next matching hash value or insert if no more
pos += 1
# store hash/gen/pop/box info at same position in various lists
hashlist.insert(pos, h)
genlist.insert(pos, int(g.getgen()))
poplist.insert(pos, int(g.getpop()))
boxlist.insert(pos, pbox)
return False
# --------------------------------------------------------------------
def fit_if_not_visible():
# fit pattern in viewport if not empty and not completely visible
r = rect(g.getrect())
if (not r.empty) and (not r.visible()): g.fit()
# --------------------------------------------------------------------
#g.show("Checking for oscillation... (hit escape to abort)")
oldsecs = time()
while not oscillating():
g.run(1)
newsecs = time()
#if newsecs - oldsecs >= 1.0: # show pattern every second
#oldsecs = newsecs
#fit_if_not_visible()
#g.update()
if int(g.getpop()) > maxPop: #If not: Use int(g.getgen()) > maxGen
break
Mostly just oscar.py
It has found quite a few ships, not released yet, still in my "Solid" folder.
How to use:
1. Use slowshipconvert.py in the top post (
here) to convert to the desired range.
2. (Optional) Tweak the limits a bit, +-5 or something.
3. Select an area to search. Make sure that a 50% fill of the area produces only 1 "donut" when you fill it or else oscar will get stuck if it finds a osc+ship or ship+ship. Expanding soups will be skipped using a "smart maxPop" I made.
4. Still selecting the area, run solid.py
5. Wait until a ship is found (It will beep because it uses g.exit)
TODO:
-Display approximate soups/sec
-After a set amount of failed soups, adjust the rule and start over
EDIT:
VERY FAST c/10o with a very thin core found with the script
Code: Select all
x = 28, y = 28, rule = R10,C0,M1,S154..256,B133..269,NM
12b3o$11b6o$10bob3o$11b5o$11b6o$10b7o$9b9o$9b10o$8b12o$7b14o$5b18o2bo$
bo2b8o3b10obo$11o5b11o$11o6b11o$10o7b11o$11o6b11o$12o4b9obo$bo2b9ob9o$
6b16o$8b12o$9b10o$9b9o$10b8o$11b6o$11b5o$11b5o$11b6o$12b4o!
Turns out the original slow ship rule has a 2c/542o!
Code: Select all
x = 24, y = 25, rule = R10,C0,M1,S154..262,B133..265,NM
10b6o$11b7o$6bo2b10o$5bob12o$4bob14o$3b18o$2b18o$b10o3b7o$9o6b7o$8o8b
6obo$7o10b7o$7o10b7o$7o10b7o$7o10b7o$ob6o9b7o$2b6o8b8o$3b6o6b9o$3b8o2b
10o$4b18o$3b16obo$4b14obo$5b11o2bo$6b9o$7b5o3bo$9b4o!