def goto(newgen, delay): g.show("goto running, hit escape to abort...") oldsecs = time() # before stepping we advance by 1 generation, for two reasons: # 1. if we're at the starting gen then the *current* step size # will be saved (and restored upon Reset/Undo) rather than a # possibly very large step size # 2. it increases the chances the user will see updates and so # get some idea of how long the script will take to finish # (otherwise if the base is 10 and a gen like 1,000,000,000 # is given then only a single step() of 10^9 would be done) if delay <= 1.0: g.run(1) newgen -= 1 # use fast stepping (thanks to PM 2Ring) for i, d in enumerate(intbase(newgen, g.getbase())): if d > 0: g.setstep(i) for j in range(d): if g.empty(): g.show("Pattern is empty.") return g.step() newsecs = time() if newsecs - oldsecs >= delay: # time to do an update? oldsecs = newsecs g.update() g.show("")
def randtopo(num, low, high): hashlist = [] topolist = [] arealist = [] i = 0 while i < num: size = random.choice(range(low, high + 1)) area = size * size sel = [size, size, size, size] g.new('') randfill(sel, (1 + random.randrange(area)) * int(100 / area)) if g.empty(): continue h = g.hash(g.getrect()) if h in hashlist: continue else: hashlist.append(h) pbox = g.getrect() actarea = pbox[2] * pbox[3] clist = g.getcells(g.getrect()) g.store(clist, dir + 'topo_area%i_hash%i' % (actarea, h)) clist.insert(0, pbox[2]) #prepare for tiling clist.insert(1, pbox[3]) topolist.append(clist) arealist.append(actarea) i = i + 1 continue return [topolist, hashlist, arealist]
def goto(newgen, delay): g.show("goto running, hit escape to abort...") oldsecs = time() # before stepping we advance by 1 generation, for two reasons: # 1. if we're at the starting gen then the *current* step size # will be saved (and restored upon Reset/Undo) rather than a # possibly very large step size # 2. it increases the chances the user will see updates and so # get some idea of how long the script will take to finish # (otherwise if the base is 10 and a gen like 1,000,000,000 # is given then only a single step() of 10^9 would be done) if delay <= 1.0: g.run(1) newgen -= 1 # use fast stepping (thanks to PM 2Ring) for i, d in enumerate(intbase(newgen, g.getbase())): if d > 0: g.setstep(i) for j in xrange(d): if g.empty(): g.show("Pattern is empty.") return g.step() newsecs = time() if newsecs - oldsecs >= delay: # time to do an update? oldsecs = newsecs g.update() g.show("")
def gofast(newgen, delay): ''' Fast goto ''' #Save current settings oldbase = g.getbase() # oldhash = g.setoption("hashing", True) g.show('gofast running, hit escape to abort') oldsecs = time() #Advance by binary powers, to maximize advantage of hashing g.setbase(2) for i, b in enumerate(intbits(newgen)): if b: g.setstep(i) g.step() g.dokey(g.getkey()) newsecs = time() if newsecs - oldsecs >= delay: # do an update every sec oldsecs = newsecs g.update() if g.empty(): break g.show('') #Restore settings # g.setoption("hashing", oldhash) g.setbase(oldbase)
def envelope(): # draw stacked layers using same location and scale g.setoption("stacklayers", 1) g.show("Hit escape key to stop script...") while True: g.run(1) if g.empty(): g.show("Pattern died out.") break # copy current pattern to envelope layer; # we temporarily disable event checking so thumb scrolling # and other mouse events won't cause confusing changes currpatt = g.getcells(g.getrect()) g.check(0) g.setlayer(envindex) g.putcells(currpatt) g.setlayer(currindex) g.check(1) step = 1 exp = g.getstep() if exp > 0: step = g.getbase()**exp if int(g.getgen()) % step == 0: # display all 3 layers (envelope, start, current) g.update()
def envelope (): # draw stacked layers using same location and scale g.setoption("stacklayers", 1) g.show("Hit escape key to stop script...") while True: g.run(1) if g.empty(): g.show("Pattern died out.") break # copy current pattern to envelope layer; # we temporarily disable event checking so thumb scrolling # and other mouse events won't cause confusing changes currpatt = g.getcells(g.getrect()) g.check(0) g.setlayer(envindex) g.putcells(currpatt) g.setlayer(currindex) g.check(1) step = 1 exp = g.getstep() if exp > 0: step = g.getbase()**exp if int(g.getgen()) % step == 0: # display all 3 layers (envelope, start, current) g.update()
def testRule(rulestr): r = g.getrect() if r: g.select(r) g.clear(0) g.putcells(origPatt) g.setrule(rulestr) g.run(stabGen) if g.empty(): return () pop = int(g.getpop()) if (pop < minPop or pop > maxPop): return () r = g.getrect() testPatt = g.transform(g.getcells(r), -r[0], -r[1]) testPop = int(g.getpop()) testRect = g.getrect() stabPatt = list(testPatt) stabPop = testPop for ii in xrange(maxGen): g.run(1) pop = int(g.getpop()) if (pop < minPop or pop > maxPop): break if (pop == testPop): # Test for periodicity r = g.getrect() if testPatt == g.transform(g.getcells(r), -r[0], -r[1]): period = ii + 1 dy, dx = sss.minmaxofabs( (r[0] - testRect[0], r[1] - testRect[1])) if (dx == 0): # Oscillator (reject if low period or bOsc is False) if bOsc and period >= minOscP: return (0, 0, period) elif (period >= minShipP): # Spaceship return (dx, dy, period) elif ((dx + dy / 1.9) / (period * 1.0) > minSpeed and period >= fastShipP): # Fast spaceship return (dx, dy, period) break # Pattern is a low period oscillator or spaceship # Stability check if (ii % stabCheckP == 0): r = g.getrect() # First check for BBox expansion if maxDim > 0 and max(r[2:4]) > maxDim: # Pattern is expanding # XXX Attempt to separate components expanding in different directions break currPatt = g.transform(g.getcells(r), -r[0], -r[1]) if (pop == stabPop and currPatt == stabPatt): # Pattern has stabilised to low period oscillator / spaceship break stabPop = pop stabPatt = list(currPatt) return ()
def setminisorule(period): if g.empty(): return if period < 1: return b_need, s_need, b_OK, s_OK = getRuleRangeElems(period, ruleRange='min') minrulestr = 'B' + ''.join(sorted(b_need)) + '/S' + ''.join(sorted(s_need)) g.setrule(minrulestr) return minrulestr
def replace_sel(IN, ): od = IN.split('/') od = [int(x) for x in od] sel = (g.getselrect() != []) if g.empty(): g.show('universe is empty') else: if sel: replace(g.getselrect(), od) else: replace(g.getrect(), od)
def goto(newgen): currgen = int(g.getgen()) if newgen < currgen: # try to go back to starting gen (not necessarily 0) and # then forwards to newgen; note that reset() also restores # algorithm and/or rule, so too bad if user changed those # after the starting info was saved; # first save current location and scale midx, midy = g.getpos() mag = g.getmag() g.reset() # restore location and scale g.setpos(midx, midy) g.setmag(mag) # current gen might be > 0 if user loaded a pattern file # that set the gen count currgen = int(g.getgen()) if newgen < currgen: g.error("Can't go back any further; pattern was saved " + "at generation " + str(currgen) + ".") return if newgen == currgen: return oldsecs = time() # before stepping we advance by 1 generation, for two reasons: # 1. if we're at the starting gen then the *current* step size # will be saved (and restored upon Reset/Undo) rather than a # possibly very large step size # 2. it increases the chances the user will see updates and so # get some idea of how long the script will take to finish # (otherwise if the base is 10 and a gen like 1,000,000,000 # is given then only a single step() of 10^9 would be done) g.run(1) currgen += 1 # use fast stepping (thanks to PM 2Ring) oldstep = g.getstep() for i, d in enumerate(intbase(newgen - currgen, g.getbase())): if d > 0: g.setstep(i) for j in xrange(d): if g.empty(): g.show("Pattern is empty.") return g.step() newsecs = time() if newsecs - oldsecs >= 1.0: # do an update every sec oldsecs = newsecs g.update() g.setstep(oldstep)
def shrink(): global d if g.empty(): return g.select(g.getrect()) d=int(10000*float(g.getpop())/(int(g.getselrect()[2])*int(g.getselrect()[3]))) while d<100: bbox=g.getselrect() bbox[0]=bbox[0]+1 bbox[1]=bbox[1]+1 bbox[2]=bbox[2]-2 bbox[3]=bbox[3]-2 g.select(bbox) g.shrink() d=int(10000*float(g.getpop())/(int(g.getselrect()[2])*int(g.getselrect()[3])))
def better_randfill(): g.new('') g.select([-10, -10, GRID_SIZE[0], GRID_SIZE[1]]) g.randfill(random.randrange(50)) g.select([]) g.autoupdate(True) cnt = 0 for x in range(0, GENS): cnt += 1 if not g.empty(): g.run(1) if is_static(): break time.sleep(0.05) else: break if cnt % 10 == 0: g.fit()
def find_all_glider_idx(mask): idxs = extract_indexes(mask) idxs.sort(key=lambda idx: (1.01 * gliders_in[idx][0] + gliders_in[idx][1])) copy_idxs = idxs[:] for edge_i in enum_shooters(mask): reaction_cells = shoot_defs[edge_i][4] stable_cells = shoot_defs[edge_i][5] for g_i in list(copy_idxs): g.new("") for g_j in idxs: x, y, idx = gliders_in[g_j] if g_j == g_i: g.putcells(g.evolve(reaction_cells, idx), x, y) else: g.putcells(g.evolve(gld, idx), x - 128, y + 128) g.setbase(8) g.setstep(3) g.step() x, y, _ = gliders_in[g_i] # test if the pattern consists of the stable cells plus the # necessary gliders and nothing else g.putcells(stable_cells, x, y, 1, 0, 0, 1, "xor") if int(g.getpop()) != 5 * len(idxs): continue for g_j in idxs: x, y, idx = gliders_in[g_j] g.putcells(g.evolve(gld, idx), x, y, 1, 0, 0, 1, "xor") if g.empty(): copy_idxs.remove(g_i) yield g_i,edge_i
def run_patt(known_cells): global patt_count, meth_count g.new("PlutoniumSearch") g.reset() g.update() patt_count += 1 #patt = g.parse(known_cells + "!") patt = g.parse(known_cells[1:] + "!") #g.note(known_cells[1:] + "!") g.putcells(patt) g.update() hashlist = {} for gene in range(999): if g.empty(): break if g.hash(g.getrect()) in hashlist: p = int(g.getgen()) - hashlist[g.hash(g.getrect())] if not p in boring_periods: g.reset() g.save("p" + str(p) + "_" + str(cnt[p]) + ".rle", "rle") cnt[p] += 1 break else: hashlist[g.hash(g.getrect())] = int(g.getgen()) g.run(1) """ except: # Pattern dies if int(g.getgen()) > min_lifespan: meth_count += 1 newlifespan = int(g.getgen()) g.new("Saving methuselah") g.putcells(patt) try: g.save("diehard-" + str(newlifespan) + ".rle", "rle") except: pass g.update() #max_final_pop = newpop break""" #g.warn(str(hashlist)) g.show(str(patt_count) + "/" + str(2**(bx * by)))
def get_pop(numsteps=44100, x=256, y=256): if numsteps < 1: g.exit("numsteps must be greater than 0.") randfill(x, y) poplist = [int(g.getpop())] extinction = sys.maxint rule = g.getrule() oldsecs = time.time() for i in xrange(numsteps - 1): if g.empty(): extinction = int(g.getgen()) break g.step() poplist.append(int(g.getpop())) newsecs = time.time() if newsecs - oldsecs >= 1.0: oldsecs = newsecs g.show("Rule {}, Step {} of {}".format(rule, i + 1, numsteps)) return (poplist, extinction)
def EventLoop(): global volume, genspersec nextgen = 0.0 running = True while True: space = False event = g.getevent() if len(event) == 0: sleep(0.005) # don't hog CPU if idle elif event == "key space none": running = False space = True nextgen = 0 elif event == "key return none": running = not running elif event == "key h none": ShowHelp() elif event == "key up none": volume = min(1.0, volume + 0.1) ShowInfo() elif event == "key down none": volume = max(0.0, volume - 0.1) ShowInfo() elif event == "key = none" or event == "key + none": genspersec = min(30, genspersec + 1) ShowInfo() elif event == "key - none": genspersec = max(1, genspersec - 1) ShowInfo() else: g.doevent(event) # might be a keyboard shortcut if (running or space) and time() >= nextgen: g.run(1) if g.empty(): g.exit("The pattern died.") PlaySound() g.update() if not space: nextgen = time() + 1.0 / genspersec
def getRuleRangeElems(period, ruleRange='minmax'): if g.empty(): return if period < 1: return rule = g.getrule().split(':')[0] if not (rule[0] == 'B' and '/S' in rule): g.exit('Please set Golly to an isotropic 2-state rule.') # Parse rule string to list of transitions for Birth and Survival oldrule = rule Bstr, Sstr = rule.split('/') Bstr = Bstr.lstrip('B') Sstr = Sstr.lstrip('S') b_need = parseTransitions(Bstr) b_OK = list(b_need) s_need = parseTransitions(Sstr) s_OK = list(s_need) patt = g.getcells(g.getrect()) # Record behavior of pattern in current rule clist = [] poplist = [] for i in range(0, period): g.run(1) clist.append(g.getcells(g.getrect())) poplist.append(g.getpop()) finalpop = g.getpop() if 'min' in ruleRange: # Test all rule transitions to determine if they are required for t in b_OK: b_need.remove(t) g.setrule('B' + ''.join(b_need) + '/S' + Sstr) r = g.getrect() if r: g.select(r) g.clear(0) g.putcells(patt) for j in range(0, period): g.run(1) try: if not (clist[j] == g.getcells(g.getrect())): b_need.append(t) break except: b_need.append(t) break b_need.sort() for t in s_OK: s_need.remove(t) g.setrule('B' + Bstr + '/S' + ''.join(s_need)) r = g.getrect() if r: g.select(r) g.clear(0) g.putcells(patt) for j in range(0, period): g.run(1) try: if not (clist[j] == g.getcells(g.getrect())): s_need.append(t) break except: s_need.append(t) break s_need.sort() if 'max' in ruleRange: # Test unused rule transitions to determine if they are allowed allRuleElem = [t for l in Hensel for t in l] for t in allRuleElem: if t in b_OK: continue b_OK.append(t) g.setrule('B' + ''.join(b_OK) + '/S' + Sstr) r = g.getrect() if r: g.select(r) g.clear(0) g.putcells(patt) for j in range(0, period): g.run(1) try: if not (clist[j] == g.getcells(g.getrect())): b_OK.remove(t) break except: b_OK.remove(t) break b_OK.sort() for t in allRuleElem: if t in s_OK: continue s_OK.append(t) g.setrule('B' + Bstr + '/S' + ''.join(s_OK)) r = g.getrect() if r: g.select(r) g.clear(0) g.putcells(patt) for j in range(0, period): g.run(1) try: if not (clist[j] == g.getcells(g.getrect())): s_OK.remove(t) break except: s_OK.remove(t) break s_OK.sort() r = g.getrect() if r: g.select(r) g.clear(0) g.putcells(patt) g.setrule(oldrule) return b_need, s_need, b_OK, s_OK
# Use multiple layers to create a history of the current pattern. # The "envelope" layer remembers all live cells. # Author: Andrew Trevorrow ([email protected]), December 2006. # Updated for better compatibility with envelope.pl, June 2007. # Updated to use new setcolors command, September 2008. import golly as g if g.empty(): g.exit("There is no pattern.") currindex = g.getlayer() startindex = 0 envindex = 0 startname = "starting pattern" envname = "envelope" if currindex > 1 and g.getname(currindex - 1) == startname \ and g.getname(currindex - 2) == envname : # continue from where we left off startindex = currindex - 1 envindex = currindex - 2 elif currindex + 2 < g.numlayers() \ and g.getname(currindex + 1) == startname \ and g.getname(currindex) == envname : # switch from envelope layer to current layer and continue currindex += 2 g.setlayer(currindex) startindex = currindex - 1 envindex = currindex - 2
while not o.oscillating() and iterations<max_iter: g.step() iterations += 1 end_time = time() status = o.status if iterations >= max_iter: status = "timeout" #f2.write("%d, %s\n" % (trial_number, str(test_list))) #g.store(test_list, rlepatterns_filename%(trial_number)) elif initial_pop<=g.getpop() and status == '': if iterations==0: status = "no_change" elif g.empty() == False: current_clist = g.hash(g.getrect()) g.step() next_clist = g.hash(g.getrect()) if current_clist == next_clist: status = "stable" else: status = "glider" #if status is 'glider': # g.store(test_list, rlepatterns_filename%(trial_number)) d = calculate_density() f.write("%d,%d,%s,%s,%f,%f,%s,%f\n" % (trial_number, iterations, initial_pop, g.getpop(), initial_d, d, status, end_time-start_time)) progress = float(100*(trial_number+1)) / float(number_of_tests)
# Use the current selection to create a toroidal universe. # Author: Andrew Trevorrow ([email protected]), Sept 2010. from glife import inside, outside import golly as g selrect = g.getselrect() if len(selrect) == 0: g.exit("There is no selection.") x = selrect[0] y = selrect[1] wd = selrect[2] ht = selrect[3] selcells = g.getcells(selrect) if not g.empty(): g.clear(inside) g.clear(outside) # get current rule, remove any existing suffix, then add new suffix rule = g.getrule().split(":")[0] g.setrule(rule + ":T" + str(wd) + "," + str(ht)) newx = -int(wd/2) newy = -int(ht/2) selrect[0] = newx selrect[1] = newy g.select(selrect) if len(selcells) > 0: g.putcells(selcells, newx - x, newy - y) g.fitsel()
dmax = int(input.split('/')[1]) poplist = [] hashlist = [int(g.hash(g.getrect()))] popold = int(g.getpop()) dead = 0 if g.getrule().split(':')[0] in dict_lc: popfunc = lambda: popcount() else: popfunc = lambda: g.getpop() for i in range(numsteps): g.run(1) if g.empty(): break poplist.append(int(popfunc())) h = int(g.hash(g.getrect())) if h in hashlist: break hashlist.append(h) layername = "recurrent plot" poplayer = -1 for i in xrange(g.numlayers()): if g.getname(i) == layername: poplayer = i break if poplayer == -1 and g.numlayers() == g.maxlayers():
def area(): if not g.empty(): shrink() return g.getselrect()[2] * g.getselrect()[3] else: return 0
def density(): if not g.empty(): shrink() return d else: return 0
def boxdm(orientation): if not g.empty(): shrink() return g.getselrect()[orientation] else: return 0
# Fill clicked region with current drawing state. # Author: Andrew Trevorrow ([email protected]), Jan 2011. import golly as g from time import time # avoid an unbounded fill if g.empty(): if g.getwidth() == 0 or g.getheight() == 0: g.exit("You cannot fill an empty universe that is unbounded!") else: # set fill limits to the pattern's bounding box # (these will be extended below if the grid is bounded) r = g.getrect() minx = r[0] miny = r[1] maxx = minx + r[2] - 1 maxy = miny + r[3] - 1 # allow filling to extend to the edges of bounded grid if g.getwidth() > 0: minx = -int(g.getwidth()/2) maxx = minx + g.getwidth() - 1 if g.getheight() > 0: miny = -int(g.getheight()/2) maxy = miny + g.getheight() - 1 # ------------------------------------------------------------------------------ def checkneighbor(x, y, oldstate): # first check if x,y is outside fill limits
''' Calculate the heat of the current oscillator/spaceship ''' import golly as g from glife import validint # Python versions < 2.4 don't have "set" built-in try: set except NameError: from sets import Set as set def chunks(l,w): for i in xrange(0, len(l), 2): yield l[i]+(w*l[i+1]) if g.empty(): g.exit("The pattern is empty.") s = g.getstring("Enter the period:","", "Heat calculator") if not validint(s): g.exit('Bad number: %s' % s) numsteps = int(s) if numsteps < 2: g.exit('Period must be at least 2.') g.show('Processing...') heat = 0; maxheat = 0; minheat = 9*g.getpop(); for i in range(0, numsteps):
# Written by Nathaniel Johnston # March 28, 2009 # Python 3.x udates by Book, March 1, 2022 # https://conwaylife.com/forums/viewtopic.php?p=142312#p142312 ''' Calculate the heat of the current oscillator/spaceship ''' from glife import getstring, validint import golly as g def chunks(l, w): for i in range(0, len(l), 2): yield l[i] + (w * l[i + 1]) if g.empty(): g.exit("The pattern is empty.") s = g.getstring("Enter the period:", "", "Heat calculator") if not validint(s): g.exit('Bad number: %s' % s) numsteps = int(s) if numsteps < 2: g.exit('Period must be at least 2.') g.show('Processing...') heat = 0 maxheat = 0 minheat = int(9 * g.getpop()) for i in range(0, numsteps):
g.setrule(rule) # Set Directory Back to Parent Folder fileLoc = g.getdir("rules") + generationDir # Creates Subfolder specific to Rule Set to hold Generation Patterns fileLoc += rule.replace("/", "_") + "/" if (os.path.isdir(fileLoc) is not True): os.mkdir(fileLoc) # Prepare File Names for each Genereration's Pattern File fileNamePrefix = fileLoc + rule.replace("/", "_") + "_" # Loop and Save Patterns for i in range(int(timeElapsed) + 1): # Stop Loop if Universe is Empty if (g.empty()): break # Determine File Names fileNameRLE = fileNamePrefix + str(i) + ".rle" # Determine Previous File Names fileNamePrevRLE = fileNamePrefix + str(i - 1) + ".rle" g.save(fileNameRLE, "rle") # Compare Previous Generation to Determine Class I Systems if (i > 0 and compare_rle(fileNameRLE, fileNamePrevRLE)): break g.run(1) # Close
draw_line(x + barwd, 0, x + barwd, -barht, extrastate) if barht > 1: # fill bar with corresponding color x1 = x + 1 x2 = x + barwd - 1 for y in xrange(barht - 1): draw_line(x1, -(y + 1), x2, -(y + 1), state) if statecount[state] > 0: # show count on top of bar t, twd, tht = color_text(str(statecount[state]), extrastate) t.put(barwd * (state + 1) - barwd / 2 - twd / 2, -barht - tht - 3) # -------------------------------------------------------------------- if g.empty(): g.exit("There is no pattern.") if g.numstates() == 256: g.exit("No room for extra state.") # check that a layer is available for the histogram histname = "histogram" histlayer = -1 for i in xrange(g.numlayers()): if g.getname(i) == histname: histlayer = i break if histlayer == -1 and g.numlayers() == g.maxlayers(): g.exit("You need to delete a layer.") # use selection rect if it exists, otherwise use pattern bounds label = "Selection" r = rect(g.getselrect())
if not tile == []: # add a layer layername = "Topology_Search" poplayer = -1 for i in xrange(g.numlayers()): if g.getname(i) == layername: poplayer = i break if poplayer == -1 and g.numlayers() == g.maxlayers(): g.exit("You need to delete a layer.") if poplayer == -1: poplayer = g.addlayer() else: g.setlayer(poplayer) g.new(layername) if not g.empty(): g.select(g.getrect()) g.clear(0) rule = g.getrule().split(':')[0] rule0 = rule rule = rule.replace('/', '-') i = 0 while True: try: filename = g.getdir('rules') + 'topoS_%s_%i.csv' % (rule, i) myfile = open(filename, 'r') i = i + 1 continue except: