Hi Paul!
Yes, I find that SimpleInverseFire output very interesting, particularly the diagonal ship! What is even more interesting to me is that you seem to found ships I didn't, but I seem to have found ships that you didn't as well. Even the shallowest of my searches (by not specifying an "L" parameter) revealed different ships.
Here's my collection so far:
x = 224, y = 22, rule = SimpleInverseFire
148bo21bo11bo$147b3o19b3o4bo4b3o$118bo29bo21bo4b3o4bo17bobo$30bo3bo82b
3o28bo21bo5bo5bo17b3o$29bo2bo2bo82bo27b5o17b5o3bo3b5o14bo3bo$29b7o50bo
9bo20bobo28bo21bo3b5o3bo17bobo17bobo$32bo51bo3bo5bo3bo17bo3bo55bo23bob
o17bobo$30b5o50bo2bo5bo2bo19bobo81bo17bo3bo$31b3o12b5o17b2o15bob2o5b2o
bo122bobo$bobo7bobo18bo13bo3bo16bo17bo3bo3bo3bo20bo$4o7b4o17bo15bo19b
4o12bo2b3obob3o2bo19bo$2bobo5bobo18b3o12b5o17b2o2bo43b5o$b2ob2o3b2ob2o
18bo34b3o18bobobobo23bo$b3o3bo3b3o18bo15bo15b3obo18bobobobobo20b5o$o2b
9o2bo17bo14bobo17b2ob2o15bo7bo22bo$2bobobobobobo16bo2bo2bo10bo3bo12b5o
3bo46bo$3bo2bobo2bo18bobobo10b2o3b2o10bo4b4o$2bo9bo15b3obob3o9bo3bo14b
obo$3bob5obo17bo2bo2bo11bobo16bo$4bo5bo18bobobobo12bo$4bobobobo16bob2o
3b2obo$7bo20bobo3bobo!
My guess is that you're well on your way to working out the various terminal() conditions, but you're not finished, hence the discrepancy. But if that's not the case, maybe it would be helpful for you to see what I've been doing (or really, what I haven't been doing, since I've been doing the least effort version, using David Epstein's original terminal() code.)
Attached is a SimpleInverseFire version of your patched gfind code. Search for the string "EDG Patch" to see what I did (or undid). Also included below are two python scripts which build the rule tables needed for gfind.
I'm going to stop writing to Paul directly for a moment, and address anyone else reading this thread. If you'd like to search for spaceships in Weighted Life rules or in Hensel notation non-totalistic rules, here's what you can do (for now, until Paul comes out with a much improved version!):
1) Download SimpleInverseFire-v2.c and the two included scripts. Run either of the gfind-related scripts, and look for their output in Golly's rule table (set in Golly's preferences). For searching hexagonal totalistic rules, use the For-gifind-from-WeightedLife.py, and set all the weights to "1" except NE and SW, which should be set to zero.
2) Open SimpleInverseFire-v2.c, and search for the string "EDG Patch" until you find the long list of RuleTab entries. Delete these entries, and replace them with the output from one of the gfind-related scripts.
3) Rename and recompile the new version of SimpleinverseFire-v2.c. When the proram asks for a rule, type in any totalistic rule (eg B3/S23).
Back to Paul:
The For-gfind-from-HenselNotation.pyscript will probably make you want to cover your eyes in horror, as it is an ugly way to do what you did in GenCols! Both scripts create lots of duplicate entries, but the C compiler really doesn't mind the smidgen of extra work. Obviously, this sort of code should be in the C program, not in a separate python script.
As for whether searching for hexagonal rules successfully was lucky or not, I suspect the following two sentences will answer that question: I think it worked because I didn't let set4x() do its thing, and instead built ruletables using the scripts below. Once the ruletable is thrown together by one of the scripts, there is no problem, since gfind's rule table is just like weighted life and doesn't insist on isotropy. (So, in other words, I got lucky, right?) Seriously, lucky or not, it does work -- I've found one of Carter Bays' hexagonal spaceships as well. And I've also found spaceships in non-isotropic rules like MCell's Mosquito2, which is weighted like this:
-1 -1 5
5 . C .5
5 -1 -1
But I'd rather have an isotropic version that works very well, and it look like you're well on the way to creating one!
Here are the two gfind scripts:
Code: Select all
# For-gfind-from-WeightedLife.py
# by Eric Goldstein, July 20, 2012.
# The comments and most of the code are from Weightedlife->Ruletree(1.0).py
import golly
# Default values
RS = []
RB = []
ME_weight = 0
NW_weight = 1
NN_weight = 1
NE_weight = 1
WW_weight = 1
EE_weight = 1
SW_weight = 1
SS_weight = 1
SE_weight = 1
CR = chr(13)
LF = chr(10)
# The lookup table below for Life32"s non-totalistic notation uses the eight neighbor values:
# N,NE,E,SE,S,SW,W,NW
notationdict = {
"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
"2v" : [0,1,0,0,0,1,0,0], # NE, SW
"3a" : [1,1,1,0,0,0,0,0], # N, NE, E
"3v" : [1,1,0,1,0,0,0,0], # N, NE, SE
"3y" : [1,1,0,0,1,0,0,0], # N, NE, S (3r in non-swapped notation)
"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
"3r" : [1,0,0,1,0,1,0,0], # N, SE, SW (3y in non-swapped notation)
"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
"4y" : [1,1,1,0,1,0,0,0], # N, NE, E, S (4r in non-swapped notation)
"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
"4r" : [1,1,0,1,0,1,0,0], # N, NE, SE, SW (4y in non-swapped notation)
"4k" : [1,1,0,1,0,0,1,0], # N, NE, SE, W
"4v" : [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
"5a" : [0,0,0,1,1,1,1,1], # SE, S, SW, W, NW
"5v" : [0,0,1,0,1,1,1,1], # E, S, SW, W, NW
"5y" : [0,0,1,1,0,1,1,1], # E, SE, SW, W, NW (5r in non-swapped notation)
"5q" : [0,0,1,1,1,0,1,1], # E, SE, S, W, NW
"5j" : [0,0,1,1,1,1,0,1], # E, SE, S, SW, NW
"5i" : [0,0,1,1,1,1,1,0], # E, SE, S, SW, W
"5e" : [0,1,0,1,0,1,1,1], # NE, SE, SW, W, NW,
"5k" : [0,1,0,1,1,0,1,1], # NE, SE, S, W, NW
"5r" : [0,1,1,0,1,0,1,1], # NE, E, S, W, NW (5y in non-swapped notation)
"5c" : [1,0,1,0,1,0,1,1], # N, E, S, W, NW
"6a" : [0,0,1,1,1,1,1,1], # E, SE, S, SW, W, NW
"6e" : [0,1,0,1,1,1,1,1], # NE, SE, S, SW, W, NW
"6k" : [0,1,1,0,1,1,1,1], # NE, E, S, SW, W, NW
"6i" : [0,1,1,1,0,1,1,1], # NE, E, SE, SW, W, NW
"6c" : [1,0,1,0,1,1,1,1], # N, E, S, SW, W, NW
"6v" : [1,0,1,1,1,0,1,1], # N, E, SE, S, W, NW
"7e" : [0,1,1,1,1,1,1,1], # NE, E, SE, S, SW, W, NW
"7c" : [1,0,1,1,1,1,1,1] # N, E, SE, S, SW, W, NW
}
# Here's a graphical depiction of the notation.
dummyvariable = '''
x = 147, y = 97, rule = B/S012345678
21b3o6b5o5bo3bo6b3o6b5o5bo3bo5bo3bo6b3o10bo5b4o6b5o5bobobo5b5o$20bo3bo
5bo9bo2bo6bo3bo7bo7bo3bo5bo3bo5bo3bo9bo5bo3bo7bo7bobobo9bo$20bo9bo9bob
o7bo3bo7bo7bo3bo5bo3bo5bo3bo9bo5bo3bo7bo7bobobo8bo$20bo9b3o7b2o8b5o7bo
7bo3bo6bobo6bo3bo9bo5b4o8bo7bobobo7bo$20bo9bo9bobo7bo3bo7bo7bo3bo7bo7b
obobo5bo3bo5bo3bo7bo7bobobo6bo$20bo3bo5bo9bo2bo6bo3bo7bo8bobo8bo7bo2bo
6bo3bo5bo3bo7bo7bobobo5bo$21b3o6b5o5bo3bo5bo3bo5b5o7bo9bo8b2obo6b3o6bo
3bo7bo8bobo6b5o4$b3o6b7o$o3bo5bo5bo$o2b2o5bo5bo$obobo5bo2bo2bo$2o2bo5b
o5bo$o3bo5bo5bo$b3o6b7o4$b2o17b7o3b7o$obo17bo5bo3bo5bo$2bo17bobo3bo3bo
2bo2bo$2bo17bo2bo2bo3bo2bo2bo$2bo17bo5bo3bo5bo$2bo17bo5bo3bo5bo$5o15b
7o3b7o4$b3o16b7o3b7o3b7o3b7o3b7o3b7o$o3bo15bo5bo3bo5bo3bo5bo3bo5bo3bo
5bo3bo5bo$4bo15bobobobo3bo2bo2bo3bobo3bo3bobo3bo3bo2bo2bo3bo3bobo$3bo
16bo2bo2bo3bob2o2bo3bo2bo2bo3bob2o2bo3bo2bo2bo3bo2bo2bo$2bo17bo5bo3bo
5bo3bo2bo2bo3bo5bo3bo2bo2bo3bobo3bo$bo18bo5bo3bo5bo3bo5bo3bo5bo3bo5bo
3bo5bo$5o15b7o3b7o3b7o3b7o3b7o3b7o4$b3o16b7o3b7o3b7o3b7o3b7o3b7o3b7o3b
7o3b7o3b7o$o3bo15bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo
3bo5bo$4bo15bobobobo3bo2bo2bo3bobo3bo3bob2o2bo3bo3bobo3bobobobo3bo2b2o
bo3bo3bobo3bo3bobo3bobobobo$2b2o16bo2bo2bo3bob2o2bo3bo2b2obo3bob2o2bo
3bo2b2obo3bob2o2bo3bo2bo2bo3bo2bo2bo3bo2b2obo3bo2bo2bo$4bo15bobo3bo3bo
2bo2bo3bo2bo2bo3bo5bo3bo3bobo3bo5bo3bo2bo2bo3bob2o2bo3bo2bo2bo3bo2bo2b
o$o3bo15bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo$b
3o16b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o4$2b2o16b7o3b7o3b7o3b7o3b7o
3b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o$bobo16bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3b
o5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo$o2bo16bobobobo3bo2bo2bo
3bo2b2obo3bob3obo3bob2o2bo3bobobobo3bob2o2bo3bob2o2bo3bo3bobo3bobobobo
3bob3obo3bobo3bo3bob2o2bo$5o15bo2bo2bo3bob3obo3bob2o2bo3bob2o2bo3bo2bo
2bo3bob2o2bo3bob2o2bo3bob2o2bo3bob3obo3bo2bo2bo3bo2bo2bo3bob2o2bo3bo2b
o2bo$3bo16bobobobo3bo2bo2bo3bo3bobo3bo5bo3bob2o2bo3bobo3bo3bo2bo2bo3bo
3bobo3bo2bo2bo3bob2o2bo3bo2bo2bo3bo2b2obo3bo2b2obo$3bo16bo5bo3bo5bo3bo
5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo$3bo16b
7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o4$5o15b7o3b7o3b7o3b
7o3b7o3b7o3b7o3b7o3b7o3b7o$o19bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5b
o3bo5bo3bo5bo3bo5bo$4o16bo2bo2bo3bobobobo3bo2b2obo3bo3bobo3bob2o2bo3bo
bo3bo3bobobobo3bob2o2bo3bob2o2bo3bobobobo$4bo15bob3obo3bo2b2obo3bob2o
2bo3bo2b2obo3bob2o2bo3bob3obo3bob3obo3bob2o2bo3bob2o2bo3bob3obo$4bo15b
o2b2obo3bobobobo3bobobobo3bob3obo3bob2o2bo3bob2o2bo3bobo3bo3bo2b2obo3b
obobobo3bo2bo2bo$o3bo15bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo
3bo5bo3bo5bo$b3o16b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o4$b3o16b7o3b
7o3b7o3b7o3b7o3b7o$o3bo15bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo$o19bo2bo
2bo3bobobobo3bo2b2obo3bo2b2obo3bobobobo3bob2o2bo$4o16bob3obo3bo2b2obo
3bob3obo3bo2b2obo3bob3obo3bob3obo$o3bo15bob3obo3bob3obo3bobobobo3bob3o
bo3bobobobo3bo2b2obo$o3bo15bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo$b3o16b
7o3b7o3b7o3b7o3b7o3b7o4$5o15b7o3b7o$4bo15bo5bo3bo5bo$3bo16bo2b2obo3bob
3obo$3bo16bob3obo3bo2b2obo$2bo17bob3obo3bob3obo$2bo17bo5bo3bo5bo$2bo
17b7o3b7o4$b3o6b7o$o3bo5bo5bo$o3bo5bob3obo$b3o6bob3obo$o3bo5bob3obo$o
3bo5bo5bo$b3o6b7o!
'''
WeightedRulestring = golly.getstring('''
This script converts Weighted Life rules to a rule table usable by
David Epstein's gfind program, as modified by Paul Tooke.
Newly created rule tables will be placed in Golly's Rules directory (set in Golly"s preferences).
You can delete them once you've moved them into Paul Tooke's modified gfind program.
Enter a Weighted Life rule here:
''', "NW5,NN1,NE5,WW1,ME0, EE1,SW5,SS1,SE5,HI0,RS1,RS5,RB2,RB10")
WeightedRulestring = WeightedRulestring.replace("ame = ", "ame=")
WeightedRulestring = WeightedRulestring.replace(" ", ",")
WeightedRulestring = WeightedRulestring.replace(CR, ",")
WeightedRulestring = WeightedRulestring.replace(LF, ",")
for x in WeightedRulestring.split(","):
if x.startswith("Name=") or x.startswith("name="):
name = x.split("ame=")[1]
else:
x = x.upper()
if x.startswith("NW"):
NW_weight = int(x.split("NW")[1])
elif x.startswith("NN"):
NN_weight = int(x.split("NN")[1])
elif x.startswith("NE"):
NE_weight = int(x.split("NE")[1])
elif x.startswith("WW"):
WW_weight = int(x.split("WW")[1])
elif x.startswith("EE"):
EE_weight = int(x.split("EE")[1])
elif x.startswith("SW"):
SW_weight = int(x.split("SW")[1])
elif x.startswith("SS"):
SS_weight = int(x.split("SS")[1])
elif x.startswith("SE"):
SE_weight = int(x.split("SE")[1])
elif x.startswith("ME"):
ME_weight = int(x.split("ME")[1])
elif x.startswith("RS"):
RS.append(int(x.split("RS")[1]))
elif x.startswith("RB"):
RB.append(int(x.split("RB")[1]))
elif x.startswith("HI"):
n_states = (int(x.split("HI")[1]))
f = open(golly.getdir("rules")+"gfind-table"+" temp"+".txt", "w") # using temp for the rule name, for now. Put code from weightedlife-ruletree in, once that finalizes.
def convertorder_aux (x2, x3, x6, x9, x8, x7, x4, x1):
return [x1, x2, x3, x4, 0, x6, x7, x8, x9] # by inserting zero, it can not handle ME values. To do: take ME_weight as a parameter.
def isotropy (x1, x2, x3, x4, x5, x6, x7, x8, x9):
return [[x1, x2, x3, x4, x5, x6, x7, x8, x9],
[x3, x2, x1, x6, x5, x4, x9, x8, x7],
[x7, x8, x9, x4, x5, x6, x1, x2, x3],
[x1, x4, x7, x2, x5, x8, x3, x6, x9],
[x9, x6, x3, x8, x5, x2, x7, x4, x1],
[x7, x4, x1, x8, x5, x2, x9, x6, x3],
[x9, x8, x7, x6, x5, x4, x3, x2, x1],
[x3, x6, x9, x2, x5, x8, x1, x4, x7]
]
def handleall(B_or_S_flag, RB_or_RS_list):
for i in notationdict:
converted = convertorder_aux(notationdict[i][0],notationdict[i][1],notationdict[i][2],notationdict[i][3],notationdict[i][4],notationdict[i][5],notationdict[i][6],notationdict[i][7])
for config in isotropy(converted[0],converted[1],converted[2],converted[3], converted[4], converted[5], converted[6], converted[7], converted[8]):
for rulevalue in RB_or_RS_list:
if rulevalue == NW_weight*config[0]+NN_weight*config[1]+NE_weight*config[2]+WW_weight*config[3]+EE_weight*config[5]+SW_weight*config[6]+SS_weight*config[7]+SE_weight*config[8]:
f.write( "ruleTab[")
if config[0] == 1:
f.write("mNW + ")
if config[1] == 1:
f.write( "mNN + ")
if config[2] == 1:
f.write("mNE + ")
if config[3] == 1:
f.write("mWW + ")
if config[5] == 1:
f.write("mEE + ")
if config[6] == 1:
f.write("mSW + ")
if config[7] == 1:
f.write("mSS + ")
if config[8] == 1:
f.write("mSE + ")
f.write(B_or_S_flag + "] = 1;" +"\n")
handleall("0",RB)
handleall("mME",RS)
f.flush()
f.close()
golly.show("Created gfind-table"+ " temp"+".txt in "+golly.getdir("rules"))
Code: Select all
# For-gfind-from-HenselNotation.py
# by Eric Goldstein, July 20, 2012.
# All of the comments (and most of the code) is from HenselNotation->Ruletable.py
# This script builds a ruleTable for Life32's non-totalistic notation.
# The notation was originally adapted from Alan Hensel"s work on that subject.
dialog_box_message = '''This script will allow you to enter the non-totalistic rule notation
used by Johan Bontes' Life32 program, based on work by Alan Hensel.
Please look in the script file to see how the notation works.
The goal is to create a series of rule table entries for David Epstein's gfind proram, as modified by Paul Tooke.
Newly created rules will be placed in Golly's Rules directory (set in Golly"s preferences).
You can delete them once you've moved them into Paul Tooke's modified gfind program.
Enter a rule here:
'''
# Minor note:
# Unfortunately, Alan Hensel's notation for r and y are swapped in Life32.
# Life32's rule dialog box shows the correct arrangements, but they are swapped in the implementation.
# What should work as 3r, 4r, and 5r, actually work as 3y, 4y, and 5y, and vice versa.
# This script swaps the definition of r and y just like Life32 does, so that patterns intended to be run
# on Life32 will run the same way in Golly.
# Golly"s ruleTable format use the following notation:
# C,N,NE,E,SE,S,SW,W,NW,C'
# where C is the current state, and C' is the new state, and
# where the eight neighbors in the Moore neighborhood are as shown below.
# NW N NE
# W C E
# SW S SE
# The lookup table below for Life32"s non-totalistic notation uses the eight neighbor values:
# N,NE,E,SE,S,SW,W,NW
notationdict = {
"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
"2v" : [0,1,0,0,0,1,0,0], # NE, SW
"3a" : [1,1,1,0,0,0,0,0], # N, NE, E
"3v" : [1,1,0,1,0,0,0,0], # N, NE, SE
"3y" : [1,1,0,0,1,0,0,0], # N, NE, S (3r in non-swapped notation)
"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
"3r" : [1,0,0,1,0,1,0,0], # N, SE, SW (3y in non-swapped notation)
"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
"4y" : [1,1,1,0,1,0,0,0], # N, NE, E, S (4r in non-swapped notation)
"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
"4r" : [1,1,0,1,0,1,0,0], # N, NE, SE, SW (4y in non-swapped notation)
"4k" : [1,1,0,1,0,0,1,0], # N, NE, SE, W
"4v" : [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
"5a" : [0,0,0,1,1,1,1,1], # SE, S, SW, W, NW
"5v" : [0,0,1,0,1,1,1,1], # E, S, SW, W, NW
"5y" : [0,0,1,1,0,1,1,1], # E, SE, SW, W, NW (5r in non-swapped notation)
"5q" : [0,0,1,1,1,0,1,1], # E, SE, S, W, NW
"5j" : [0,0,1,1,1,1,0,1], # E, SE, S, SW, NW
"5i" : [0,0,1,1,1,1,1,0], # E, SE, S, SW, W
"5e" : [0,1,0,1,0,1,1,1], # NE, SE, SW, W, NW,
"5k" : [0,1,0,1,1,0,1,1], # NE, SE, S, W, NW
"5r" : [0,1,1,0,1,0,1,1], # NE, E, S, W, NW (5y in non-swapped notation)
"5c" : [1,0,1,0,1,0,1,1], # N, E, S, W, NW
"6a" : [0,0,1,1,1,1,1,1], # E, SE, S, SW, W, NW
"6e" : [0,1,0,1,1,1,1,1], # NE, SE, S, SW, W, NW
"6k" : [0,1,1,0,1,1,1,1], # NE, E, S, SW, W, NW
"6i" : [0,1,1,1,0,1,1,1], # NE, E, SE, SW, W, NW
"6c" : [1,0,1,0,1,1,1,1], # N, E, S, SW, W, NW
"6v" : [1,0,1,1,1,0,1,1], # N, E, SE, S, W, NW
"7e" : [0,1,1,1,1,1,1,1], # NE, E, SE, S, SW, W, NW
"7c" : [1,0,1,1,1,1,1,1] # N, E, SE, S, SW, W, NW
}
# Here's a graphical depiction of the notation.
dummyvariable = '''
x = 147, y = 97, rule = B/S012345678
21b3o6b5o5bo3bo6b3o6b5o5bo3bo5bo3bo6b3o10bo5b4o6b5o5bobobo5b5o$20bo3bo
5bo9bo2bo6bo3bo7bo7bo3bo5bo3bo5bo3bo9bo5bo3bo7bo7bobobo9bo$20bo9bo9bob
o7bo3bo7bo7bo3bo5bo3bo5bo3bo9bo5bo3bo7bo7bobobo8bo$20bo9b3o7b2o8b5o7bo
7bo3bo6bobo6bo3bo9bo5b4o8bo7bobobo7bo$20bo9bo9bobo7bo3bo7bo7bo3bo7bo7b
obobo5bo3bo5bo3bo7bo7bobobo6bo$20bo3bo5bo9bo2bo6bo3bo7bo8bobo8bo7bo2bo
6bo3bo5bo3bo7bo7bobobo5bo$21b3o6b5o5bo3bo5bo3bo5b5o7bo9bo8b2obo6b3o6bo
3bo7bo8bobo6b5o4$b3o6b7o$o3bo5bo5bo$o2b2o5bo5bo$obobo5bo2bo2bo$2o2bo5b
o5bo$o3bo5bo5bo$b3o6b7o4$b2o17b7o3b7o$obo17bo5bo3bo5bo$2bo17bobo3bo3bo
2bo2bo$2bo17bo2bo2bo3bo2bo2bo$2bo17bo5bo3bo5bo$2bo17bo5bo3bo5bo$5o15b
7o3b7o4$b3o16b7o3b7o3b7o3b7o3b7o3b7o$o3bo15bo5bo3bo5bo3bo5bo3bo5bo3bo
5bo3bo5bo$4bo15bobobobo3bo2bo2bo3bobo3bo3bobo3bo3bo2bo2bo3bo3bobo$3bo
16bo2bo2bo3bob2o2bo3bo2bo2bo3bob2o2bo3bo2bo2bo3bo2bo2bo$2bo17bo5bo3bo
5bo3bo2bo2bo3bo5bo3bo2bo2bo3bobo3bo$bo18bo5bo3bo5bo3bo5bo3bo5bo3bo5bo
3bo5bo$5o15b7o3b7o3b7o3b7o3b7o3b7o4$b3o16b7o3b7o3b7o3b7o3b7o3b7o3b7o3b
7o3b7o3b7o$o3bo15bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo
3bo5bo$4bo15bobobobo3bo2bo2bo3bobo3bo3bob2o2bo3bo3bobo3bobobobo3bo2b2o
bo3bo3bobo3bo3bobo3bobobobo$2b2o16bo2bo2bo3bob2o2bo3bo2b2obo3bob2o2bo
3bo2b2obo3bob2o2bo3bo2bo2bo3bo2bo2bo3bo2b2obo3bo2bo2bo$4bo15bobo3bo3bo
2bo2bo3bo2bo2bo3bo5bo3bo3bobo3bo5bo3bo2bo2bo3bob2o2bo3bo2bo2bo3bo2bo2b
o$o3bo15bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo$b
3o16b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o4$2b2o16b7o3b7o3b7o3b7o3b7o
3b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o$bobo16bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3b
o5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo$o2bo16bobobobo3bo2bo2bo
3bo2b2obo3bob3obo3bob2o2bo3bobobobo3bob2o2bo3bob2o2bo3bo3bobo3bobobobo
3bob3obo3bobo3bo3bob2o2bo$5o15bo2bo2bo3bob3obo3bob2o2bo3bob2o2bo3bo2bo
2bo3bob2o2bo3bob2o2bo3bob2o2bo3bob3obo3bo2bo2bo3bo2bo2bo3bob2o2bo3bo2b
o2bo$3bo16bobobobo3bo2bo2bo3bo3bobo3bo5bo3bob2o2bo3bobo3bo3bo2bo2bo3bo
3bobo3bo2bo2bo3bob2o2bo3bo2bo2bo3bo2b2obo3bo2b2obo$3bo16bo5bo3bo5bo3bo
5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo$3bo16b
7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o4$5o15b7o3b7o3b7o3b
7o3b7o3b7o3b7o3b7o3b7o3b7o$o19bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5b
o3bo5bo3bo5bo3bo5bo$4o16bo2bo2bo3bobobobo3bo2b2obo3bo3bobo3bob2o2bo3bo
bo3bo3bobobobo3bob2o2bo3bob2o2bo3bobobobo$4bo15bob3obo3bo2b2obo3bob2o
2bo3bo2b2obo3bob2o2bo3bob3obo3bob3obo3bob2o2bo3bob2o2bo3bob3obo$4bo15b
o2b2obo3bobobobo3bobobobo3bob3obo3bob2o2bo3bob2o2bo3bobo3bo3bo2b2obo3b
obobobo3bo2bo2bo$o3bo15bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo
3bo5bo3bo5bo$b3o16b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o4$b3o16b7o3b
7o3b7o3b7o3b7o3b7o$o3bo15bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo$o19bo2bo
2bo3bobobobo3bo2b2obo3bo2b2obo3bobobobo3bob2o2bo$4o16bob3obo3bo2b2obo
3bob3obo3bo2b2obo3bob3obo3bob3obo$o3bo15bob3obo3bob3obo3bobobobo3bob3o
bo3bobobobo3bo2b2obo$o3bo15bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo$b3o16b
7o3b7o3b7o3b7o3b7o3b7o4$5o15b7o3b7o$4bo15bo5bo3bo5bo$3bo16bo2b2obo3bob
3obo$3bo16bob3obo3bo2b2obo$2bo17bob3obo3bob3obo$2bo17bo5bo3bo5bo$2bo
17b7o3b7o4$b3o6b7o$o3bo5bo5bo$o3bo5bob3obo$b3o6bob3obo$o3bo5bob3obo$o
3bo5bo5bo$b3o6b7o!
'''
# This is the isotropy function's order: NW,NN,NE,WW,ME,EE,SW,SS,SE
# This is the notationdict's order: N,NE,E,SE,S,SW,W,NW
# So, a conversion function is necessary to use notationdict.
# the conversion function takes a notationdict entry like "1,1,1,0,0,0,0,0" and
# returns "0 1 1 0 0 1 0 0 0"
# and then isotropy can be run on that result.
def convertorder (totalistic_num, notation_letter):
n = notationdict[totalistic_num+notation_letter]
return convertorderaux(n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7])
def convertorderaux (x2, x3, x6, x9, x8, x7, x4, x1):
return [x1, x2, x3, x4, 0, x6, x7, x8, x9]
def isotropy (x1, x2, x3, x4, x5, x6, x7, x8, x9):
return [[x1, x2, x3, x4, x5, x6, x7, x8, x9],
[x3, x2, x1, x6, x5, x4, x9, x8, x7],
[x7, x8, x9, x4, x5, x6, x1, x2, x3],
[x1, x4, x7, x2, x5, x8, x3, x6, x9],
[x9, x6, x3, x8, x5, x2, x7, x4, x1],
[x7, x4, x1, x8, x5, x2, x9, x6, x3],
[x9, x8, x7, x6, x5, x4, x3, x2, x1],
[x3, x6, x9, x2, x5, x8, x1, x4, x7]
]
def create_isotropy_rows (input_isotropy_list, bs):
result = ""
for row in input_isotropy_list:
result = result + "ruleTab["
if row[0] == 1:
result = result + "mNW + "
if row[1] == 1:
result = result + "mNN + "
if row[2] == 1:
result = result + "mNE + "
if row[3] == 1:
result = result + "mWW + "
if row[5] == 1:
result = result + "mEE + "
if row[6] == 1:
result = result + "mSW + "
if row[7] == 1:
result = result + "mSS + "
if row[8] == 1:
result = result + "mSE + "
result = result + bs + "] = 1;" +"\n"
return result
# The following function takes a rule element like B2a or B2-a and creates the appropriate ruleTable row.
# Parameters:
# bs is a string with one of two values "0," to indicate birth, and "1," to indicates survival.
# totalistic_num is one character string "0" ... "8"
# notation_letter is a one character string indicating Hensel's notation "a",
# inverse_list is a list of notation letters for inverse notation
def create_table_row(bs,totalistic_num, notation_letter, inverse_list):
result = ""
if totalistic_num == "0":
if bs == "0":
result = "Sorry - not ready for B0 rules yet..."
else:
result = "ruleTab[mME] = 1;"+"\n"
elif totalistic_num == "8":
result = "ruleTab[mNW+mNN+mNE+mWW+mME+mEE+mSW+mSS+mSE+mME] = 1;" + "\n"
elif notation_letter != "none":
myinput = convertorder(totalistic_num, notation_letter)
result = create_isotropy_rows(isotropy(myinput[0],myinput[1],myinput[2],myinput[3],myinput[4],myinput[5],myinput[6],myinput[7],myinput[8]), bs)
elif inverse_list != []:
for i in notationdict:
if not (i[1] in inverse_list) and i.startswith(totalistic_num):
myinput = convertorder(totalistic_num, i.replace(totalistic_num, ""))
result = result+ create_isotropy_rows(isotropy(myinput[0],myinput[1],myinput[2],myinput[3],myinput[4],myinput[5],myinput[6],myinput[7],myinput[8]), bs)
else:
for i in notationdict:
if i.startswith(totalistic_num):
myinput = convertorder(totalistic_num, i.replace(totalistic_num, ""))
result = result + create_isotropy_rows(isotropy(myinput[0],myinput[1],myinput[2],myinput[3],myinput[4],myinput[5],myinput[6],myinput[7],myinput[8]), bs)
return result
import golly
CR = chr(13)
LF = chr(10)
rulestring = golly.getstring(dialog_box_message, "B2a/S12")
# The following code cleans up the rulestring
# so that it makes a valid and somewhat readable file name - eg "B2-a_S12.table"
rulestring = rulestring.replace(" ", "")
rulestring = rulestring.lower()
rulestring = rulestring.replace("b", "B")
rulestring = rulestring.replace("s", "S")
# The variable named rulestring will be parsed.
# The variable named rule_name will be the name of the new file.
# Valid rules contain a slash character but filenames can not include slashes.
rule_name = rulestring.replace("/", "_")
# To do: Allow the user to specify their own name for a rule.
# The following code cleans up the rule string to
# make life easier for the parser.
if rulestring.startswith("B") or rulestring.startswith("S"):
rulestring = rulestring.replace("/", "")
else:
rulestring = rulestring.replace("/", "B")
rulestring = rulestring + "\n"
# Lets make a new file
f = open(golly.getdir("rules")+"gfind-table"+rule_name+".txt", "w")
# Now create the header for the rule table
# Now that the header for the rule table has been created,
# parse the rulestring, and add rows to the ruleTable as we go.
# Lets say rule strings contain "rule elements", such as B2i, or B2-a, which are composed of:
# 1) a birth or survival flag
# 2) a "totalistic context" consisting of an integer between zero and 8
# 3) a "notation_letter".
# 4) a flag for "positive" or "inverse" notation
bs = "mME" # Use "mME" for survival or "BIRTH" for birth
totalistic_context = "none" # "none" will be replaced with "0" through
# "8" by the parser.
last_totalistic_context = "none" # Lets the parser remember the previous
# integer it encountered.
notation_letter = "none" # "none","a", "e", "i", etc.
positive_or_inverse = "positive"
inverse_list = []
for x in rulestring:
if x == "S" or x == "B" or x.isdigit() or x == "\n":
last_totalistic_context = totalistic_context
totalistic_context = x
if last_totalistic_context != "none" and notation_letter == "none":
f.write(create_table_row(bs, last_totalistic_context, "none",[]))
if last_totalistic_context != "none" and positive_or_inverse == "inverse":
f.write(create_table_row(bs, last_totalistic_context, "none", inverse_list))
# Now lets get ready to move on to the next character.
notation_letter = "none"
inverse_list = []
positive_or_inverse = "positive"
if x == "S" or x == "B":
totalistic_context = "none"
if x == "S":
bs = "mME"
if x == "B":
bs = "0"
elif x == "-":
positive_or_inverse = "inverse"
elif x in ["c", "a", "e", "k", "i", "v", "j", "y", "q", "r", "w", "t", "z"] and totalistic_context != "none":
if positive_or_inverse == "positive":
notation_letter = x
f.write(create_table_row(bs, totalistic_context, notation_letter, []))
else:
notation_letter = x
inverse_list.append(x)
f.flush()
f.close()
golly.show("Created gfind-table"+rule_name+".txt in "+golly.getdir("rules"))