def loadtopo(maxnum,step,boxwidth): global pboxlist tile=[] for i in range(step,maxnum+step,step): make_text(str(i)).put(boxwidth*(i-1),0) box.put(boxwidth*(i-1),0) boxsel=[boxwidth*(i-1)+1,1,38,38] g.select(boxsel) g.shrink() if g.getselrect()==boxsel: continue else: sel=g.getselrect() pbox=g.getselrect() clist=g.getcells(pbox) for i in range(int(len(clist)/3)): clist[3*i] = clist[3*i]-sel[0] clist[3*i+1] = clist[3*i+1]-sel[1] clist.insert(0,sel[2]) clist.insert(1,sel[3]) tile.append(clist) pboxlist.append(pbox) return tile
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 find_best_selection(): r = g.getrect() all = g.getcells(r) sep = 1 # - run the pattern for 4096 ticks, get the new settled pattern # - try XORing new pattern with original pattern for every possible offset up to 512 # - one of the offsets should give the lowest total population # (will probably decrease the population instead of increasing it, # unless what is being built is a prolific puffer or gun or some such) bestscore, bestsep = len(all), -1 # = population * 2 allplus4096 = g.evolve(all, 4096) g.addlayer() while sep <= 512: g.show("Finding stage spacing -- testing " + str(sep)) g.new("sep=" + str(sep)) g.putcells(all) g.putcells(allplus4096, sep, 0, 1, 0, 0, 1, "xor") score = int(g.getpop()) if bestscore > score: bestscore, bestsep = score, sep sep += 1 g.dellayer() sep = bestsep g.show("found separation: " + str(sep)) bestblockscore, bestoffset = -999999, -1 for offset in range(sep): g.select([r[0] - offset, r[1], sep, r[3]]) g.update() blockscore = 0 for blockx in range(r[0] - offset, r[0] + r[2], sep): g.select([blockx, r[1], sep, r[3]]) blockrect = g.getselrect() block = g.getcells(blockrect) if len( block ) == 0: # ran into empty block, this must not be the right separation g.exit("Invalid pattern format found at separation = " + str(sep) + ": selected block is empty.") g.shrink(1) shrunkblockrect = g.getselrect() leftdiff = shrunkblockrect[0] - blockrect[0] rightdiff = (blockrect[0] + blockrect[2]) - (shrunkblockrect[0] + shrunkblockrect[2]) blockscore += leftdiff + rightdiff if leftdiff < 10: blockscore -= (10 - leftdiff)**2 if rightdiff < 10: blockscore -= (10 - rightdiff)**2 if blockscore > bestblockscore: bestblockscore, bestoffset = blockscore, offset g.select([r[0] - bestoffset, r[1], r[2] + offset, r[3]]) return sep
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 lookforkeys(event, deltax, deltay): global oldcells, selrect, selpatt # look for keys used to flip/rotate selection if event == "key x none" or event == "key y none": # flip floating selection left-right or top-bottom if len(oldcells) > 0: g.clear(0) g.putcells(selpatt, deltax, deltay) if " x " in event: g.flip(0) else: g.flip(1) selpatt = g.transform(g.getcells(selrect), -deltax, -deltay) if len(oldcells) > 0: g.clear(0) g.putcells(oldcells) g.putcells(selpatt, deltax, deltay) g.update() return if event == "key > none" or event == "key < none": # rotate floating selection clockwise or anticlockwise; # because we use g.rotate below we have to use the exact same # calculation (see Selection::Rotate in wxselect.cpp) for rotrect: midx = selrect[0] + int((selrect[2]-1)/2) midy = selrect[1] + int((selrect[3]-1)/2) newleft = midx + selrect[1] - midy newtop = midy + selrect[0] - midx rotrect = [ newleft, newtop, selrect[3], selrect[2] ] if not rectingrid(rotrect): g.warn("Rotation is not allowed if selection would be outside grid.") return g.clear(0) if len(oldcells) > 0: g.putcells(oldcells) oldcells = g.join(oldcells, g.getcells(rotrect)) g.clear(0) g.select(rotrect) g.clear(0) g.select(selrect) g.putcells(selpatt, deltax, deltay) if " > " in event: g.rotate(0) else: g.rotate(1) selrect = g.getselrect() if selrect != rotrect: g.warn("Bug: selrect != rotrect") selpatt = g.transform(g.getcells(selrect), -deltax, -deltay) if len(oldcells) > 0: g.clear(0) g.putcells(oldcells) g.putcells(selpatt, deltax, deltay) g.update() return if event == "key h none": showhelp2() return g.doevent(event)
def popcount(sel=0): dict_lc = {'BDRainbow': [2, 4], 'BGRainbowR2': [2, 4]} live_cells = dict_lc[g.getrule().split(':')[0]] if not sel: clist = g.getcells(g.getrect()) else: clist = g.getcells(g.getselrect()) return sum(clist[2::3].count(x) for x in live_cells)
def loadtopo(): for i in range(step, max + step, step): make_text(str(i)).put(boxwidth * (i - 1), 0) box.put(boxwidth * (i - 1), 0) boxsel = [boxwidth * (i - 1) + 1, 1, 38, 38] g.select(boxsel) g.shrink() if g.getselrect() == boxsel: continue else: clist = g.getcells(g.getselrect()) sel = g.getselrect() for i in range(int(len(clist) / 3)): clist[3 * i] = clist[3 * i] - sel[0] clist[3 * i + 1] = clist[3 * i + 1] - sel[1] clist.insert(0, sel[2]) clist.insert(1, sel[3]) tile.append(clist) return tile
def popcount(sel=0): dict_lc = {'BDRainbow': [2, 4], 'BGRainbowR2': [2, 4]} rule = g.getrule().split(':')[0] try: live_cells = dict_lc[rule] except: live_cells = range(1, g.numstates()) if not sel: clist = g.getcells(g.getrect()) else: clist = g.getcells(g.getselrect()) return sum(clist[2::3].count(x) for x in live_cells)
def main(): # get selection and set to boundary bound = g.getselrect() if len( bound ) == 0: g.note( "No selection." ) g.exit() # get current Golly states left = bound[ 0 ] top = bound[ 1 ] width = bound[ 2 ] height = bound[ 3 ] for y in xrange( 0, height ): for x in xrange( 0, width ): state = g.getcell( left + x, top + y ) g.setcell( height - y - 600, x - 600, state )
def tileit(clist,tilewd): global inc,pbox cliplist=clist # g.select([boxsel[0]-20,boxsel[1]-20,20,20]) # g.clear(0) # make_text(str(posi)).put(boxsel[0]-20,boxsel[1]) pbox = rect( [0, 0] + cliplist[0 : 2] ) wd=tilewd*pbox.wd ht=tilewd*pbox.ht boxsel=[-int(wd/2),-int(wd/2),wd,ht] g.select(boxsel) selrect = rect( g.getselrect() ) inc=2 cliplist[0 : 2] = [] # remove wd,ht p = pattern( cliplist ) if len(cliplist) & 1 == 1: inc = 3 # multi-state? g.clear(inside) if len(cliplist) > 0: # tile selrect with p, clipping right & bottom edges if necessary y = selrect.top while y <= selrect.bottom: bottom = y + pbox.height - 1 x = selrect.left while x <= selrect.right: right = x + pbox.width - 1 if (right <= selrect.right) and (bottom <= selrect.bottom): p.put(x, y) else: clip_rb( p(x, y), selrect.right, selrect.bottom ).put() x += pbox.width y += pbox.height if not selrect.visible(): g.fitsel()
def get_bitmap(): selrect = golly.getselrect() if len(selrect) == 0: golly.exit("There is no selection, aborting.") #Get bitmap size w, h = selrect[2:] #Adjust width, so it's in the form of 4m, m>1 w = (w + 3) // 4 * 4 w = max(8, w) #Initialize empty bitmap row = w * ['0'] bm = [row[:] for i in xrange(h)] #Populate bitmap with cell data u, v = selrect[:2] cells = golly.getcells(selrect) cellsxy = [(cells[i] - u, cells[i+1] - v) for i in xrange(0, len(cells), 2)] for x, y in cellsxy: bm[y][x] = '1' #Convert to CSV string return ','.join([''.join(row) for row in bm])
def get_bitmap(): ''' Get current selection & turn it into a bitmap. ''' selrect = golly.getselrect() if len(selrect) == 0: golly.exit("There is no selection, aborting.") #Get bitmap size w, h = selrect[2:] #Adjust width, so it's in the form of 4m, m>1 w = (w + 3) // 4 * 4 w = max(8, w) #Initialize empty bitmap row = w * [0] bm = [row[:] for i in xrange(h)] #Populate bitmap with cell data u, v = selrect[:2] cells = golly.getcells(selrect) cellsxy = [(cells[i] - u, cells[i + 1] - v) for i in xrange(0, len(cells), 2)] for x, y in cellsxy: bm[y][x] = 1 return bm
def getoctohash(clist): ptr = 0 g.new("Octotest" + str(count)) for orientation in [[1, 0, 0, 1], [0, -1, 1, 0], [-1, 0, 0, -1], [0, 1, -1, 0], [-1, 0, 0, 1], [1, 0, 0, -1], [0, 1, 1, 0], [0, -1, -1, 0]]: g.putcells(clist, ptr * 2048, 0, *orientation) ptr += 1 for j in range(8): g.select([2048 * j - 1024, -1024, 2048, 2048]) g.shrink() r = g.getselrect() if r == []: r = [0, 0, 1, 1] pat = g.getcells(r) deltax, deltay = 0, 0 if pat != []: deltax, deltay = -pat[0], -pat[1] if j == 0: minstr = str(g.transform(pat, deltax, deltay)) else: strpat = str(g.transform(pat, deltax, deltay)) if strpat < minstr: minstr = strpat return " " + get9char(minstr)
r = g.getselrect() if r == []: r = [0, 0, 1, 1] pat = g.getcells(r) deltax, deltay = 0, 0 if pat != []: deltax, deltay = -pat[0], -pat[1] if j == 0: minstr = str(g.transform(pat, deltax, deltay)) else: strpat = str(g.transform(pat, deltax, deltay)) if strpat < minstr: minstr = strpat return " " + get9char(minstr) r = g.getselrect() if r == []: g.exit("No selection. Select something to find by fingerprint.") g.fitsel() r = g.getselrect() if r == []: g.exit("No selection. Select something to find by fingerprint.") count = NUMLINES outptrx, outptry, matches = 0, 0, 0 pat = g.getcells(r) g.addlayer() # do tests in a new layer, then put results there hash = getoctohash(pat) g.new("Output") if pat != []:
import os.path # default base path as the Desktop, change it if needed default_path = os.path.expanduser('~/Desktop') # default name is the current pattern name without extension pattern_name = g.getname().split('.')[0] # getting an output path export_path = g.savedialog('Choose the directory and name', 'All files (*)|*', default_path, pattern_name) if export_path == "": export_path = default_path # number of generations num_generations = 10 # has a selection been made? selected = 1 if len(g.getselrect()) > 0 else 0 for i in range(num_generations): # advance by one generation (checking if something is selected) if selected == 1: g.advance(0, 1) else: g.run(1) # export to a new file file_path = '%s-%d.rle' % (export_path, i) g.show(file_path) g.save(file_path, 'rle')
) objs = [] add_it(objs, '3o$2bo$bo!', 1, -1) add_it(objs, '3o$o$bo!', -1, -1) add_it(objs, 'bo$2bo$3o!', 1, 1) add_it(objs, 'bo$o$3o!', -1, 1) add_it(objs, '3o$o2bo$o$o$bobo!', 0, -2) add_it(objs, 'bobo$o$o$o2bo$3o!', 0, 2) add_it(objs, 'o2bo$4bo$o3bo$b4o!', 2, 0) add_it(objs, 'bo2bo$o$o3bo$4o!', -2, 0) site_step = 0 rect = g.getselrect() if not rect: site_step = find_best_selection() rect = g.getselrect() if not rect: g.exit( "No selection. Could not locate a valid separation and offset automatically." ) g.fitsel() g.update() if site_step == 0: site_step = int(g.getstring("Enter step between construction sites")) delay2 = int( g.getstring( "Enter delay for 2nd construction (only relevant for spaceships)",
dict_lc={'BDRainbow':[2,4],'BGRainbowR2':[2,4]} live_cells=dict_lc[g.getrule().split(':')[0]] if sel: clist=g.getcells(g.getselrect()) else: clist=g.getcells(g.getrect()) return sum(clist[2::3].count(x) for x in live_cells) dict_lc={'BDRainbow':[2,4],'BGRainbowR2':[2,4]} input=(g.getstring('How many steps?/similarity distance?','2000/1')) numsteps=int(input.split('/')[0]) dmax=int(input.split('/')[1]) sel=(g.getselrect()!=[]) rule=g.getrule().split(':')[0] if rule in dict_lc: popfunc=lambda:popcount(sel) else: popfunc=lambda:int(g.getpop()) poplist=[] dpoplist=[] hashlist=[int(g.hash(g.getrect()))] popold=int(popfunc()) poplist.append(popold)
if selrect[1] < gridt: selrect[1] = gridt y = selrect[1] + yoffset elif selrect[1] + selrect[3] - 1 > gridb: selrect[1] = gridb + 1 - selrect[3] y = selrect[1] + yoffset g.select(selrect) oldcells = g.getcells(selrect) g.putcells(selpatt, x - firstx, y - firsty) oldmouse = mousepos g.update() # ------------------------------------------------------------------------------ selrect = g.getselrect() if len(selrect) == 0: g.exit("There is no selection.") selpatt = g.getcells(selrect) # remember initial selection in case user aborts script firstrect = g.getselrect() firstpatt = g.getcells(selrect) g.show("Click anywhere in selection, move mouse and click again..." + helpmsg) oldcursor = g.getcursor() g.setcursor("Move") oldcells = [] try: aborted = True moveselection()
def main(step=1, start=0): global bound, expand, duration # get selection and set to boundary bound = g.getselrect() if duration == None: duration = int(g.getgen()) if isReset: g.reset() if len(bound) == 0: g.note("No selection.") g.exit() # get current Golly states bound[0] -= expand bound[1] -= expand bound[2] += expand * 2 bound[3] += expand * 2 left = bound[0] top = bound[1] width = bound[2] height = bound[3] palette = getPalette() cells = g.getcells(bound) isMultiStates = len(cells) % 2 == 1 cellW = 3 if isMultiStates else 2 # create image and destination directory dstDir = "%s/%s" % (exportDir, name) if not os.path.exists(dstDir): os.makedirs(dstDir) # else: # g.note( "destination folder already exists" ) # g.exit() # log( cells ) for i in xrange(duration): g.show("Processing... %d / %d" % (i + 1, duration)) g.run(1) g.update() cells = g.getcells(bound) # create image img = Image.new("RGB", (width, height)) cellLen = int(floor(len(cells) / cellW) * cellW) for i in xrange(0, cellLen, cellW): x = cells[i] y = cells[i + 1] state = cells[i + 2] if isMultiStates else 1 img.putpixel((x - left, y - top), palette[state]) # save gen = int(g.getgen()) img.save("%s/%s_%08d.png" % (dstDir, name, gen))
# Tile current selection with pattern inside selection. # Author: Andrew Trevorrow ([email protected]), March 2006. # Updated to use exit command, Nov 2006. # Updated to handle multi-state patterns, Aug 2008. from glife import * import golly as g selrect = rect( g.getselrect() ) if selrect.empty: g.exit("There is no selection.") selpatt = pattern( g.getcells(g.getselrect()) ) if len(selpatt) == 0: g.exit("No pattern in selection.") # determine if selpatt is one-state or multi-state inc = 2 if len(selpatt) & 1 == 1: inc = 3 # ------------------------------------------------------------------------------ def clip_left (patt, left): clist = list(patt) # remove padding int if present if (inc == 3) and (len(clist) % 3 == 1): clist.pop() x = 0 while x < len(clist): if clist[x] < left: clist[x : x+inc] = [] # remove cell from list else:
def fit_if_not_visible(): # fit pattern in viewport if not empty and not completely visible r = rect(g.getselrect()) if (not r.empty) and (not r.visible()): g.fit()
def burp(): test_signal=pattern(""" 40bo$41bo$39b3o17$40bo4bo4bo4bo4bo$41bo4bo4bo4bo4bo$39b3o2b3o2b3o2b3o 2b3o3$40bo4bo4bo4bo4bo$41bo4bo4bo4bo4bo$39b3o2b3o2b3o2b3o2b3o3$40bo4bo 4bo4bo4bo$41bo4bo4bo4bo4bo$39b3o2b3o2b3o2b3o2b3o3$40bo4bo4bo4bo4bo$41b o4bo4bo4bo4bo$39b3o2b3o2b3o2b3o2b3o3$bo38bo4bo4bo4bo4bo18bo$2bo38bo4bo 4bo4bo4bo18bo$3o36b3o2b3o2b3o2b3o2b3o16b3o37$40bo$41bo$39b3o!""") prepare_burp() ticks=0 tickstep=5 last_signal=-99999 viewport_speed=16 sel_speed=0.0 delta_sel=0.0 delay=-1.0 run_flag=False ch="" selx=600.0 sely=365.0 place_signal=3 helpstring="""Use ENTER and SPACE to run or halt the pattern; use + and - to change the step size or delay value; use arrow keys and mouse tools to pan and zoom in any pane; T toggles between a tiled view and a single-pane view; S creates another signal fleet near the detection mechanism; R resets the Heisenburp device to its initial state; Q quits out of the script and restores original settings.""" instr="Press H for help. " g.show(instr + str(tickstep)) g.select([selx,sely,50,50]) # keyboard handling while ch<>"q": if place_signal>0: if ticks-last_signal>1846: test_signal.put(-150,60) last_signal=ticks place_signal-=1 if place_signal>0 and run_flag==True: show_status_text("Next signal placement in " \ + str(1847 - ticks + last_signal) + " ticks. " + instr, delay, tickstep) else: show_status_text(instr,delay,tickstep) event = g.getevent() if event.startswith("key"): evt, ch, mods = event.split() else: ch = "" if ch=="r": prepare_burp() ticks=0 last_signal=-99999 viewport_speed=16 sel_speed=0 run_flag=False selx=600.0 sely=365.0 place_signal=3 g.select([selx,sely,50,50]) elif ch=="h": g.note(helpstring) elif ch=="t": g.setoption("tilelayers",1-g.getoption("tilelayers")) elif ch=="=" or ch=="+": if delay>.01: delay/=2 elif delay==.01: delay=-1 else: if tickstep==1: tickstep=3 elif tickstep<250: tickstep=(tickstep-1)*2+1 elif ch=="-" or ch=="_": if delay==-1: if tickstep==1: delay=.01 else: if tickstep==3: tickstep=1 else: tickstep=(tickstep-1)/2+1 else: if delay<1: delay*=2 elif ch=="space": run_flag=False elif ch=="return": run_flag=not run_flag elif ch=="s": place_signal+=1 else: # just pass any other keyboard/mouse event through to Golly g.doevent(event) # generation and selection speed handling if ch=="space" or run_flag==True: g.run(tickstep) currlayer = g.getlayer() if currlayer != 4: # user has switched layer so temporarily change it back # so we only change location of bottom right layer g.check(False) g.setlayer(4) x, y = getposint() oldticks=ticks ticks+=tickstep delta_view=int(ticks/viewport_speed) - int(oldticks/viewport_speed) if delta_view <> 0: # assumes diagonal motion for now setposint(x + delta_view, y + delta_view) sel = g.getselrect() if len(sel)<>0: x, y, w, h = sel if int(selx)<>x: # user changed selection # prepare to move new selection instead (!?!) # -- use floating-point selx, sely to account for fractional speeds selx=x sely=y else: selx+=sel_speed*tickstep sely+=sel_speed*tickstep g.select([selx, sely, w, h]) else: g.select([selx, sely, 50, 50]) if currlayer != 4: g.setlayer(currlayer) g.check(True) # change viewport speed at appropriate times to follow the action if oldticks<4570 and ticks>=4570: sel_speed=.666667 # one-time correction to catch up with the signal at high sim speeds g.select([600+(ticks-4570)*1.5, 365+(ticks-4570)*1.5, w, h]) if selx>2125: sel_speed=0 g.select([2125, sely+2125-selx, w, h]) if oldticks<4750 and ticks>=4750: viewport_speed=1.5 if oldticks<6125 and ticks>=6125: viewport_speed=16 if oldticks>=11995: viewport_speed=99999.9 # stop automatically after the last signal passes through the device if oldticks - last_signal<8705 and ticks - last_signal>=8705: run_flag=False if run_flag==True and delay>0: sleep(delay) g.update()
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)
# Metafier V2: writes directly to output.mc # Uses numpy and memoization to speed up a crap ton & compress data a bit # ===REQUIRES metatemplate11.mc=== import golly as g import numpy as np from shutil import copyfile #Get the selection selection = g.getselrect() if not selection: g.exit("No selection.") #Get the cells in the selection cells = g.getcells(selection) if not cells: g.exit("No pattern in selection") if len(cells) % 3: cells = cells[:-1] selw = selection[2] selh = selection[3] patternsize = 1 << int(np.ceil(np.log2(selh | selw))) metapattern = np.zeros((patternsize, patternsize)) #Pseudo-convolution, to detect diagonal neighbors # +1 +0 +2 # +0 *16 +0 # +4 +0 +8 for cell in np.reshape(cells, (-1, 3)): selx = cell[0] - selection[0] sely = cell[1] - selection[1]
cells_dict = dict.fromkeys(zip(cells[::2], cells[1::2])) for x, y in zip(cells[::2], cells[1::2]): glider_dict = dict.fromkeys([(x, y), (x, y + 2), (x + 1, y + 1), (x + 1, y + 2), (x + 2, y + 1)]) spot = product(range(x - 1, x + 4), range(y - 1, y + 4)) if all([((i, j) in cells_dict) is ((i, j) in glider_dict) for i, j in spot]): gliders.append((x, y)) return gliders def compute_invariants(glider_pair): (x1, y1, t1), (x2, y2, t2) = glider_pair dx = x2 - x1 dy = y2 - y1 dt = t2 - t1 hd = dx - dy tr = float(hd) / 2 * 47 return [abs(dt - 4 * dy - tr), abs(4 * dx - dt - tr)] invariants = get_invariants(g.getcells(g.getselrect())) g.show(' '.join([str(item) for item in invariants]))
import golly as g catdir = '/home/scorbie/Apps/ptbtest/cats' r = g.getselrect() if len(r)==0: r=g.getrect() if len(r)==0: g.exit('No pattern, nothing to do.') sel = g.getcells(r) if len(sel)==0: g.exit('Nothing in selection.') if g.getrule() != 'LifeHistory': g.exit('The rule should be in LifeHistory.') # Get catalyst in various positions if g.getselrect() != []: g.shrink() pattern = g.getcells(r) patrlelist = [] translist =[(1,0,0,1), (1,0,0,-1), (-1,0,0,1), (-1,0,0,-1), (0,1,1,0), (0,-1,1,0), (0,1,-1,0), (0,-1,-1,0)] # Get unique transformed patterns for trans in translist: g.new('') g.putcells(g.transform(pattern, 0, 0, *trans)) g.select(g.getrect()) g.copy() patrle = ''.join(g.getclipstr().split('\n')[1:]) if patrle not in patrlelist:
newlist.append(temp[0] + x) newlist.append(temp[1] + y) newlist.append(temp[2]) newlist.append(0) return newlist input = g.getstring( 'what cell state to screen for/ \n \ treat selection as torus?/ \n \ how many repeating units?', '%s/%s/%s' % (g.getoption("drawingstate"), '1', '2')) state = int(input.split('/')[0]) torus = int(input.split('/')[1]) n = int(input.split('/')[2]) pbox = g.getselrect() clist = getquad(pbox, n=n) g.setclipstr(str(clist)) parsed_clist = parse_list(clist) g.show('clist %i %s, parsed_clist %i %s' % (len(clist), str(clist), len(parsed_clist), str(parsed_clist))) fclist = full_clist(parsed_clist, pbox) adjmat = adjacencymatrix(parsed_clist, pbox, torus, n=n) s = mathematica(str(adjmat)) g.setclipstr(s)
# Make a pattern from states 1 and 0, select it and then # run this script to make a Codd CA pattern that will then # construct the pattern. The constructor will then attempt # to inject sheathing and triggering signals to a point one # up from the pattern's bottom-left corner. # # See example: Patterns/Codd/golly-constructor.rle # # Tim Hutton <*****@*****.**> from glife import rect from time import time import golly as g r = rect( g.getselrect() ) if r.empty: g.exit("There is no selection.") oldsecs = time() maxstate = g.numstates() - 1 # these are the commands: extend = '70116011' extend_left = '4011401150116011' extend_right = '5011501140116011' retract = '4011501160116011' retract_left = '5011601160116011' retract_right = '4011601160116011' mark = '701160114011501170116011' erase = '601170114011501160116011' sense = '70117011' cap = '40116011'
# A randomized rectangle filler for use with Golly. # Author: Nathaniel Johnston ([email protected]), June 2009. # # Even though Golly comes built-in with the golly.randfill() function, there # does not seem to be a way to seed that function, so you get the same sequence # of random rectangles every time you reload Golly. This script eliminates that # problem. import golly as g import random g.note(str(g.getcells(g.getselrect())))
return [ item for item in invariants if item not in seen and not seen.add(item) ] def find_all_gliders(cells): gliders = [] cells_dict = dict.fromkeys(zip(cells[::2], cells[1::2])) for x, y in zip(cells[::2], cells[1::2]): glider_dict = dict.fromkeys([(x, y), (x, y+2), (x+1, y+1), (x+1, y+2), (x+2, y+1)]) spot = product(range(x-1, x+4), range(y-1, y+4)) if all([ ((i, j) in cells_dict) is ((i, j) in glider_dict) for i, j in spot ]): gliders.append( (x, y) ) return gliders def compute_invariants(glider_pair): (x1, y1, t1), (x2, y2, t2) = glider_pair dx = x2 - x1 dy = y2 - y1 dt = t2 - t1 hd = dx - dy tr = float(hd) / 2 * 47 return [abs(dt - 4 * dy - tr), abs(4 * dx - dt - tr)] invariants = get_invariants(g.getcells(g.getselrect())) g.show(' '.join([str(item) for item in invariants]))
def oscillating(): # return True if the pattern is empty, stable or oscillating # first get current pattern's bounding box csel = g.getselrect() g.shrink() prect = g.getselrect() g.select(csel) pbox = rect(prect) if pbox.empty: g.show("The pattern is empty.") return True # get current pattern and create hash of "normalized" version -- ie. shift # its top left corner to 0,0 -- so we can detect spaceships and knightships ## currpatt = pattern( g.getcells(prect) ) ## h = hash( tuple( currpatt(-pbox.left, -pbox.top) ) ) # use Golly's hash command (3 times faster than above code) h = g.hash(prect) # check if outer-totalistic rule has B0 but not S8 rule = g.getrule().split(":")[0] hasB0notS8 = rule.startswith("B0") and (rule.find("/") > 1) and not rule.endswith("8") # determine where to insert h into hashlist pos = 0 listlen = len(hashlist) while pos < listlen: if h > hashlist[pos]: pos += 1 elif h < hashlist[pos]: # shorten lists and append info below del hashlist[pos:listlen] del genlist[pos:listlen] del poplist[pos:listlen] del boxlist[pos:listlen] break else: # h == hashlist[pos] so pattern is probably oscillating, but just in # case this is a hash collision we also compare pop count and box size if (pbox.wd == boxlist[pos].wd) and \ (pbox.ht == boxlist[pos].ht): # (int(g.getpop()) == poplist[pos]) period = int(g.getgen()) - genlist[pos] if hasB0notS8 and (period % 2 > 0) and (pbox == boxlist[pos]): # ignore this hash value because B0-and-not-S8 rules are # emulated by using different rules for odd and even gens, # so it's possible to have identical patterns at gen G and # gen G+p if p is odd return False if period == 1: if pbox == boxlist[pos]: g.show("The pattern is stable.") else: show_spaceship_speed(1, 0, 0) elif pbox == boxlist[pos]: g.show("Oscillator detected (period = " + str(period) + ")") else: deltax = abs(boxlist[pos].x - pbox.x) deltay = abs(boxlist[pos].y - pbox.y) show_spaceship_speed(period, deltax, deltay) return True else: # look at next matching hash value or insert if no more pos += 1 # store hash/gen/pop/box info at same position in various lists hashlist.insert(pos, h) genlist.insert(pos, int(g.getgen())) poplist.insert(pos, int(g.getpop())) boxlist.insert(pos, pbox) return False
from glife import validint, inside from string import lower import golly as g import math rules = ("JvN29", "Nobili32", "Hutton32") rule = g.getrule () if rule not in rules: g.exit ("Invalid rule: " + rule + " (must be " + rules + ")") rect = g.getselrect () if len (rect) == 0: g.exit ("There is no selection.") answer = g.getstring("Enter direction to rotate in\n" + "(valid rotations are cw and ccw, default is cw):", "cw", "Rotate selection") if answer != "cw" and answer != "ccw": g.exit ("Unknown direction: " + answer + " (must be cw/ccw)") cells = g.getcells (rect) jvn_rotate = (( 9, 12, 11, 10), (13, 16, 15, 14), (17, 20, 19, 18), (21, 24, 23, 22)) def rotated (rotations, direction, state):
# Calculates the density of live cells in the current pattern. # Author: Andrew Trevorrow ([email protected]), March 2006. # Updated to use exit command, Nov 2006. import golly as g from glife import * from utils import * def popcount(sel=0): dict_lc = {'BDRainbow': [2, 4], 'BGRainbowR2': [2, 4]} live_cells = dict_lc[g.getrule().split(':')[0]] if not sel: clist = g.getcells(g.getrect()) else: clist = g.getcells(g.getselrect()) return sum(clist[2::3].count(x) for x in live_cells) pop = popcount(sel=1) medium = int(len(g.getcells(g.getselrect())) / 3) density = float(pop) / float(medium) * 100 g.setclipstr(str(density)) g.show('density=%i/100,pop=%i,medium=%i' % (density, pop, medium))
# Fill clicked region with current drawing state. # Author: Andrew Trevorrow ([email protected]), Jan 2011. import golly as g from time import time def fill(rectcoords): newstate = g.getoption("drawingstate") for i in range(rectcoords[0],rectcoords[0]+rectcoords[2]): for j in range(rectcoords[1],rectcoords[1]+rectcoords[3]): g.setcell(i, j, newstate) try: sel=g.getselrect() fill(sel) except: g.show('no selection')
# should be deleted so the script can re-generate them. # # 3 July 2007: added code to avoid errors in rules like Seeds, # where the Golly canonical form of the rule doesn't include a '/' # # Modified by Andrew Trevorrow, 20 July 2006 (faster, simpler and # doesn't change the current clipboard). # # Modified by Andrew Trevorrow, 5 October 2007 (metafied pattern is # created in a separate layer so we don't clobber the selection). import os import golly as g from glife import * selrect = g.getselrect() if len(selrect) == 0: g.exit("There is no selection.") # check that a layer is available for the metafied pattern; # if metafied layer already exists then we'll use that layername = "metafied" metalayer = -1 for i in xrange(g.numlayers()): if g.getname(i) == layername: metalayer = i break if metalayer < 0 and g.numlayers() == g.maxlayers(): g.exit("You need to delete a layer.") # note that getrule returns canonical rule string rulestr = g.getrule().split(":")[0]
def boxdm(orientation): if not g.empty(): shrink() return g.getselrect()[orientation] else: return 0
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 r.empty: label = "Pattern" r = rect(g.getrect()) # count all cell states in r g.show("Counting cell states...") counted = 0 totalcells = r.wd * r.ht statecount = [0] * g.numstates() oldsecs = time() for row in xrange(r.top, r.top + r.height): for col in xrange(r.left, r.left + r.width): counted += 1 statecount[g.getcell(col, row)] += 1 newsecs = time()
def area(): if not g.empty(): shrink() return g.getselrect()[2] * g.getselrect()[3] else: return 0