def check_for_shared_rule(rulename): # rulename has at least one hyphen so get all chars before the last hyphen prefix = rulename.rsplit('-',1)[0] # replace any illegal filename chars with underscores filename = prefix.replace("/","_").replace("\\","_") + "-shared.rule" rulepath = g.getdir("rules") + filename if not os.path.isfile(rulepath): rulepath = g.getdir("app") + "Rules/" + filename if not os.path.isfile(rulepath): # there is no prefix-shared.rule file return "" # ask user if they would prefer to edit icons in shared file sharedname = prefix + "-shared" try: answer = g.getstring("There are no icons in " + rulename + ".rule.\n" + "Would you prefer to edit the icons in " + sharedname + ".rule?", "Yes", "Edit icons in shared rule?") except: # user hit Cancel (which would normally abort script) return "" if len(answer) == 0 or (answer[0] != "Y" and answer[0] != "y"): return "" return sharedname # user said Yes
def check_for_shared_rule(rulename): # rulename has at least one hyphen so get all chars before the last hyphen prefix = rulename.rsplit('-', 1)[0] # replace any illegal filename chars with underscores filename = prefix.replace("/", "_").replace("\\", "_") + "-shared.rule" rulepath = g.getdir("rules") + filename if not os.path.isfile(rulepath): rulepath = g.getdir("app") + "Rules/" + filename if not os.path.isfile(rulepath): # there is no prefix-shared.rule file return "" # ask user if they would prefer to edit icons in shared file sharedname = prefix + "-shared" try: answer = g.getstring( "There are no icons in " + rulename + ".rule.\n" + "Would you prefer to edit the icons in " + sharedname + ".rule?", "Yes", "Edit icons in shared rule?") except: # user hit Cancel (which would normally abort script) return "" if len(answer) == 0 or (answer[0] != "Y" and answer[0] != "y"): return "" return sharedname # user said Yes
def to_golly_rule(self): ''' Writes the rule file directly into rule directory. ''' from golly import getdir, show with open(getdir('rules') + self.n + '.rule', 'w') as f: f.write(str(self)) show("Saved rule to " + getdir('rules') + self.n + '.rule') return self
def to_golly_rule(self): ''' Writes the rule file directly into rule directory. ''' from golly import getdir, show with open(getdir('rules')+self.n+'.rule','w') as f: f.write(str(self)) show("Saved rule to "+getdir('rules')+self.n+'.rule') return self
def FindWssByDirection(isUp, modY): wssList = pickle.load( open(path.join(g.getdir("data"), "WssData.pkl"), "rb")) wssLaneList = pickle.load( open(path.join(g.getdir("data"), "WssLaneData.pkl"), "rb")) dy = 0 if isUp: dy = 1 objects = [] for i in xrange(dy, len(wssList), 2): objects += FindObj(wssList[i], i) objects.sort() result = [] for obj in objects: if len(result) == 0: x, y, v = obj result.append((x, y % modY, v)) else: x, y, v = result[len(result) - 1] nx, ny, nv = obj if x == nx and y % modY == ny % modY and v == nv: continue result.append((nx, ny % modY, nv)) tempRes = [] for r in result: x, y, v = r l, r = wssLaneList[v] if isUp: tempRes.append((x + r, x, y, v)) else: tempRes.append((x + l, x, y, v)) tempRes.sort() result = [] for r in tempRes: t, x, y, v = r result.append((x, y, v)) return result
def FindWssByDirection(isUp, modY): wssList = pickle.load(open(path.join(g.getdir("data"),"WssData.pkl"),"rb") ) wssLaneList = pickle.load(open(path.join(g.getdir("data"),"WssLaneData.pkl"),"rb") ) dy = 0 if isUp: dy = 1 objects = [] for i in xrange(dy, len(wssList), 2): objects += FindObj(wssList[i], i) objects.sort() result = [] for obj in objects: if len(result) == 0: x, y, v = obj result.append((x, y % modY, v)) else: nx, ny, nv = obj if (nx, ny % modY, nv) in result: continue result.append((nx, ny % modY, nv)) tempRes = [] for r in result: x, y, v = r l, r = wssLaneList[v] if isUp: tempRes.append((x + r, x, y, v)) else: tempRes.append((x + l, x, y, v)) tempRes.sort() result = [] for r in tempRes: t, x, y, v = r result.append((x, y, v)) return result
def writeRuleTree(self,name): # create a .tree file in user's rules directory f=open(golly.getdir("rules")+name+".tree", 'w') f.write("# Automatically generated by make-ruletree.py.\n") f.write("num_states=" + str(self.numStates)+"\n") f.write("num_neighbors=" + str(self.numNeighbors)+"\n") f.write("num_nodes=" + str(len(self.r))+"\n") for rule in self.r: f.write(rule+"\n") f.flush() # ensure file is complete (only on Windows?) f.close() golly.setalgo("RuleTree") # in case name.table exists golly.setrule(name) golly.show("Created "+name+".tree in "+golly.getdir("rules"))
def slideshow(): oldalgo = g.getalgo() oldrule = g.getrule() message = "Hit space to continue or escape to exit the slide show..." g.show(message) for root, dirs, files in os.walk(g.getdir("app") + "Patterns"): for name in files: if name.startswith("."): # ignore hidden files (like .DS_Store on Mac) pass else: g.new("") g.setalgo("QuickLife") # nicer to start from this algo fullname = join(root, name) g.open(fullname, False) # don't add file to Open/Run Recent submenu g.update() if name.endswith(".lua") or name.endswith(".py"): # reshow message in case it was changed by script g.show(message) while True: event = g.getevent() if event == "key space none": break g.doevent(event) # allow keyboard/mouse interaction sleep(0.01) # avoid hogging cpu # if all patterns have been displayed then restore original algo and rule # (don't do this if user hits escape in case they want to explore pattern) g.new("untitled") g.setalgo(oldalgo) g.setrule(oldrule)
def saverule(self, name, comments, table, colours): ruledir = g.getdir("rules") filename = ruledir + name + ".rule" results = "@RULE " + name + "\n\n" results += "*** File autogenerated by saverule. ***\n\n" results += comments results += "\n\n@TABLE\n\n" results += table results += "\n\n@COLORS\n\n" results += colours results += "\n\n@ICONS\n\n" results += "circles\n" # 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. if not os.path.exists(filename): try: f = open(filename, 'w') f.write(results) f.close() except: g.warn("Unable to create rule table:\n" + filename)
def slideshow (): oldalgo = g.getalgo() oldrule = g.getrule() message = "Hit space to continue or escape to exit the slide show..." g.show(message) for root, dirs, files in os.walk(g.getdir("app") + "Patterns"): for name in files: if name.startswith("."): # ignore hidden files (like .DS_Store on Mac) pass else: fullname = join(root, name) g.open(fullname, False) # don't add file to Open/Run Recent submenu g.update() if name.endswith(".pl") or name.endswith(".py"): # reshow message in case it was changed by script g.show(message) while True: event = g.getevent() if event == "key space none": break g.doevent(event) # allow keyboard/mouse interaction sleep(0.01) # avoid hogging cpu if "CVS" in dirs: dirs.remove("CVS") # don't visit CVS directories # if all patterns have been displayed then restore original algo and rule # (don't do this if user hits escape in case they want to explore pattern) g.new("untitled") g.setalgo(oldalgo) g.setrule(oldrule)
def SaveWss(file): g.setrule("b3/s23") wss = [g.parse("bobo$4bo$o3bo$o3bo$4bo$bo2bo$2b3o!"), g.parse("bobo$4bo$o3bo$4bo$bo2bo$2b3o!"), g.parse("obo$3bo$3bo$o2bo$b3o!")] wssList = [] for w in wss: for i in xrange(0, 4): wssList.append(PrepareList(g.evolve(w, i))) wssList.append(PrepareList(g.transform(g.evolve(w, i), 0, 0, 1, 0, 0, -1))) pickle.dump(wssList, open(path.join(g.getdir("data"),file), "wb"))
def MakeTriangularIcons_CheckerboardMethod(n_states,colors,force_background,rule_name): width = 15*(n_states*2-1) if force_background and n_states>2: width+=15 height = 22 pixels = [[(0,0,0) for x in range(width)] for y in range(height)] lower = [[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,1,0,0,0,0,0,0,0], [0,0,0,0,0,0,1,1,1,0,0,0,0,0,0], [0,0,0,0,0,1,1,1,1,1,0,0,0,0,0], [0,0,0,0,1,1,1,1,1,1,1,0,0,0,0], [0,0,0,1,1,1,1,1,1,1,1,1,0,0,0], [0,0,1,1,1,1,1,1,1,1,1,1,1,0,0], [0,1,1,1,1,1,1,1,1,1,1,1,1,1,0], [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]] lower7x7 = [[0,0,0,0,0,0,0], [0,0,0,0,0,0,0], [0,0,0,1,0,0,0], [0,0,1,1,1,0,0], [0,1,1,1,1,1,0], [1,1,1,1,1,1,1], [0,0,0,0,0,0,0]] if force_background: bg_color = colors[0] else: bg_color = (0,0,0) for i in range(1,n_states): fg_color = colors[i] # draw 15x15 icons for row in range(15): for column in range(15): # draw lower triangle icons pixels[row][15*(i-1) + column] = [bg_color,fg_color][lower[row][column]] # draw upper triangle icons pixels[row][15*(n_states+i-2) + column] = [bg_color,fg_color][lower[13-row][column]] # draw 7x7 icons for row in range(7): for column in range(7): # draw lower triangle icons pixels[15+row][15*(i-1) + column] = [bg_color,fg_color][lower7x7[row][column]] # draw upper triangle icons pixels[15+row][15*(n_states+i-2) + column] = [bg_color,fg_color][lower7x7[6-row][column]] WriteBMP( pixels, golly.getdir('rules') + rule_name + ".icons" )
def ConvertRuleTableTransitionsToRuleTree(neighborhood,n_states,transitions,input_filename): '''Convert a set of vonNeumann or Moore transitions directly to a rule tree.''' rule_name = os.path.splitext(os.path.split(input_filename)[1])[0] remap = { "vonNeumann":[0,3,2,4,1], # CNESW->CSEWN "Moore":[0,5,3,7,1,4,6,2,8] # C,N,NE,E,SE,S,SW,W,NW -> C,S,E,W,N,SE,SW,NE,NW } numNeighbors = len(remap[neighborhood])-1 tree = RuleTree(n_states,numNeighbors) for i,t in enumerate(transitions): golly.show("Building rule tree... ("+str(100*i/len(transitions))+"%)") tree.add_rule([ t[j] for j in remap[neighborhood] ],t[-1][0]) tree.write(golly.getdir('rules')+rule_name+".tree" ) return rule_name
def TriangularTransitionsToRuleTree_CheckerboardMethod(neighborhood, n_states, transitions, rule_name): # Background state 0 has no checkerboard, we infer it from its neighboring cells. def encode_lower(s): return s def encode_upper(s): ### AKT: this code causes syntax error in Python 2.3: ### return [0 if se==0 else n_states+se-1 for se in s] temp = [] for se in s: if se == 0: temp.append(0) else: temp.append(n_states + se - 1) return temp total_states = n_states * 2 - 1 if total_states > 256: golly.warn("Number of states exceeds Golly's limit of 256!") golly.exit() tree = RuleTree(total_states, 4) for t in transitions: # as lower tree.add_rule( [ encode_lower(t[0]), # C encode_upper(t[2]), # S encode_upper(t[1]), # E encode_upper(t[3]), # W range(total_states) ], # N encode_lower(t[4])[0]) # C' # as upper tree.add_rule( [ encode_upper(t[0]), # C range(total_states), # S encode_lower(t[3]), # E encode_lower(t[1]), # W encode_lower(t[2]) ], # N encode_upper(t[4])[0]) # C' # output the rule tree golly.show("Compressing rule tree and saving to file...") tree.write(golly.getdir('rules') + rule_name + '.tree')
def ConvertRuleTableTransitionsToRuleTree(neighborhood, n_states, transitions, input_filename): '''Convert a set of vonNeumann or Moore transitions directly to a rule tree.''' rule_name = os.path.splitext(os.path.split(input_filename)[1])[0] remap = { "vonNeumann": [0, 3, 2, 4, 1], # CNESW->CSEWN "Moore": [0, 5, 3, 7, 1, 4, 6, 2, 8] # C,N,NE,E,SE,S,SW,W,NW -> C,S,E,W,N,SE,SW,NE,NW } numNeighbors = len(remap[neighborhood]) - 1 tree = RuleTree(n_states, numNeighbors) for i, t in enumerate(transitions): golly.show("Building rule tree... (" + str(100 * i / len(transitions)) + "%)") tree.add_rule([t[j] for j in remap[neighborhood]], t[-1][0]) tree.write(golly.getdir('rules') + rule_name + ".tree") return rule_name
def SaveWss(file): g.setrule("b3/s23") wss = [ g.parse("bobo$4bo$o3bo$o3bo$4bo$bo2bo$2b3o!"), g.parse("bobo$4bo$o3bo$4bo$bo2bo$2b3o!"), g.parse("obo$3bo$3bo$o2bo$b3o!") ] wssList = [] for w in wss: for i in xrange(0, 4): wssList.append(PrepareList(g.evolve(w, i))) wssList.append( PrepareList(g.transform(g.evolve(w, i), 0, 0, 1, 0, 0, -1))) pickle.dump(wssList, open(path.join(g.getdir("data"), file), "wb"))
def golly_main(): bounding_box = g.getrect() g.show('Installing rule file...') src_rule = os.path.join(scriptdir, 'grills-examples', 'Grills.rule') dst_rule = os.path.join(g.getdir('rules'), 'Grills.rule') shutil.copyfile(src_rule, dst_rule) g.show('...installed.') if (len(bounding_box) == 0): g.setrule("Grills") g.exit("Please draw or load an input pattern.") elif (g.getrule() == "Grills"): golly_grills() elif (g.getrule() == "LifeHistory"): golly_lhistory() else: g.exit("Pattern has the incorrect rule: '%s' != '%s'" % (g.getrule(), 'Grills'))
def TriangularTransitionsToRuleTree_CheckerboardMethod(neighborhood,n_states,transitions,rule_name): # Background state 0 has no checkerboard, we infer it from its neighboring cells. def encode_lower(s): return s def encode_upper(s): ### AKT: this code causes syntax error in Python 2.3: ### return [0 if se==0 else n_states+se-1 for se in s] temp = [] for se in s: if se==0: temp.append(0) else: temp.append(n_states+se-1) return temp total_states = n_states*2 - 1 if total_states>256: golly.warn("Number of states exceeds Golly's limit of 256!") golly.exit() tree = RuleTree(total_states,4) for t in transitions: # as lower tree.add_rule([encode_lower(t[0]), # C encode_upper(t[2]), # S encode_upper(t[1]), # E encode_upper(t[3]), # W range(total_states)], # N encode_lower(t[4])[0]) # C' # as upper tree.add_rule([encode_upper(t[0]), # C range(total_states), # S encode_lower(t[3]), # E encode_lower(t[1]), # W encode_lower(t[2])], # N encode_upper(t[4])[0]) # C' # output the rule tree golly.show("Compressing rule tree and saving to file...") tree.write(golly.getdir('rules') + rule_name + '.tree')
def MakeTriangularIcons_SplittingMethod(n_states,colors,force_background,rule_name): width = 15*(n_states*n_states-1) if force_background and n_states>2: width+=15 height = 22 pixels = [[(0,0,0) for x in range(width)] for y in range(height)] for row in range(height): for column in range(width): if force_background and n_states>2 and column>=width-15: # add extra 'icon' filled with the intended background color pixels[row][column] = background_color else: # decide if this pixel is a lower or upper triangle iState = int(column/15) upper = int((iState+1) / n_states) lower = (iState+1) - upper*n_states is_upper = False is_lower = False if row<15: # big icon if (column-iState*15) > row: is_upper = True elif (column-iState*15) < row: is_lower = True elif (column-iState*15)<7: # little icon if (column-iState*15) > row-15: is_upper = True elif (column-iState*15) < row-15: is_lower = True if is_upper: pixels[row][column] = colors[upper] elif is_lower: pixels[row][column] = colors[lower] else: pixels[row][column] = 0,0,0 WriteBMP( pixels, golly.getdir('rules') + rule_name + ".icons" )
def saverule(self, name, comments, table, colours, icons): ruledir = g.getdir("rules") filename = ruledir + name + ".rule" results = "@RULE " + name + "\n\n" results += "*** File autogenerated by saverule. ***\n\n" results += comments results += "\n\n@TABLE\n\n" results += table results += "\n\n@COLORS\n\n" results += colours results += "\n\n@ICONS\n\n" results += icons # Change in behavior: always create rule table, # silently overwriting any file with the same name try: f = open(filename, 'w') f.write(results) f.close() except: g.warn("Unable to create rule table:\n" + filename)
def ConvertRuleTableTransitionsToRuleTree(neighborhood, n_states, transitions, input_filename, timelimit): '''Convert a set of vonNeumann or Moore transitions directly to a rule tree.''' rule_name = os.path.splitext(os.path.split(input_filename)[1])[0] remap = { "vonNeumann": [0, 3, 2, 4, 1], # CNESW->CSEWN "Moore": [0, 5, 3, 7, 1, 4, 6, 2, 8] # C,N,NE,E,SE,S,SW,W,NW -> C,S,E,W,N,SE,SW,NE,NW } numNeighbors = len(remap[neighborhood]) - 1 tree = RuleTree(n_states, numNeighbors) tree.input_filename = input_filename tree.timelimit = timelimit l = len(transitions) for i, t in enumerate(transitions): tree.percent = 100 * i // l tree.add_rule([t[j] for j in remap[neighborhood]], t[-1][0]) if tree.timeout > 0: break if tree.timeout == 0: tree.write(golly.getdir('rules') + rule_name + ".tree") # use rule_name.tree to create rule_name.rule (no icons) ConvertTreeToRule(rule_name, n_states, []) return rule_name, tree.timeout
def transition_function ( s ) : return ( s[0] + s[1] + s[2] ) % 5 ''' import golly from glife.RuleTree import * # exec() only works if all lines end with LF, so we need to convert # any Win line endings (CR+LF) or Mac line endings (CR) to LF CR = chr(13) LF = chr(10) try: exec(golly.getclipstr().replace(CR+LF,LF).replace(CR,LF)) MakeRuleTreeFromTransitionFunction( n_states, n_neighbors, transition_function, golly.getdir("rules")+name+".tree" ) # use name.tree to create name.rule (with no icons); # note that if name.rule already exists then we only replace the info in # the @TREE section to avoid clobbering any other info added by the user ConvertTreeToRule(name, n_states, []) golly.setalgo("RuleLoader") golly.setrule(name) golly.show("Created "+golly.getdir("rules")+name+".rule and switched to that rule.") except: import sys import traceback exception, msg, tb = sys.exc_info() golly.warn(\
# 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")+rule_name+".table", "w") # Now create the header for the rule table neighborhood = "Moore" # Incorporate Paul Callahan's hexagonal non-totaistic notation next? f.write("neighborhood:"+neighborhood+"\n") # The next line is where the magic happens! f.write("symmetries:rotate4reflect\n") # Lets stick with 2 states for now, but it would be interesting # to add generations-style decay states, as MCell's Weighted Life does. n_states = 2
# emulate-Margolus-table.py # reads a Margolus rule table, and produces a Moore-nhood rule table that # emulates it. import golly import os # ask user to select .table file fn = golly.opendialog('Open a Margolus table to emulate', 'Rule tables (*.table)|*.table', golly.getdir('rules')) if len(fn) == 0: golly.exit() # user hit Cancel # state s becomes 1+2s and 2+2s, the first for when the cell is currently # the top-left square of the Margolus partition, the other for when it isn't. def as_top_left(s): return 1+2*s def as_not_top_left(s): return 2+2*s # for the various symmetries we need to remap the inputs and outputs: symm = { 'none':[[0,1,2,3,4,5,6,7]], 'reflect_horizontal':[[0,1,2,3,4,5,6,7],[1,0,3,2,5,4,7,6]], 'reflect_vertical':[[0,1,2,3,4,5,6,7],[2,3,0,1,6,7,4,5]], 'rotate4': [[0,1,2,3,4,5,6,7],[2,0,3,1,6,4,7,5],[3,2,1,0,7,6,5,4],[1,3,0,2,5,7,4,6]], 'rotate4reflect':[ [0,1,2,3,4,5,6,7],[2,0,3,1,6,4,7,5],[3,2,1,0,7,6,5,4],[1,3,0,2,5,7,4,6],
if multistate: n = cells[i+2] * 4 + 1 im.putpixel((cells[i]-x,row), (colors[n],colors[n+1],colors[n+2])) else: im.putpixel((cells[i]-x,row), (colors[5],colors[6],colors[7])) cellcount += 1 if cellcount % 1000 == 0: # allow user to abort huge pattern/selection g.dokey( g.getkey() ) if cellcount == 0: g.exit("Selection is empty.") g.show("") # set initial directory for the save dialog initdir = "" savename = g.getdir("data") + "save-image.ini" try: # try to get the directory saved by an earlier run f = open(savename, 'r') initdir = f.readline() f.close() except: # this should only happen the very 1st time initdir = g.getdir("data") # remove any existing extension from layer name and append .png initfile = g.getname().split('.')[0] + ".png" # prompt user for output file (image type depends on extension) outfile = g.savedialog("Save image file", "PNG (*.png)|*.png|BMP (*.bmp)|*.bmp|GIF (*.gif)|*.gif" +
# -------------------------------------------------------------------- def savegen(filename, gen): try: f = open(filename, 'w') f.write(gen) f.close() except: g.warn("Unable to save given gen in file:\n" + filename) # -------------------------------------------------------------------- # use same file name as in goto.pl GotoINIFileName = g.getdir("data") + "goto.ini" previousgen = "" try: f = open(GotoINIFileName, 'r') previousgen = f.readline() f.close() if not validint(previousgen): previousgen = "" except: # should only happen 1st time (GotoINIFileName doesn't exist) pass gen = g.getstring( "Enter the desired generation number,\n" + "or -n/+n to go back/forwards by n:", previousgen, "Go to generation") if len(gen) == 0:
break modForward = 1 while (2 * step * modForward) % distForward != 0: modForward += 1 modBack = 1 while (2 * step * modBack) % distBack != 0: modBack += 1 modDY = distBack / modBack #Crucial init don't mark directionType = "B" #dir = r'C:\Users\SimSim314\Documents\GitHub\GlueNew\Glue\MonochromaticP2' dir = g.getdir("temp") g.show("Loading slow salvo recipes") recipes = RecipeConstructor() recipes.Init("OptimizedEven.txt", "OptimizedOdd.txt", "WSS.txt") #This code creates the Tail part of the caterloopillar g.show("Calculating WSS relative movement for Tail") SaveForwardSalvoData(dir) CreateWssMovementData(recipes, dir, True) wssMovementList = pickle.load( open( path.join(dir, str(step) + "_" + str(period) + "_ForwardWssBaseAuto.pkl"), "rb"))
def choose_pickles(g): """ Present a GUI to ask the users which folder of pickles they would like to analyze. """ # # Open a dialog window and ask the user to select two folders. # g.note("Analyze Pickles\n\n" + \ "You will be presented with two dialog menus:\n\n" + \ " (1) Select a FOLDER of pickled seeds.\n" + \ " (2) Select a FOLDER for storing the analysis results.\n\n" + \ "The pickles will be analyzed and the results will be stored.\n") # pickle_dir = g.opendialog("Choose a folder of pickled seeds", \ "dir", g.getdir("app")) analysis_dir = g.opendialog("Choose a folder for the analysis", \ "dir", g.getdir("app")) # g.note("Verify Selection\n\n" + \ "The chosen folder of pickled seeds:\n\n" + \ " " + pickle_dir + "\n\n" + \ "The chosen folder for the analysis results:\n\n" + \ " " + analysis_dir + "\n\n" + \ "Exit now if these folders are incorrect.") # # Make a list of the pickles in pickle_dir. # pickle_list = [] for file in os.listdir(pickle_dir): if file.endswith(".bin"): pickle_list.append(file) # # Verify that there are some ".bin" files in the list. # if (len(pickle_list) == 0): g.note("No pickles were found in the directory:\n\n" + \ " " + pickle_dir + "\n\n" + \ "Exiting now.") sys.exit(0) # # Make a hash table that maps pickle names to the last # generation number of the given group of pickles. # pickle_hash = hash_pickles(pickle_list) # # Calculate the size of the smallest group of pickles. # smallest_pickle_size = min(pickle_hash.values()) # # Report the base parts of the pickles and their maximum # values # sorted_pickle_names = sorted(pickle_hash.keys()) pickle_note = "" for pickle_base in sorted_pickle_names: pickle_note = pickle_note + \ pickle_base + " ranges from 0 to " + \ str(pickle_hash[pickle_base]) + "\n" g.note("These pickles were found:\n\n" + pickle_note + "\n" + \ "The analysis will range from 0 to " + \ str(smallest_pickle_size) + "\n\n" + \ "Exit now if this is not what you expected.") # return [pickle_dir, analysis_dir, \ sorted_pickle_names, smallest_pickle_size]
def EmulateTriangular(neighborhood,n_states,transitions_list,input_filename): '''Emulate a triangularVonNeumann or triangularMoore neighborhood rule table with a rule tree.''' input_rulename = os.path.splitext(os.path.split(input_filename)[1])[0] # read rule_name+'.colors' file if it exists force_background = False background_color = [0,0,0] cfn = os.path.split(input_filename)[0] + "/" + input_rulename + ".colors" try: cf = open(cfn,'r') except IOError: # use Golly's default random colours random_colors=[[0,0,0],[0,255,127],[127,0,255],[148,148,148],[128,255,0],[255,0,128],[0,128,255],[1,159,0], [159,0,1],[255,254,96],[0,1,159],[96,255,254],[254,96,255],[126,125,21],[21,126,125],[125,21,126], [255,116,116],[116,255,116],[116,116,255],[228,227,0],[28,255,27],[255,27,28],[0,228,227], [227,0,228],[27,28,255],[59,59,59],[234,195,176],[175,196,255],[171,194,68],[194,68,171], [68,171,194],[72,184,71],[184,71,72],[71,72,184],[169,255,188],[252,179,63],[63,252,179], [179,63,252],[80,9,0],[0,80,9],[9,0,80],[255,175,250],[199,134,213],[115,100,95],[188,163,0], [0,188,163],[163,0,188],[203,73,0],[0,203,73],[73,0,203],[94,189,0],[189,0,94]] colors = dict(zip(range(len(random_colors)),random_colors)) else: # read from the .colors file colors = {0:[0,0,0]} # background is black for line in cf: if line[0:6]=='color ': entries = map(int,line[6:].replace('=',' ').replace('\n',' ').split()) if len(entries)<4: continue # too few entries, ignore if entries[0]==0: force_background = True background_color = [entries[1],entries[2],entries[3]] else: colors.update({entries[0]:[entries[1],entries[2],entries[3]]}) # (we don't support gradients in .colors) rule_name = input_rulename + '_emulated' # (we use a special suffix to avoid picking up any existing .colors or .icons) # make a rule tree and some icons if n_states <= 16: TriangularTransitionsToRuleTree_SplittingMethod(neighborhood,n_states,transitions_list,rule_name) MakeTriangularIcons_SplittingMethod(n_states,colors,force_background,rule_name) total_states = n_states * n_states elif neighborhood=='triangularVonNeumann' and n_states <= 128: TriangularTransitionsToRuleTree_CheckerboardMethod(neighborhood,n_states,transitions_list,rule_name) MakeTriangularIcons_CheckerboardMethod(n_states,colors,force_background,rule_name) total_states = n_states * 2 - 1 else: golly.warn('Only support triangularMoore with 16 states or fewer, and triangularVonNeumann\n'+\ 'with 128 states or fewer.') golly.exit() if n_states==2: # the icons we wrote are monochrome, so we need a .colors file to avoid # them all having different colors or similar from Golly's preferences c = open(golly.getdir('rules')+rule_name+".colors",'w') if force_background: c.write('color = 0 '+' '.join(map(str,background_color))+'\n') for i in range(1,total_states): c.write('color = '+str(i)+' '+' '.join(map(str,colors[1]))+'\n') c.flush() c.close() return rule_name
for row in range(15): for column in range(15): pixels[row][(color-1)*15+column] = [palette[0],bg,bg][big[row][column]] for row in range(7): for column in range(7): pixels[15+row][(color-1)*15+column] = [palette[0],bg,bg][small[row][column]] for state in range(n_states): fg = palette[n_colors+state] # draw the 15x15 icon for row in range(15): for column in range(15): pixels[row][(encode(color,state)-1)*15+column] = [palette[0],bg,fg][big[row][column]] # draw the 7x7 icon for row in range(7): for column in range(7): pixels[15+row][(encode(color,state)-1)*15+column] = [palette[0],bg,fg][small[row][column]] WriteBMP( pixels, golly.getdir('rules') + rule_name + ".icons" ) # -- select the new rule -- golly.setalgo('RuleTree') golly.setrule(rule_name) golly.new(rule_name+'-demo.rle') golly.setcell(0,0,encode(0,0)) # start with a single turmite golly.show('Created '+rule_name+'.tree and '+rule_name+'.icons and selected that rule.')
# We owe a lot to MCell's implementation of the Margolus neighbourhood. Thanks Mirek! # # Tim Hutton <*****@*****.**> import golly as g # ask the user for the MCell string to convert (comma-separated works too) s = g.getstring("Enter a specification string.\n\nThis can either be an MCell format Margolus\nstring or just a comma-separated list of the 16 case indices.\n\nSee: http://psoup.math.wisc.edu/mcell/rullex_marg.html\n","MS,D0;8;4;3;2;5;9;7;1;6;10;11;12;13;14;15","Enter Margolus specification") # defaults to BBM # pull out the 16 numeric tokens that tell us what each partition becomes becomes = map(int,s.replace('M',' ').replace('S',' ').replace(',',' ').replace('D',' ').replace(';',' ').split()) # we should be able to write straight into the user's rules folder, # so we can call setrule immediately folder = g.getdir('rules') # construct a rule_name from next case indices rule_name = 'Margolus-' + '-'.join(map(str,becomes)) # ask the user to confirm this name or suggest a more readable one (e.g. "BBM") rule_name = g.getstring("Enter a name for the rule:",rule_name,"Enter rule name") # todo: detect slashes and tildes, tell user that can't change dir like that # open the rule table file for writing f = open(folder + rule_name + '.table','w') # write the initial descriptors and some variables f.write('# Emulation of Margolus neighbourhood for MCell string:\n# %s\n\n'%s) f.write('# (see: http://psoup.math.wisc.edu/mcell/rullex_marg.html )\n') f.write('#\n') f.write('# Rule table produced by convert-MCell-string.py, which can\n')
def TriangularTransitionsToRuleTree_SplittingMethod(neighborhood,n_states,transitions_list,rule_name): # each square cell is j*N+i where i is the lower triangle, j is the upper triangle # each i,j in (0,N] # (lower and upper are lists) def encode(lower,upper): return [ up*n_states+low for up in upper for low in lower ] # what neighbors of the lower triangle overlap neighbors of the upper triangle? lower2upper = { "triangularVonNeumann": [(0,1),(1,0)], "triangularMoore": [(0,1),(1,0),(2,12),(3,4),(4,3),(5,10),(6,11),(10,5),(11,6),(12,2)], } numNeighbors = { "triangularVonNeumann":4, "triangularMoore":8 } # convert transitions to list of list of sets for speed transitions = [[set(e) for e in t] for t in transitions_list] tree = RuleTree(n_states*n_states,numNeighbors[neighborhood]) # for each transition pair, see if we can apply them both at once to a square for i,t1 in enumerate(transitions): # as lower golly.show("Building rule tree... (pass 1 of 2: "+str(100*i/len(transitions))+"%)") for t2 in transitions: # as upper # we can only apply both rules at once if they overlap to some extent ### AKT: any() and isdisjoint() are not available in Python 2.3: ### if any( t1[j].isdisjoint(t2[k]) for j,k in lower2upper[neighborhood] ): ### continue any_disjoint = False for j,k in lower2upper[neighborhood]: if len(t1[j] & t2[k]) == 0: any_disjoint = True break if any_disjoint: continue # take the intersection of their inputs if neighborhood=="triangularVonNeumann": tree.add_rule( [ encode(t1[0]&t2[1],t1[1]&t2[0]), # C encode(range(n_states),t1[2]), # S encode(t2[3],range(n_states)), # E encode(range(n_states),t1[3]), # W encode(t2[2],range(n_states)) ], # N encode(t1[4],t2[4])[0] ) # C' elif neighborhood=="triangularMoore": tree.add_rule( [ encode(t1[0]&t2[1],t1[1]&t2[0]), # C encode(t1[7],t1[2]&t2[12]), # S encode(t1[4]&t2[3],t2[9]), # E encode(t1[9],t1[3]&t2[4]), # W encode(t1[12]&t2[2],t2[7]), # N encode(t1[6]&t2[11],t1[5]&t2[10]), # SE encode(range(n_states),t1[8]), # SW encode(t2[8],range(n_states)), # NE encode(t1[10]&t2[5],t1[11]&t2[6]) ], # NW encode(t1[13],t2[13])[0] ) # C' # apply each transition to an individual triangle, leaving the other unchanged for i,t in enumerate(transitions): golly.show("Building rule tree... (pass 2 of 2: "+str(100*i/len(transitions))+"%)") for t_1 in t[1]: if neighborhood=="triangularVonNeumann": # as lower triangle: tree.add_rule( [ encode(t[0],[t_1]), # C encode(range(n_states),t[2]), # S range(n_states*n_states), # E encode(range(n_states),t[3]), # W range(n_states*n_states) ], # N encode(t[4],[t_1])[0] ) # C' # as upper triangle: tree.add_rule( [ encode([t_1],t[0]), # C range(n_states*n_states), # S encode(t[3],range(n_states)), # E range(n_states*n_states), # W encode(t[2],range(n_states)) ], # N encode([t_1],t[4])[0] ) # C' elif neighborhood=="triangularMoore": # as lower triangle: tree.add_rule( [encode(t[0],[t_1]), # C encode(t[7],t[2]), # S encode(t[4],range(n_states)), # E encode(t[9],t[3]), # W encode(t[12],range(n_states)), # N encode(t[6],t[5]), # SE encode(range(n_states),t[8]), # SW range(n_states*n_states), # NE encode(t[10],t[11]) ], # NW encode(t[13],[t_1])[0] ) # C' # as upper triangle: tree.add_rule( [encode([t_1],t[0]), encode(range(n_states),t[12]), # S encode(t[3],t[9]), # E encode(range(n_states),t[4]), # W encode(t[2],t[7]), # N encode(t[11],t[10]), # SE range(n_states*n_states), # SW encode(t[8],range(n_states)), # NE encode(t[5],t[6]) ], # NW encode([t_1],t[13])[0] ) # C' # output the rule tree golly.show("Compressing rule tree and saving to file...") tree.write(golly.getdir('rules') + rule_name + '.tree')
def import_icons(rulename): global iconinfo31, iconinfo15, iconinfo7, iconcolors # replace any illegal filename chars with underscores rulename = rulename.replace("/","_").replace("\\","_") rulepath = g.getdir("rules") + rulename + ".rule" if not os.path.isfile(rulepath): rulepath = g.getdir("app") + "Rules/" + rulename + ".rule" if not os.path.isfile(rulepath): # there is no .rule file return try: # open in universal newline mode to handle LF, CR, or CR+LF rulefile = open(rulepath,"rU") except: g.exit("Failed to open .rule file: " + rulepath) foundicons = False xpmcount = 0 width = 0 height = 0 num_colors = 0 chars_per_pixel = 0 iconinfo = [] colordict = {} iconcolors = [] # WARNING: The code below must agree with how Golly looks for icon info # (see LoadRuleInfo and ParseIcons in wxlayer.cpp). In particular, if # there are multiple @ICONS sections then only the 1st one is used. for line in rulefile: if foundicons and line.startswith("@"): # start of another section (possibly another @ICONS section) break line = line.rstrip("\n") if line == "@ICONS": foundicons = True elif foundicons and line == "XPM": xpmcount = 1 iconinfo = [] colordict = {} elif foundicons and line in ("circles","diamonds","hexagons","triangles"): use_builtin_icons(line) # don't break (agrees with Golly) elif xpmcount > 0 and line[0] == "\"": # extract the stuff inside double quotes, ignoring anything after 2nd one line = line.lstrip("\"").split("\"")[0] if xpmcount == 1: # parse "width height num_colors chars_per_pixel" header = line.split() width = int(header[0]) height = int(header[1]) num_colors = int(header[2]) chars_per_pixel = int(header[3]) iconinfo.append(width) iconinfo.append(height) iconinfo.append(num_colors) iconinfo.append(chars_per_pixel) elif xpmcount > 1 and xpmcount <= 1 + num_colors: # parse color index line like "A c #FFFFFF" or "AB c #FF009900BB00" key, c, hexrgb = line.split() rgb = parse_hex(hexrgb.lstrip("#")) if not rgb in iconcolors: iconcolors.append(rgb) colordict[key] = rgb if xpmcount == 1 + num_colors: iconinfo.append(colordict) elif xpmcount <= 1 + num_colors + height: # simply append pixel data in line like "......AAA......" iconinfo.append(line) if xpmcount == 1 + num_colors + height: if width == 31: iconinfo31 = iconinfo if width == 15: iconinfo15 = iconinfo if width == 7: iconinfo7 = iconinfo xpmcount = 0 # skip any extra lines else: xpmcount += 1 rulefile.close()
def Main(self): g.show("left click on a pattern to change, 'h' for help") gollyMode = False while True: event = g.getevent() if ("key" in event and "return" in event) or (gollyMode and " a " in event): gollyMode = not gollyMode if gollyMode: g.show("In golly mode") g.update() else: g.show("left click on a pattern, right click to finish") g.setrule("B3/S23") g.setalgo("HashLife") g.reset() g.update() continue if gollyMode: if " delete " in event: g.clear(0) if "click" in event and "ctrl" in event and g.getxy() != "": x, y = g.getxy().split() cell = g.getcell(int(x), int(y)) if cell >= 0 and cell <= 1: g.setcell(int(x), int(y), 1 - cell) g.update() if " c " in event and "ctrl" in event and g.getselrect() != []: g.copy() if " v " in event and "ctrl" in event and g.getxy() != "": x, y = g.getxy().split() g.paste(int(x), int(y), "or") if " space " in event: if "ctrl" in event: g.run(10) else: g.run(1) g.doevent(event) continue if "click" in event: if "left" in event: if self.ExistinCircuitHandler() == None: if self.SignalClickHandler(event) == None: g.show("left click on a pattern, h for help") elif "key" in event: if " space " in event: for i in xrange(0, 30): g.run(60) g.update() g.reset() g.update() if " a " in event: if g.getrule() == "Perrier": g.setrule("B3/S23") g.setalgo("HashLife") g.update() else: g.setrule("Perrier") for key in self.smarCells: x, y = key.split(":") g.setcell(int(x), int(y), self.smarCells[key] + 2) gollyMode = True g.show("In golly mode") g.update() if " s " in event: fname = os.path.join(g.getdir("data"), "MetadataManager.json") #self.Save(fname) if " h " in event: noteMessage = "Viewing and Selecting\n\n" noteMessage += "'left click' to chose gun or glider\n" noteMessage += "'a' to see in colors, a to go back \n" noteMessage += "'space' see ahead 1800 generations \n" noteMessage += "'enter' gollyMode, stays in the script \n" noteMessage += "\n Editing Gun \n\n" noteMessage += "'left click' to place\n" noteMessage += "'right click' to switch gun/orientation \n" noteMessage += "'delete' to delete the gun \n" noteMessage += "'left-right arrow' - one step adjustment\n" noteMessage += "\n In Golly Mode \n\n" noteMessage += "'delete' to clear selection\n" noteMessage += "'ctrl' + 'click' to draw \n" noteMessage += "'ctrl' + 'c' to copy selection \n" noteMessage += "'ctrl' + 'v' to paste in mouse location \n" noteMessage += "'space' + to run 1 generation \n" noteMessage += "'ctrl' +'space' to run 10 generations \n" g.note(noteMessage)
import golly import os from glife.ReadRuleTable import * from glife.RuleTree import * from glife.EmulateTriangular import * from glife.EmulateMargolus import * from glife.EmulateOneDimensional import * from glife.EmulateHexagonal import * # ask user to select .table file filename = golly.opendialog('Open a rule table to convert:', 'Rule tables (*.table)|*.table', golly.getdir('rules')) if len(filename) == 0: golly.exit() # user hit Cancel # add new converters here as they become available: Converters = { "vonNeumann":ConvertRuleTableTransitionsToRuleTree, "Moore":ConvertRuleTableTransitionsToRuleTree, "triangularVonNeumann":EmulateTriangular, "triangularMoore":EmulateTriangular, "Margolus":EmulateMargolus, "square4_figure8v":EmulateMargolus, "square4_figure8h":EmulateMargolus, "square4_cyclic":EmulateMargolus, "oneDimensional":EmulateOneDimensional, "hexagonal":EmulateHexagonal, } golly.show("Reading from rule table file...")
# ask the user for the MCell string to convert (comma-separated works too) s = golly.getstring( '''Enter a specification string. This can either be an MCell format Margolus string or just a comma-separated list of the 16 case indices. See: http://psoup.math.wisc.edu/mcell/rullex_marg.html ''', "MS,D0;8;4;3;2;5;9;7;1;6;10;11;12;13;14;15","Enter Margolus specification") # defaults to BBM # pull out the 16 numeric tokens that tell us what each partition becomes becomes = map(int,s.replace('M',' ').replace('S',' ').replace(',',' ').replace('D',' ').replace(';',' ').split()) # write straight into the user's rules folder, so we can call setrule immediately folder = golly.getdir('rules') # construct a rule_name from next case indices rule_name = 'Margolus-' + '-'.join(map(str,becomes)) # ask the user to confirm this name or suggest a more readable one (e.g. "BBM") rule_name = golly.getstring("Enter a name for the rule:",rule_name,"Enter rule name") # todo: detect slashes and tildes, tell user that can't change dir like that # open the rule table file for writing tablepath = folder + rule_name + '.table' f = open(tablepath,'w') # write the initial descriptors and some variables f.write('# Emulation of Margolus neighbourhood for MCell string:\n# %s\n\n'%s) f.write('# (see: http://psoup.math.wisc.edu/mcell/rullex_marg.html )\n')
### transition_inputs = [leaving_color_behind[central_color]] + \ ### [ inputs if i==dir else not_arriving_from_here[i] for i in remap ] transition_inputs = [leaving_color_behind[central_color]] for i in remap: if i==dir: transition_inputs.append(inputs) else: transition_inputs.append(not_arriving_from_here[i]) transition_output = encode(central_color,s) tree.add_rule( transition_inputs, transition_output ) # default: square is left with no turmite present for output_color,inputs in leaving_color_behind.items(): tree.add_rule([inputs]+[range(total_states)]*4,output_color) tree.write(golly.getdir('rules')+rule_name+'.tree') # Write some colour icons so we can see what the turmite is doing # A simple ball drawing, with specular highlights (2) and anti-aliasing (3): icon15x15 = [[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,3,3,3,0,0,0,0,0,0], [0,0,0,0,3,1,1,1,1,1,3,0,0,0,0], [0,0,0,3,1,1,1,1,1,1,1,3,0,0,0], [0,0,3,1,1,2,1,1,1,1,1,1,3,0,0], [0,0,1,1,2,1,1,1,1,1,1,1,1,0,0], [0,3,1,1,2,1,1,1,1,1,1,1,1,3,0], [0,3,1,1,1,1,1,1,1,1,1,1,1,3,0], [0,3,1,1,1,1,1,1,1,1,1,1,1,3,0], [0,0,1,1,1,1,1,1,1,1,1,1,1,0,0], [0,0,3,1,1,1,1,1,1,1,1,1,3,0,0], [0,0,0,3,1,1,1,1,1,1,1,3,0,0,0],
### [ inputs if i==dir else not_arriving_from_here[i] for i in remap ] transition_inputs = [leaving_color_behind[central_color]] for i in remap: if i == dir: transition_inputs.append(inputs) else: transition_inputs.append(not_arriving_from_here[i]) transition_output = encode(central_color, s, opposite_dirs[dir]) tree.add_rule(transition_inputs, transition_output) # default: square is left with no turmite present for output_color, inputs in list(leaving_color_behind.items()): tree.add_rule([inputs] + [list(range(total_states))] * 4, output_color) rule_name = prefix + '_' + spec_string tree.write(golly.getdir('rules') + rule_name + '.tree') # Create some multi-colour icons so we can see what the turmite is doing # Andrew's ant drawing: (with added eyes (2) and anti-aliasing (3)) ant31x31 = [[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 ],
# recognizer1.3.py # Version 1.3: fixed line 44 for Python3 compatibility (remove encode() to make it work in Python2) # Version 1.2: wrote populate-sample-library.py exporter script, created a sample archive # Version 1.1: added ability to read tickstorun and matchtype limitations from RLE file # Version 1.0: first working version import golly as g import hashlib import os libpath = g.getdir("data") + "recognizer-library/" scriptFN = g.getdir("scripts") + "PatternBuildScript.py" libraryFN = libpath + "library.txt" xforms = [[1, 0, 0, 1], [0, -1, 1, 0], [-1, 0, 0, -1], [0, 1, -1, 0], [0, 1, 1, 0], [1, 0, 0, -1], [0, -1, -1, 0], [-1, 0, 0, 1]] xformnames = [ "identity", "rcw", "flip", "rccw", "swap_xy", "flip_y", "swap_xy_flip", "flip_x" ] # for glife script g.setrule("B3/S23") # returns a cell list sorted into TL/BR order def cellsort(clist): return g.evolve(clist, 0) def findTL(clist): return findTLsorted(cellsort(clist))
See: http://psoup.math.wisc.edu/mcell/rullex_marg.html ''', "MS,D0;8;4;3;2;5;9;7;1;6;10;11;12;13;14;15", "Enter Margolus specification") # defaults to BBM # pull out the 16 numeric tokens that tell us what each partition becomes becomes = map( int, s.replace('M', ' ').replace('S', ' ').replace(',', ' ').replace('D', ' ').replace(';', ' ').split()) # write straight into the user's rules folder, so we can call setrule immediately folder = golly.getdir('rules') # construct a rule_name from next case indices rule_name = 'Margolus-' + '-'.join(map(str, becomes)) # ask the user to confirm this name or suggest a more readable one (e.g. "BBM") rule_name = golly.getstring("Enter a name for the rule:", rule_name, "Enter rule name") # todo: detect slashes and tildes, tell user that can't change dir like that # open the rule table file for writing tablepath = folder + rule_name + '.table' f = open(tablepath, 'w') # write the initial descriptors and some variables f.write('# Emulation of Margolus neighbourhood for MCell string:\n# %s\n\n' %
### transition_inputs = [leaving_color_behind[central_color]] + \ ### [ inputs if i==dir else not_arriving_from_here[i] for i in remap ] transition_inputs = [leaving_color_behind[central_color]] for i in remap: if i==dir: transition_inputs.append(inputs) else: transition_inputs.append(not_arriving_from_here[i]) transition_output = encode(central_color,s) tree.add_rule( transition_inputs, transition_output ) # default: square is left with no turmite present for output_color,inputs in leaving_color_behind.items(): tree.add_rule([inputs]+[range(total_states)]*4,output_color) tree.write(golly.getdir('rules')+rule_name+'.tree') # Write some colour icons so we can see what the turmite is doing # A simple ball drawing, with specular highlights (2) and anti-aliasing (3): icon31x31 = [[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,3,1,1,1,1,1,1,1,1,1,3,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,3,1,1,1,1,1,1,1,1,1,1,1,1,1,3,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,0,0,0,0,0,0,0], [0,0,0,0,0,0,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,0,0,0,0,0,0], [0,0,0,0,0,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,0,0,0,0,0], [0,0,0,0,3,1,1,1,1,1,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,0,0,0,0], [0,0,0,0,1,1,1,1,1,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0], [0,0,0,3,1,1,1,1,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,0,0,0], [0,0,0,1,1,1,1,1,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0],
import golly as g import hashlib import os libpath = g.getdir("data") + "recognizer-library/" libraryFN = libpath + "library.txt" def removecomments(s): temp = s + "#" return temp[:temp.find("#")].rstrip() f = open(libraryFN, 'r') patnames=f.readlines() f.close() patnames+=["library"] # export the library file, too output_script_filename = g.getdir("scripts")+"populate-sample-library.py" outfile = open(output_script_filename,"w") outfile.write('import golly as g\nimport os\nlibpath = g.getdir("data") + "recognizer-library/"\n') outfile.write('os.mkdir(libpath)\n\n') for name in patnames: basename = removecomments(name) if basename=="library": realname=basename+".txt" else: realname=basename+".rle" temp = basename.split(" ") if len(temp)==2: basename, tickstorun = temp if len(temp)==3: basename, tickstorun, matchtype = temp
mi0, ma0 = testCA.get_mm() testCA.run(12) mi1, ma1 = testCA.get_mm() if mi0 == mi1 and ma0 == ma1: return True else: return False stablecnt = 0 explodecnt = 0 rule_cnt = 0 if not os.path.exists(os.path.join(g.getdir("files"), '3d')): os.makedirs(os.path.join(g.getdir("files"), '3d')) for iter in range(1000000): init_flags() testCA = CA3d(ruleFEV) if is_exploding(testCA): explodecnt += 1 g.show(str((stablecnt, explodecnt))) g.update() continue fail = True for i in range(3):
### [ inputs if i==dir else not_arriving_from_here[i] for i in remap ] transition_inputs = [leaving_color_behind[central_color]] for i in remap: if i == dir: transition_inputs.append(inputs) else: transition_inputs.append(not_arriving_from_here[i]) transition_output = encode(central_color, s, opposite_dirs[dir]) tree.add_rule(transition_inputs, transition_output) # default: square is left with no turmite present for output_color, inputs in leaving_color_behind.items(): tree.add_rule([inputs] + [range(total_states)] * 4, output_color) rule_name = prefix + '_' + spec_string tree.write(golly.getdir('rules') + rule_name + '.tree') # Write some colour icons so we can see what the turmite is doing # Andrew's ant drawing: (with added eyes (2) and anti-aliasing (3)) ant15x15 = [[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 2, 1, 2, 0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 3, 1, 3, 0, 0, 1, 0, 0, 0],
def ConvertTreeToRule(rule_name, total_states, icon_pixels): ''' Convert rule_name.tree to rule_name.rule and delete the .tree file. If rule_name.colors exists then use it to create an @COLORS section and delete the .colors file. If icon_pixels is supplied then add an @ICONS section. Format of icon_pixels (in this example there are 4 icons at each size): --------------------------------------------------------- | | | | | | | | | | | 31x31 | 31x31 | 31x31 | 31x31 | | | | | | | | | | | --------------------------------------------------------- | |.....| |.....| |.....| |.....| | 15x15 |.....| 15x15 |.....| 15x15 |.....| 15x15 |.....| | |.....| |.....| |.....| |.....| --------------------------------------------------------- |7x7|.........|7x7|.........|7x7|.........|7x7|.........| --------------------------------------------------------- The top layer of 31x31 icons is optional -- if not supplied (ie. the height is 22) then there are no gaps between the 15x15 icons. ''' rulepath = golly.getdir('rules')+rule_name+'.rule' treepath = golly.getdir('rules')+rule_name+'.tree' colorspath = golly.getdir('rules')+rule_name+'.colors' # get contents of .tree file try: treefile = open(treepath,'r') treedata = treefile.read() treefile.close() except: golly.exit('Failed to open .tree file: '+treepath) # if the .rule file already exists then only replace the @TREE section # so we don't clobber any other info added by the user if os.path.isfile(rulepath): ReplaceTreeSection(rulepath, treedata) os.remove(treepath) if os.path.isfile(colorspath): os.remove(colorspath) return # create a new .rule file rulefile = open(rulepath,'w') rulefile.write('@RULE '+rule_name+'\n\n') rulefile.write('@TREE\n\n') # append contents of .tree file, then delete that file rulefile.write(treedata) os.remove(treepath) # if .colors file exists then append @COLORS section and delete file if os.path.isfile(colorspath): colorsfile = open(colorspath,'r') rulefile.write('\n@COLORS\n\n') for line in colorsfile: if line.startswith('color') or line.startswith('gradient'): # strip off everything before 1st digit line = line.lstrip('colorgadient= \t') rulefile.write(line) colorsfile.close() os.remove(colorspath) # if icon pixels are supplied then append @ICONS section if len(icon_pixels) > 0: wd = len(icon_pixels[0]) ht = len(icon_pixels) iconsize = 15 # size of icons in top row if ht > 22: iconsize = 31 # 31x31 icons are present numicons = wd / iconsize # get colors used in all icons (we assume each icon size uses the same set of colors) colors, multi_colored = GetColors(icon_pixels, wd, ht) if len(colors) > 256: golly.warn('Icons use more than 256 colors!') rulefile.flush() rulefile.close() return if multi_colored: # create @COLORS section using color info in icon_pixels (not grayscale) rulefile.write('\n@COLORS\n\n') if numicons >= total_states: # extra icon is present so use top right pixel to set the color of state 0 R,G,B = icon_pixels[0][wd-1] rulefile.write('0 ' + str(R) + ' ' + str(G) + ' ' + str(B) + '\n') numicons -= 1 # set colors for each live state to the average of the non-black pixels # in each icon on top row (note we've skipped the extra icon detected above) for i in xrange(numicons): nbcount = 0 totalR = 0 totalG = 0 totalB = 0 for row in xrange(iconsize): for col in xrange(iconsize): R,G,B = icon_pixels[row][col + i*iconsize] if R > 0 or G > 0 or B > 0: nbcount += 1 totalR += R totalG += G totalB += B if nbcount > 0: rulefile.write(str(i+1) + ' ' + str(totalR / nbcount) + ' ' \ + str(totalG / nbcount) + ' ' \ + str(totalB / nbcount) + '\n') else: # avoid div by zero rulefile.write(str(i+1) + ' 0 0 0\n') # create @ICONS section using (r,g,b) triples in icon_pixels[row][col] rulefile.write('\n@ICONS\n') if ht > 22: # top row of icons is 31x31 CreateXPMIcons(colors, icon_pixels, 31, 0, 31, numicons, rulefile) CreateXPMIcons(colors, icon_pixels, 15, 31, 31, numicons, rulefile) CreateXPMIcons(colors, icon_pixels, 7, 46, 31, numicons, rulefile) else: # top row of icons is 15x15 CreateXPMIcons(colors, icon_pixels, 15, 0, 15, numicons, rulefile) CreateXPMIcons(colors, icon_pixels, 7, 15, 15, numicons, rulefile) rulefile.flush() rulefile.close()
g.show("") # -------------------------------------------------------------------- def savegen(filename, gen): try: f = open(filename, 'w') f.write(gen) f.close() except: g.warn("Unable to save given gen in file:\n" + filename) # -------------------------------------------------------------------- # use same file name as in goto.lua GotoINIFileName = g.getdir("data") + "goto.ini" previousgen = "" try: f = open(GotoINIFileName, 'r') previousgen = f.readline() f.close() if not validint(previousgen): previousgen = "" except: # should only happen 1st time (GotoINIFileName doesn't exist) pass gen = g.getstring("Enter the desired generation number,\n" + "or -n/+n to go back/forwards by n:", previousgen, "Go to generation") if len(gen) == 0:
# Shift current selection by given x y amounts using optional mode. # Author: Andrew Trevorrow ([email protected]), June 2006. # Updated to use exit command, Nov 2006. # Updated to check for bounded grid, Oct 2010. from glife import validint, inside from string import lower import golly as g selrect = g.getselrect() if len(selrect) == 0: g.exit("There is no selection.") # use same file name as in shift.lua INIFileName = g.getdir("data") + "shift.ini" oldparams = "0 0 or" try: f = open(INIFileName, 'r') oldparams = f.readline() f.close() except: # should only happen 1st time (INIFileName doesn't exist) pass answer = g.getstring("Enter x y shift amounts and an optional mode\n" + "(valid modes are copy/or/xor, default is or):", oldparams, "Shift selection") xym = answer.split() # extract x and y amounts if len(xym) == 0: g.exit() if len(xym) == 1: g.exit("Supply x and y amounts separated by a space.")
def ConvertTreeToRule(rule_name, total_states, icon_pixels): ''' Convert rule_name.tree to rule_name.rule and delete the .tree file. If rule_name.colors exists then use it to create an @COLORS section and delete the .colors file. If icon_pixels is supplied then add an @ICONS section. Format of icon_pixels (in this example there are 4 icons at each size): --------------------------------------------------------- | | | | | | | | | | | 31x31 | 31x31 | 31x31 | 31x31 | | | | | | | | | | | --------------------------------------------------------- | |.....| |.....| |.....| |.....| | 15x15 |.....| 15x15 |.....| 15x15 |.....| 15x15 |.....| | |.....| |.....| |.....| |.....| --------------------------------------------------------- |7x7|.........|7x7|.........|7x7|.........|7x7|.........| --------------------------------------------------------- The top layer of 31x31 icons is optional -- if not supplied (ie. the height is 22) then there are no gaps between the 15x15 icons. ''' rulepath = golly.getdir('rules') + rule_name + '.rule' treepath = golly.getdir('rules') + rule_name + '.tree' colorspath = golly.getdir('rules') + rule_name + '.colors' # get contents of .tree file try: treefile = open(treepath, 'r') treedata = treefile.read() treefile.close() except: golly.exit('Failed to open .tree file: ' + treepath) # if the .rule file already exists then only replace the @TREE section # so we don't clobber any other info added by the user if os.path.isfile(rulepath): ReplaceTreeSection(rulepath, treedata) os.remove(treepath) if os.path.isfile(colorspath): os.remove(colorspath) return # create a new .rule file rulefile = open(rulepath, 'w') rulefile.write('@RULE ' + rule_name + '\n\n') rulefile.write('@TREE\n\n') # append contents of .tree file, then delete that file rulefile.write(treedata) os.remove(treepath) # if .colors file exists then append @COLORS section and delete file if os.path.isfile(colorspath): colorsfile = open(colorspath, 'r') rulefile.write('\n@COLORS\n\n') for line in colorsfile: if line.startswith('color') or line.startswith('gradient'): # strip off everything before 1st digit line = line.lstrip('colorgadient= \t') rulefile.write(line) colorsfile.close() os.remove(colorspath) # if icon pixels are supplied then append @ICONS section if len(icon_pixels) > 0: wd = len(icon_pixels[0]) ht = len(icon_pixels) iconsize = 15 # size of icons in top row if ht > 22: iconsize = 31 # 31x31 icons are present numicons = wd / iconsize # get colors used in all icons (we assume each icon size uses the same set of colors) colors, multi_colored = GetColors(icon_pixels, wd, ht) if len(colors) > 256: golly.warn('Icons use more than 256 colors!') rulefile.flush() rulefile.close() return if multi_colored: # create @COLORS section using color info in icon_pixels (not grayscale) rulefile.write('\n@COLORS\n\n') if numicons >= total_states: # extra icon is present so use top right pixel to set the color of state 0 R, G, B = icon_pixels[0][wd - 1] rulefile.write('0 ' + str(R) + ' ' + str(G) + ' ' + str(B) + '\n') numicons -= 1 # set colors for each live state to the average of the non-black pixels # in each icon on top row (note we've skipped the extra icon detected above) for i in xrange(numicons): nbcount = 0 totalR = 0 totalG = 0 totalB = 0 for row in xrange(iconsize): for col in xrange(iconsize): R, G, B = icon_pixels[row][col + i * iconsize] if R > 0 or G > 0 or B > 0: nbcount += 1 totalR += R totalG += G totalB += B if nbcount > 0: rulefile.write(str(i+1) + ' ' + str(totalR / nbcount) + ' ' \ + str(totalG / nbcount) + ' ' \ + str(totalB / nbcount) + '\n') else: # avoid div by zero rulefile.write(str(i + 1) + ' 0 0 0\n') # create @ICONS section using (r,g,b) triples in icon_pixels[row][col] rulefile.write('\n@ICONS\n') if ht > 22: # top row of icons is 31x31 CreateXPMIcons(colors, icon_pixels, 31, 0, 31, numicons, rulefile) CreateXPMIcons(colors, icon_pixels, 15, 31, 31, numicons, rulefile) CreateXPMIcons(colors, icon_pixels, 7, 46, 31, numicons, rulefile) else: # top row of icons is 15x15 CreateXPMIcons(colors, icon_pixels, 15, 0, 15, numicons, rulefile) CreateXPMIcons(colors, icon_pixels, 7, 15, 15, numicons, rulefile) rulefile.flush() rulefile.close()
def EmulateTriangular(neighborhood,n_states,transitions_list,input_filename): '''Emulate a triangularVonNeumann or triangularMoore neighborhood rule table with a rule tree.''' input_rulename = os.path.splitext(os.path.split(input_filename)[1])[0] # read rule_name+'.colors' file if it exists force_background = False background_color = [0,0,0] cfn = os.path.split(input_filename)[0] + "/" + input_rulename + ".colors" try: cf = open(cfn,'r') except IOError: # use Golly's default random colours random_colors=[[0,0,0],[0,255,127],[127,0,255],[148,148,148],[128,255,0],[255,0,128],[0,128,255],[1,159,0], [159,0,1],[255,254,96],[0,1,159],[96,255,254],[254,96,255],[126,125,21],[21,126,125],[125,21,126], [255,116,116],[116,255,116],[116,116,255],[228,227,0],[28,255,27],[255,27,28],[0,228,227], [227,0,228],[27,28,255],[59,59,59],[234,195,176],[175,196,255],[171,194,68],[194,68,171], [68,171,194],[72,184,71],[184,71,72],[71,72,184],[169,255,188],[252,179,63],[63,252,179], [179,63,252],[80,9,0],[0,80,9],[9,0,80],[255,175,250],[199,134,213],[115,100,95],[188,163,0], [0,188,163],[163,0,188],[203,73,0],[0,203,73],[73,0,203],[94,189,0],[189,0,94]] colors = dict(list(zip(list(range(len(random_colors))),random_colors))) else: # read from the .colors file colors = {0:[0,0,0]} # background is black for line in cf: if line[0:6]=='color ': entries = list(map(int,line[6:].replace('=',' ').replace('\n',' ').split())) if len(entries)<4: continue # too few entries, ignore if entries[0]==0: force_background = True background_color = [entries[1],entries[2],entries[3]] else: colors.update({entries[0]:[entries[1],entries[2],entries[3]]}) # (we don't support gradients in .colors) rule_name = input_rulename + '_emulated' # (we use a special suffix to avoid picking up any existing .colors or .icons) # make a rule tree and some icons if n_states <= 16: TriangularTransitionsToRuleTree_SplittingMethod(neighborhood,n_states,transitions_list,rule_name) pixels = MakeTriangularIcons_SplittingMethod(n_states,colors,force_background,rule_name) total_states = n_states * n_states elif neighborhood=='triangularVonNeumann' and n_states <= 128: TriangularTransitionsToRuleTree_CheckerboardMethod(neighborhood,n_states,transitions_list,rule_name) pixels = MakeTriangularIcons_CheckerboardMethod(n_states,colors,force_background,rule_name) total_states = n_states * 2 - 1 else: golly.warn('Only support triangularMoore with 16 states or fewer, and triangularVonNeumann\n'+\ 'with 128 states or fewer.') golly.exit() if n_states==2: # the icons we wrote are monochrome, so we need a .colors file to avoid # them all having different colors or similar from Golly's preferences c = open(golly.getdir('rules')+rule_name+".colors",'w') if force_background: c.write('color = 0 '+' '.join(map(str,background_color))+'\n') for i in range(1,total_states): c.write('color = '+str(i)+' '+' '.join(map(str,colors[1]))+'\n') c.flush() c.close() # use rule_name.tree and rule_name.colors and icon info to create rule_name.rule ConvertTreeToRule(rule_name, total_states, pixels) return rule_name
import model_parameters as mparam import pickle # # Set the colours so they are suitable for printing. # The background should be light and the foreground # should be dark. # g.setcolors([0, 255, 255, 255, 1, 0, 0, 0]) # # Ask the user to select a pickle. # g.note("You will be asked to select a pickled seed file.\n" + \ "The top seed in the file will be inserted into Golly.") # pickle_path = g.opendialog("Select a pickled seed file (*.bin)", \ "(*.bin)|*.bin", g.getdir("app")) # # Read the pickle file. # pickle_handle = open(pickle_path, "rb") # rb = read binary pickle = pickle.load(pickle_handle) pickle_handle.close() # # Select the top seed from the pickle file. # seed = pickle[0] # # Write the seed into Golly. # for x in range(seed.xspan): for y in range(seed.yspan):
def TriangularTransitionsToRuleTree_SplittingMethod(neighborhood,n_states,transitions_list,rule_name): # each square cell is j*N+i where i is the lower triangle, j is the upper triangle # each i,j in (0,N] # (lower and upper are lists) def encode(lower,upper): return [ up*n_states+low for up in upper for low in lower ] # what neighbors of the lower triangle overlap neighbors of the upper triangle? lower2upper = { "triangularVonNeumann": [(0,1),(1,0)], "triangularMoore": [(0,1),(1,0),(2,12),(3,4),(4,3),(5,10),(6,11),(10,5),(11,6),(12,2)], } numNeighbors = { "triangularVonNeumann":4, "triangularMoore":8 } # convert transitions to list of list of sets for speed transitions = [[set(e) for e in t] for t in transitions_list] tree = RuleTree(n_states*n_states,numNeighbors[neighborhood]) # for each transition pair, see if we can apply them both at once to a square for i,t1 in enumerate(transitions): # as lower golly.show("Building rule tree... (pass 1 of 2: "+str(100*i//len(transitions))+"%)") for t2 in transitions: # as upper # we can only apply both rules at once if they overlap to some extent ### AKT: any() and isdisjoint() are not available in Python 2.3: ### if any( t1[j].isdisjoint(t2[k]) for j,k in lower2upper[neighborhood] ): ### continue any_disjoint = False for j,k in lower2upper[neighborhood]: if len(t1[j] & t2[k]) == 0: any_disjoint = True break if any_disjoint: continue # take the intersection of their inputs if neighborhood=="triangularVonNeumann": tree.add_rule( [ encode(t1[0]&t2[1],t1[1]&t2[0]), # C encode(list(range(n_states)),t1[2]), # S encode(t2[3],list(range(n_states))), # E encode(list(range(n_states)),t1[3]), # W encode(t2[2],list(range(n_states))) ], # N encode(t1[4],t2[4])[0] ) # C' elif neighborhood=="triangularMoore": tree.add_rule( [ encode(t1[0]&t2[1],t1[1]&t2[0]), # C encode(t1[7],t1[2]&t2[12]), # S encode(t1[4]&t2[3],t2[9]), # E encode(t1[9],t1[3]&t2[4]), # W encode(t1[12]&t2[2],t2[7]), # N encode(t1[6]&t2[11],t1[5]&t2[10]), # SE encode(list(range(n_states)),t1[8]), # SW encode(t2[8],list(range(n_states))), # NE encode(t1[10]&t2[5],t1[11]&t2[6]) ], # NW encode(t1[13],t2[13])[0] ) # C' # apply each transition to an individual triangle, leaving the other unchanged for i,t in enumerate(transitions): golly.show("Building rule tree... (pass 2 of 2: "+str(100*i//len(transitions))+"%)") for t_1 in t[1]: if neighborhood=="triangularVonNeumann": # as lower triangle: tree.add_rule( [ encode(t[0],[t_1]), # C encode(list(range(n_states)),t[2]), # S list(range(n_states*n_states)), # E encode(list(range(n_states)),t[3]), # W list(range(n_states*n_states)) ], # N encode(t[4],[t_1])[0] ) # C' # as upper triangle: tree.add_rule( [ encode([t_1],t[0]), # C list(range(n_states*n_states)), # S encode(t[3],list(range(n_states))), # E list(range(n_states*n_states)), # W encode(t[2],list(range(n_states))) ], # N encode([t_1],t[4])[0] ) # C' elif neighborhood=="triangularMoore": # as lower triangle: tree.add_rule( [encode(t[0],[t_1]), # C encode(t[7],t[2]), # S encode(t[4],list(range(n_states))), # E encode(t[9],t[3]), # W encode(t[12],list(range(n_states))), # N encode(t[6],t[5]), # SE encode(list(range(n_states)),t[8]), # SW list(range(n_states*n_states)), # NE encode(t[10],t[11]) ], # NW encode(t[13],[t_1])[0] ) # C' # as upper triangle: tree.add_rule( [encode([t_1],t[0]), encode(list(range(n_states)),t[12]), # S encode(t[3],t[9]), # E encode(list(range(n_states)),t[4]), # W encode(t[2],t[7]), # N encode(t[11],t[10]), # SE list(range(n_states*n_states)), # SW encode(t[8],list(range(n_states))), # NE encode(t[5],t[6]) ], # NW encode([t_1],t[13])[0] ) # C' # output the rule tree golly.show("Compressing rule tree and saving to file...") tree.write(golly.getdir('rules') + rule_name + '.tree')
def EmulateMargolus(neighborhood, n_states, transitions, input_filename): '''Emulate a Margolus or square4_* neighborhood rule table with a Moore neighborhood rule tree.''' rule_name = os.path.splitext(os.path.split(input_filename)[1])[0] total_states = 1 + 2 * n_states tree = RuleTree(total_states, 8) # now work through the transitions for tr in transitions: for iOutput, background_output in enumerate( BackgroundOutputs[neighborhood]): bg_inputs = BackgroundInputs[iOutput] iEntry = iOutput % 4 # (0=top-left, 1=top-right, 2=bottom-left, 3=bottom-right) rule_inputs = [] for i in range(9): if ForegroundInputs[iEntry][i] == -1: rule_inputs.append( encode(range(n_states), bg_inputs[i]) + [0]) # wildcard else: rule_inputs.append( encode(tr[ForegroundInputs[iEntry][i]], bg_inputs[i])) tree.add_rule(rule_inputs, encode(tr[iEntry + 4], background_output)[0]) # supply default behaviour: background still changes even if the state doesn't for iState in range(n_states): for iOutput, background_output in enumerate( BackgroundOutputs[neighborhood]): bg_inputs = BackgroundInputs[iOutput] tree.add_rule( [encode([iState], bg_inputs[0])] + [ encode(range(n_states), bg_inputs[i]) + [0] for i in range(1, 9) ], # wildcard encode([iState], background_output)[0]) # output the rule tree golly.show("Compressing rule tree and saving to file...") tree.write(golly.getdir('rules') + rule_name + '.tree') # also save a .colors file golly.show("Generating colors...") # read rule_name+'.colors' file if it exists cfn = os.path.split(input_filename)[0] + '/' + os.path.splitext( os.path.split(input_filename)[1])[0] + ".colors" try: cf = open(cfn, 'r') except IOError: # use Golly's default random colours random_colors = [[90, 90, 90], [0, 255, 127], [127, 0, 255], [148, 148, 148], [128, 255, 0], [255, 0, 128], [0, 128, 255], [1, 159, 0], [159, 0, 1], [255, 254, 96], [0, 1, 159], [96, 255, 254], [254, 96, 255], [126, 125, 21], [21, 126, 125], [125, 21, 126], [255, 116, 116], [116, 255, 116], [116, 116, 255], [228, 227, 0], [28, 255, 27], [255, 27, 28], [0, 228, 227], [227, 0, 228], [27, 28, 255], [59, 59, 59], [234, 195, 176], [175, 196, 255], [171, 194, 68], [194, 68, 171], [68, 171, 194], [72, 184, 71], [184, 71, 72], [71, 72, 184], [169, 255, 188], [252, 179, 63], [63, 252, 179], [179, 63, 252], [80, 9, 0], [0, 80, 9], [9, 0, 80], [255, 175, 250], [199, 134, 213], [115, 100, 95], [188, 163, 0], [0, 188, 163], [163, 0, 188], [203, 73, 0], [0, 203, 73], [73, 0, 203], [94, 189, 0], [189, 0, 94]] colors = dict(zip(range(len(random_colors)), random_colors)) else: # read from the .colors file colors = {} for line in cf: if line[0:5] == 'color': entries = map( int, line[5:].replace('=', ' ').replace('\n', ' ').split()) if len(entries) < 4: continue # too few entries, ignore colors.update( {entries[0]: [entries[1], entries[2], entries[3]]}) # (TODO: support gradients in .colors) # provide a deep blue background if none provided if not 0 in colors: colors.update({0: [0, 0, 120]}) c = open(golly.getdir('rules') + rule_name + ".colors", 'w') for col in colors.items()[:n_states]: c.write('color=' + str(col[0] * 2 + 1) + ' ' + ' '.join(map(str, col[1])) + '\n') c.write('color=' + str(col[0] * 2 + 2) + ' ' + ' '.join([str(int(x * 0.7)) for x in col[1]]) + '\n') # (darken slightly) c.flush() c.close() # use rule_name.tree and rule_name.colors to create rule_name.rule (no icon info) ConvertTreeToRule(rule_name, total_states, []) return rule_name
lines.append(line) res = [] for i in xrange(0, len(splitVals)): res.append(int(splitVals[i])) recipes.append(res) gld = g.parse("3o$o$bo!") block = g.parse("2o$2o!", 0, 0) d = 0 for r in recipes: g.putcells(block, d) for i in xrange(0, len(r)): g.putcells(gld, 200 * (i + 1) + d, 200 * (i + 1) + r[i]) d += 1000 g.run(50000) wssList = pickle.load(open(path.join(g.getdir("data"),"WssData.pkl"),"rb") ) objects = FindObjects(wssList) objects.sort() res = "Gen:50000,Step:200\n" for i in xrange(0, len(objects)): x, y, val = object[i] x -= 1000 * i res += str((x, y)) + ":" + lines[i] + "\n" with open(outputFile, "w") as text_file: text_file.write(res)
metalayer = g.addlayer() # create new layer # set rule to Life rule() Brle = Srle = "b10$b10$b26$b10$b10$b26$b10$b10$b!" for ch in Bvalues: ind = 32-int(ch)*4 # because B and S values are highest at the top! Brle = Brle[:ind] + "o" + Brle[ind+1:] for ch in Svalues: ind = 32-int(ch)*4 Srle = Srle[:ind] + "o" + Srle[ind+1:] RuleBits = pattern(Brle, 148, 1404) + pattern(Srle, 162, 1406) # load or generate the OFFcell tile: OFFcellFileName = g.getdir("data") + "metapixel-OFF.rle" ONcellFileName = g.getdir("data") + "metapixel-ON.rle" if os.access(OFFcellFileName, os.R_OK) and os.access(ONcellFileName, os.R_OK): g.show("Opening metapixel-OFF and metapixel-ON from saved pattern file.") OFFcell = pattern(g.transform(g.load(OFFcellFileName),-5,-5,1,0,0,1)) ONcell = pattern(g.transform(g.load(ONcellFileName),-5,-5,1,0,0,1)) else: g.show("Building OFF metacell definition...") # slide #21: programmables -------------------- LWSS = pattern("b4o$o3bo$4bo$o2bo!", 8, 0) DiagProximityFuse = pattern(""" bo$obo$bo2$4b2o$4b2o$59b2o$59b2o3$58b2o2b2o$9b2o3bo5bo5bo5bo5bo5bo5bo 7b2o2b2o$9bo3bobo3bobo3bobo3bobo3bobo3bobo3bobo$10bo2bo2bo2bo2bo2bo2bo
break modForward = 1 while (2 * step * modForward) % distForward != 0: modForward += 1 modBack = 1 while (2 * step * modBack) % distBack != 0: modBack += 1 modDY = distBack / modBack #Crucial init don't mark directionType = "B" #dir = r'C:\Users\SimSim314\Documents\GitHub\GlueNew\Glue\MonochromaticP2' dir = g.getdir("temp") g.show("Loading slow salvo recipes") recipes = RecipeConstructor() recipes.Init("OptimizedEven.txt", "OptimizedOdd.txt", "WSS.txt") #This code creates the Tail part of the caterloopillar g.show("Calculating WSS relative movement for Tail") SaveForwardSalvoData(dir) CreateWssMovementData(recipes, dir, True) wssMovementList = pickle.load(open(path.join(dir, str(step) + "_" + str(period) + "_ForwardWssBaseAuto.pkl"),"rb")) wssForward = pickle.load(open(path.join(dir, str(step) + "_ForwardSalvoAuto.pkl"),"rb")) g.show("creating the Tail part of the caterloopillar") recipes.Goto(-23, 1)
def EmulateMargolus(neighborhood,n_states,transitions,input_filename): '''Emulate a Margolus or square4_* neighborhood rule table with a Moore neighborhood rule tree.''' rule_name = os.path.splitext(os.path.split(input_filename)[1])[0]+'_emulated' total_states = 1+2*n_states tree = RuleTree(total_states,8) # now work through the transitions for tr in transitions: for iOutput,background_output in enumerate(BackgroundOutputs[neighborhood]): bg_inputs = BackgroundInputs[iOutput] iEntry = iOutput % 4 # (0=top-left, 1=top-right, 2=bottom-left, 3=bottom-right) rule_inputs = [] for i in range(9): if ForegroundInputs[iEntry][i]==-1: rule_inputs.append(encode( range(n_states), bg_inputs[i] ) + [0]) # wildcard else: rule_inputs.append(encode( tr[ForegroundInputs[iEntry][i]], bg_inputs[i] )) tree.add_rule( rule_inputs, encode( tr[iEntry+4], background_output )[0] ) # supply default behaviour: background still changes even if the state doesn't for iState in range(n_states): for iOutput,background_output in enumerate(BackgroundOutputs[neighborhood]): bg_inputs = BackgroundInputs[iOutput] tree.add_rule( [ encode( [iState], bg_inputs[0] ) ] + [ encode( range(n_states), bg_inputs[i] )+[0] for i in range(1,9) ], # wildcard encode( [iState], background_output )[0] ) # output the rule tree golly.show("Compressing rule tree and saving to file...") tree.write(golly.getdir('rules') + rule_name + '.tree') # also save a .colors file golly.show("Generating colors...") # read rule_name+'.colors' file if it exists cfn = os.path.split(input_filename)[0] + '/' + os.path.splitext(os.path.split(input_filename)[1])[0] + ".colors" try: cf = open(cfn,'r') except IOError: # use Golly's default random colours random_colors=[[90,90,90],[0,255,127],[127,0,255],[148,148,148],[128,255,0],[255,0,128],[0,128,255],[1,159,0], [159,0,1],[255,254,96],[0,1,159],[96,255,254],[254,96,255],[126,125,21],[21,126,125],[125,21,126], [255,116,116],[116,255,116],[116,116,255],[228,227,0],[28,255,27],[255,27,28],[0,228,227], [227,0,228],[27,28,255],[59,59,59],[234,195,176],[175,196,255],[171,194,68],[194,68,171], [68,171,194],[72,184,71],[184,71,72],[71,72,184],[169,255,188],[252,179,63],[63,252,179], [179,63,252],[80,9,0],[0,80,9],[9,0,80],[255,175,250],[199,134,213],[115,100,95],[188,163,0], [0,188,163],[163,0,188],[203,73,0],[0,203,73],[73,0,203],[94,189,0],[189,0,94]] colors = dict(zip(range(len(random_colors)),random_colors)) else: # read from the .colors file colors = {} for line in cf: if line[0:5]=='color': entries = map(int,line[5:].replace('=',' ').replace('\n',' ').split()) if len(entries)<4: continue # too few entries, ignore colors.update({entries[0]:[entries[1],entries[2],entries[3]]}) # (TODO: support gradients in .colors) # provide a deep blue background if none provided if not 0 in colors: colors.update({0:[0,0,120]}) c = open(golly.getdir('rules')+rule_name+".colors",'w') for col in colors.items()[:n_states]: c.write('color='+str(col[0]*2+1)+' '+' '.join(map(str,col[1]))+'\n') c.write('color='+str(col[0]*2+2)+' '+' '.join([ str(int(x*0.7)) for x in col[1] ])+'\n') # (darken slightly) c.flush() c.close() return rule_name
# Randomly fill cells in the current selection. # Author: Andrew Trevorrow ([email protected]), March 2011. import golly as g from glife import rect, validint from time import time from random import randint r = rect(g.getselrect()) if r.empty: g.exit("There is no selection.") maxlive = g.numstates() - 1 # use previous values if they exist inifilename = g.getdir("data") + "random-fill.ini" previousvals = "50 1 " + str(maxlive) try: f = open(inifilename, "r") previousvals = f.readline() f.close() except: # should only happen 1st time (inifilename doesn't exist) pass result = g.getstring( "Enter percentage minstate maxstate values\n" + "where the percentage is an integer from 0 to 100\n" + "and the state values are integers from 1 to " + str(maxlive) + "\n"