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 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 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 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)
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
x += inc y += inc # append padding int if necessary if (inc == 3) and (len(clist) & 1 == 0): clist.append(0) return pattern(clist) for i in range(step, maxnum + step, step): make_text(str(i)).put(boxwidth * (i - 1), 0) g.putcells(box, boxwidth * (i - 1), 0) boxsel = [boxwidth * (i - 1) + 1, 1, boxwidth - 2, boxwidth - 2] 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) # tile.append(g.getcells(g.getselrect())) if not tile == []:
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: patrlelist.append(patrle) patrles = '\n'.join(patrlelist)