Here are a couple of scripts that may be useful.
The first is fromgliderdb.py, which takes the glider database, and converts it into a format usable by the other scripts. Remove the top commented section before converting. This should create a new .py file with the database in a different format, gliderlistOT.py.
The second is Glider_DatabaseOT.py, which displays all known ships in the glider database converted by the first script in Golly.
The third is getallisorule2.py, which is a modified version of the original that allows the other parts to work.
The fourth is torulestringOT.py, which allows you to paste a new ship into Golly (assuming it is in the correct rule, and travel is oriented between up and up-right), and type in the period and displacement to add it to the database. You may be prompted to type in the period twice, for reasons I have yet to find out, but it still works.
If anything is unclear or you have improvements, please say so. Credits to the majority of the parts of the code goes to Nathaniel Johnston, Peter Naszvadi, and Arie Paap.
Code: Select all
#torulestringOT.py. Paste a ship you want to add to the database into Golly, and run this script. It will ask for period and displacement, and once those are provided, the ship will be added to the database.
import golly as g
import os
import sys
Outfile = "gliderlistOT.py"
#g.new("")
class RuleGenerator:
notationdict = {
"0" : [0,0,0,0,0,0,0,0], #
"1e" : [1,0,0,0,0,0,0,0], # N
"1c" : [0,1,0,0,0,0,0,0], # NE
"2a" : [1,1,0,0,0,0,0,0], # N, NE
"2e" : [1,0,1,0,0,0,0,0], # N, E
"2k" : [1,0,0,1,0,0,0,0], # N, SE
"2i" : [1,0,0,0,1,0,0,0], # N, S
"2c" : [0,1,0,1,0,0,0,0], # NE, SE
"2n" : [0,1,0,0,0,1,0,0], # NE, SW
"3a" : [1,1,1,0,0,0,0,0], # N, NE, E
"3n" : [1,1,0,1,0,0,0,0], # N, NE, SE
"3r" : [1,1,0,0,1,0,0,0], # N, NE, S
"3q" : [1,1,0,0,0,1,0,0], # N, NE, SW
"3j" : [1,1,0,0,0,0,1,0], # N, NE, W
"3i" : [1,1,0,0,0,0,0,1], # N, NE, NW
"3e" : [1,0,1,0,1,0,0,0], # N, E, S
"3k" : [1,0,1,0,0,1,0,0], # N, E, SW
"3y" : [1,0,0,1,0,1,0,0], # N, SE, SW
"3c" : [0,1,0,1,0,1,0,0], # NE, SE, SW
"4a" : [1,1,1,1,0,0,0,0], # N, NE, E, SE
"4r" : [1,1,1,0,1,0,0,0], # N, NE, E, S
"4q" : [1,1,1,0,0,1,0,0], # N, NE, E, SW
"4i" : [1,1,0,1,1,0,0,0], # N, NE, SE, S
"4y" : [1,1,0,1,0,1,0,0], # N, NE, SE, SW
"4k" : [1,1,0,1,0,0,1,0], # N, NE, SE, W
"4n" : [1,1,0,1,0,0,0,1], # N, NE, SE, NW
"4z" : [1,1,0,0,1,1,0,0], # N, NE, S, SW
"4j" : [1,1,0,0,1,0,1,0], # N, NE, S, W
"4t" : [1,1,0,0,1,0,0,1], # N, NE, S, NW
"4w" : [1,1,0,0,0,1,1,0], # N, NE, SW, W
"4e" : [1,0,1,0,1,0,1,0], # N, E, S, W
"4c" : [0,1,0,1,0,1,0,1], # NE, SE, SW, NW
"5i" : [1,1,1,1,1,0,0,0], # N, NE, E, SE, S
"5j" : [1,1,1,1,0,1,0,0], # N, NE, E, SE, SW
"5n" : [1,1,1,1,0,0,1,0], # N, NE, E, SE, W
"5a" : [1,1,1,1,0,0,0,1], # N, NE, E, SE, NW
"5q" : [1,1,1,0,1,1,0,0], # N, NE, E, S, SW
"5c" : [1,1,1,0,1,0,1,0], # N, NE, E, S, W
"5r" : [1,1,0,1,1,1,0,0], # N, NE, SE, S, SW
"5y" : [1,1,0,1,1,0,1,0], # N, NE, SE, S, W
"5k" : [1,1,0,1,0,1,1,0], # N, NE, SE, SW, W
"5e" : [1,1,0,1,0,1,0,1], # N, NE, SE, SW, NW
"6a" : [1,1,1,1,1,1,0,0], # N, NE, E, SE, S, SW
"6c" : [1,1,1,1,1,0,1,0], # N, NE, E, SE, S, W
"6k" : [1,1,1,1,0,1,1,0], # N, NE, E, SE, SW, W
"6e" : [1,1,1,1,0,1,0,1], # N, NE, E, SE, SW, NW
"6n" : [1,1,1,0,1,1,1,0], # N, NE, E, S, SW, W
"6i" : [1,1,0,1,1,1,0,1], # N, NE, SE, S, SW, NW
"7c" : [1,1,1,1,1,1,1,0], # N, NE, E, SE, S, SW, W
"7e" : [1,1,1,1,1,1,0,1], # N, NE, E, SE, S, SW, NW
"8" : [1,1,1,1,1,1,1,1], # N, NE, E, SE, S, SW, W, NW
}
allneighbours = [
["0"],
["1e", "1c"],
["2a", "2e", "2k", "2i", "2c", "2n"],
["3a", "3n", "3r", "3q", "3j", "3i", "3e", "3k", "3y", "3c"],
["4a", "4r", "4q", "4i", "4y", "4k", "4n", "4z", "4j", "4t", "4w", "4e", "4c"],
["5i", "5j", "5n", "5a", "5q", "5c", "5r", "5y", "5k", "5e"],
["6a", "6c", "6k", "6e", "6n", "6i"],
["7c", "7e"],
["8"],
]
allneighbours_flat = [n for x in allneighbours for n in x]
numneighbours = len(notationdict)
# Use dict to store rule elements, initialised by setrule():
bee = {}
ess = {}
alphanumeric = ""
rulename = ""
# Save the isotropic rule
def saveAllRules(self):
self.saveIsotropicRule()
# Interpret birth or survival string
def ruleparts(self, part):
inverse = False
nlist = []
totalistic = True
rule = { k: False for k, v in self.notationdict.iteritems() }
# Reverse the rule string to simplify processing
part = part[::-1]
for c in part:
if c.isdigit():
d = int(c)
if totalistic:
# Add all the neighbourhoods for this value
for neighbour in self.allneighbours[d]:
rule[neighbour] = True
elif inverse:
# Add all the neighbourhoods not in nlist for this value
for neighbour in self.allneighbours[d]:
if neighbour[1] not in nlist:
rule[neighbour] = True
else:
# Add all the neighbourhoods in nlist for this value
for n in nlist:
neighbour = c + n
if neighbour in rule:
rule[neighbour] = True
else:
# Error
return {}
inverse = False
nlist = []
totalistic = True
elif (c == '-'):
inverse = True
else:
totalistic = False
nlist.append(c)
return rule
# Set isotropic, non-totalistic rule
# Adapted from Eric Goldstein's HenselNotation->Ruletable(1.3).py
def setrule(self, rulestring):
# neighbours_flat = [n for x in neighbours for n in x]
b = {}
s = {}
sep = ''
birth = ''
survive = ''
rulestring = rulestring.lower()
if '/' in rulestring:
sep = '/'
elif '_' in rulestring:
sep = '_'
elif (rulestring[0] == 'b'):
sep = 's'
else:
sep = 'b'
survive, birth = rulestring.split(sep)
if (survive[0] == 'b'):
survive, birth = birth, survive
survive = survive.replace('s', '')
birth = birth.replace('b', '')
b = self.ruleparts(birth)
s = self.ruleparts(survive)
if b and s:
self.alphanumeric = 'B' + birth + 'S' + survive
self.rulename = 'B' + birth + '_S' + survive
self.bee = b
self.ess = s
else:
# Error
g.note("Unable to process rule definition.\n" +
"b = " + str(b) + "\ns = " + str(s))
g.exit()
# Save a rule file:
def saverule(self, name, comments, table, colours):
ruledir = g.getdir("rules")
filename = ruledir + name + ".rule"
global results
results = ""
results += table
# Only create a rule file if it doesn't already exist; this avoids
# concurrency issues when booting an instance of apgsearch whilst
# one is already running.
# Defines a variable:
def newvar(self, name, vallist):
line = "var "+name+"={"
for i in xrange(len(vallist)):
if (i > 0):
line += ','
line += str(vallist[i])
line += "}\n"
return line
# Defines a block of equivalent variables:
def newvars(self, namelist, vallist):
block = "\n"
for name in namelist:
block += self.newvar(name, vallist)
return block
def scoline(self, chara, charb, left, right, amount):
line = str(left) + ","
for i in xrange(8):
if (i < amount):
line += chara
else:
line += charb
line += chr(97 + i)
line += ","
line += str(right) + "\n"
return line
def isotropicline(self, chara, charb, left, right, n):
line = str(left) + ","
neighbours = self.notationdict[n]
for i in xrange(8):
if neighbours[i]:
line += chara
else:
line += charb
line += chr(97 + i)
line += ","
line += str(right) + "\n"
return line
def saveIsotropicRule(self):
table = """"""
for n in self.allneighbours_flat:
if self.bee[n]:
table += "1"
else:
table += "0"
for n in self.allneighbours_flat:
if self.ess[n]:
table += "1"
else:
table += "0"
colours = ""
comments = ""
self.saverule(self.rulename, comments, table, colours)
import golly as g
if __name__ == "__builtin__":
import getallisorule2; reload(getallisorule2)
a = str(getallisorule2.ruleres)
else:
import getallisorule3; reload(getallisorule3)
a = str(getallisorule3.ruleres)
min,max = a.split("-")
min = str(min.strip())
max = str(max.strip())
rulestring = min #g.getstring("Enter minimum rule string:")
rulestring2 = max #g.getstring("Enter maximum rule string:")
rg = RuleGenerator()
rg.setrule(rulestring)
rg.saveIsotropicRule()
q = results
rg.setrule(rulestring2)
rg.saveIsotropicRule()
t = results
g.setrule(rulestring)
# g.show(results)
final = ""
for z in range(len(q)):
if q[z] == t[z]:
final+=q[z]
else:
final+="2"
tfinal=""
def ch(a,b):
global final
if "0" in final[a:b]:
return "0"
elif "1" in final[a:b]:
return "1"
else:
return "2"
tfinal+=ch(0,1)+ch(1,3)+ch(3,9)+ch(9,19)+ch(19,32)+ch(32,42)+ch(42,48)+ch(48,50)+ch(50,51)
tfinal+=ch(51,52)+ch(52,54)+ch(54,60)+ch(60,70)+ch(70,83)+ch(83,93)+ch(93,99)+ch(99,101)+ch(101,102)
g.select(g.getrect());g.copy()
j=g.getstring("Enter the displacement in form 'a,b' where a>b:")
n = ('["'+g.getclipstr()[g.getclipstr().find("\n")+1:].replace("\n","")+'","'+tfinal+'",['+j+','+str(getallisorule2.s)+']],')
with open(Outfile) as fIn:
a = fIn.read().split("\n")
with open(Outfile,'rb+') as fUh:
fUh.seek(-1,2)
fUh.truncate()
with open(Outfile,'a') as fOut:
if n not in a:
fOut.write(n+"\n]")
else:
fOut.write("]")