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 PrepareList(cells): g.new("") g.putcells(cells) cells = g.getcells(g.getrect()) g.new("") g.putcells(cells, -cells[0], -cells[1]) c = g.getcells(g.getrect()) result = [] for i in xrange(0, len(c), 2): x = c[i] y = c[i + 1] for dx in xrange(-1, 2): for dy in xrange(-1, 2): val = g.getcell(x + dx, y + dy) if (x + dx, y + dy, val) in result: continue result.append((x + dx, y + dy, val)) random.shuffle(result) return result
def scanX(y, lines, stage, vars): if stage == 0: if g.getcell(0, y) == 0: if len(g.getcells([0, y, 10, 1])) != 0: stage = 2 else: return 0 else: stage = 1 if stage == 1: if g.getcell(0, y) == 0: stage = 2 else: vars[g.getcell(0, y)] = [g.getcell(10, y)] dx = 20 while g.getcell(dx, y) != 0: vars[g.getcell(0, y)].append(g.getcell(dx, y)) dx += 10 return stage stage = 2 dx = 0 while len(g.getcells([dx, y, 10, 10])) != 0: dx += 10 for i in range(0, dx, 10): scanXY(i, y, i == dx - 10, lines) return stage
def PrepareList(cells): g.new("") g.putcells(cells) cells = g.getcells(g.getrect()) g.new("") g.putcells(cells, -cells[0], -cells[1]) c = g.getcells(g.getrect()) result = [] for i in xrange(0, len(c), 2): x = c[i] y = c[i + 1] for dx in xrange(-1,2): for dy in xrange(-1, 2): val = g.getcell(x + dx, y + dy) if (x + dx, y + dy, val) in result: continue result.append((x + dx, y + dy, val)) random.shuffle(result) return result
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 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 HasEdgeShooter(minx): rect = g.getrect() if len(rect) == 0: return -1 y = rect[1] + rect[3] if y < 100: return -1 if rect[2] > 120: return -1 g.run(4) rect = g.getrect() if y + 2 == rect[1] + rect[3]: maxX = -10000 minL = 10000 minY = 10000 for i in xrange(0, 4): g.run(1) rect = g.getrect() curCells = g.getcells([rect[0], rect[1] + rect[3] - 10, rect[2], 11]) curx, cury = FindRightMost(curCells) curL = len(curCells) if curL <= minL: minL = curL if curx > maxX or (curx == maxX and cury < minY): maxX = curx minY = cury parity = (int(g.getgen()) % 4) + ((cury - curx + 1000000)% 2) * 4 if curL == 22: parity += 8 if curL == 26: parity += 16 if minx - 2 > maxX: cells = g.getcells([-100, -100, 200, 200]) for i in xrange(1, len(cells), 2): if cells[i - 1] - 2 < maxX: return -1 return parity return -1
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 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 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 recipe(): res = "" i = 0 prev = 0 while True: i += 1 y = int(128 * i) + 1 cells = g.getcells([-1500+y, y, 2 * 1500, 3]) if len(cells) == 0: break x = cells[0] y = cells[1] cur = x - y if g.getcell(x + 2, y) == 0: res += "O" + str(cur) + " " else: res += "E" + str(cur - 1) + " " prev = cur return res
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 UpdateMove(d, w, h, x0, y0, p, t): under = d[0] obj = d[1] x = d[2] y = d[3] if under != -1: ClearRect(x - w, y - h, 2 * w + 1, 2 * h + 1) g.putcells(under) val = g.getxy() if val == "": return x1 = int(val.split()[0]) y1 = y0 + GetDirection(t) * (x1 - x0) d[0] = g.getcells([x1 - w, y1 - h, 2 * w + 1, 2 * h + 1]) #ClearRect(x1 - w, y1 - h, 2 * w + 1, 2 * h + 1) g.putcells(g.evolve(obj, p + GetEvolveDirection(t) * ((4 * (x1 - x0)) % p)), x1, y1) g.update() d[2] = x1 d[3] = y1
def GunArea(cells, curGunPeriod): maxBox = [] minpop = -100000 for i in xrange(0, curGunPeriod, 4): g.new(str(i)) g.putcells(g.evolve(cells, i)) g.setbase(8) g.setstep(3) g.step() g.step() edgeGlider = EdgeGlider() while PerformDelete(edgeGlider, curGunPeriod): edgeGlider = DevolveGlider(edgeGlider, curGunPeriod) for j in xrange(0, 4): if g.getpop() > minpop: maxpop = g.getpop() maxpopgun = g.getcells(g.getrect()) maxBox = AppendBox(maxBox, g.getrect()) g.run(1) return [BoxValue(maxBox), maxpopgun, maxBox]
def EvolveRecipes(recipes): newrecipes = [] cnt = 0 for recipe in recipes: cnt += 1 if cnt % 100 == 0: g.show(str(cnt) + "/" + str(len(recipes))) minx = EvolveRecipe(recipe) cells = g.getcells(g.getrect()) answer = FindAllHs(cells, minx) for h in answer[0]: i = h[0] x1 = h[1] y1 = h[2] xySL = h[3] res = copy(recipe) res.append(i) result.append([res, x1, y1, xySL]) for h in answer[1]: res = copy(recipe) res.append(h) newrecipes.append(res) return newrecipes
def main(): g.setstep(0) g.setalgo('QuickLife') velocity = g.getstring('Please specify velocity', '(2,1)c/6') a, b, p = parse_velocity(velocity) params = partial_derivatives(a, b, p) dvdx = params['dvdx'] dudx = params['dudx'] dvdy = params['dvdy'] dudy = params['dudy'] dvdt = params['dvdt'] dudt = params['dudt'] cells = [] for t in xrange(p): things = g.getcells(g.getrect()) things = zip(things[::2], things[1::2]) cells += [(dudx * x + dudy * y + dudt * t, dvdx * x + dvdy * y + dvdt * t) for (x, y) in things] g.step() g.setlayer(g.addlayer()) g.putcells([x for y in cells for x in y])
def FindActive(): rect = g.getrect() cells = g.getcells([rect[0], rect[1], rect[2], 1]) return [cells[0], cells[1]]
def matchpattern (patt, xsub, ysub, txsize, tysize, rectlist): clist = g.getcells (rectlist) lmr = [] while len (clist) > 0: testrect = [clist[0] - xsub, clist[1] - ysub, txsize, tysize] testpatt = g.getcells (testrect) if len (patt) == len (testpatt): z = 0 while z < len (testpatt): testpatt [z] = testpatt [z] - testrect [0] testpatt [z+1] = testpatt [z+1] - testrect [1] z = z + 2 if patt == testpatt: lmr = lmr + [testrect] clist = clist [2:] return (lmr)
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 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 GunArea(cells, curGunPeriod): maxBox = [10000, 10000, -1000, -1000] for i in xrange(0, curGunPeriod, 4): g.new(str(i)) g.putcells(g.evolve(cells, i)) g.setbase(8) g.setstep(3) g.step() g.step() g.step() g.step() edgeGlider = EdgeGlider() while PerformDelete(edgeGlider, curGunPeriod): edgeGlider = DevolveGlider(edgeGlider, curGunPeriod) for j in xrange(0, 4): maxBox = AppendBox(maxBox, g.getrect()) g.run(1) if i == 0: somegun = g.getcells(g.getrect()) return [BoxValue(maxBox), somegun, maxBox]
def threes_and_fours(i): bounding_box = g.getrect() celllist = g.getcells(bounding_box) while (len(celllist) % 3): celllist = celllist[:-1] celllist = map(tuple, zip(celllist[0::3], celllist[1::3], celllist[2::3])) return {(x, y, i): c for (x, y, c) in celllist if c in [3, 4]}
def recipe(dx): res = "" for i in range(500): x = int(i * 7.5) if len(g.getcells([dx + x + 5, x, 3, 3])) == 0: res += "0" else: res += "1" return res.strip("0")
def PeriodCalculator(): g.setbase(8) g.setstep(3) g.step() g.step() cells = g.getrect() rect = g.getrect() cells = g.getcells(rect) for i in xrange(0, 10000): g.run(1) if str(g.getcells(rect)) == str(cells): #g.show(str(i + 1)) #g.reset return i + 1 return -1
def add_string(): cells = g.getcells(g.getrect()) n = len(cells) result = "" for i in range(0, n, 2): result += "[%d, %d, %d]" % (cells[i], cells[i + 1], int(g.getgen())) if i < n - 2: result += "," return (result, n / 2)
def PerformDelete(glider, gunPeriod): initCells = g.getcells(g.getrect()) for j in xrange(0, len(glider), 2): if g.getcell(glider[j], glider[j + 1]) != 1: return False Erase(glider) rect = g.getrect() cells = g.getcells(rect) g.run(gunPeriod) if str(g.getcells(rect)) == str(cells): g.new("") g.putcells(cells) return True else: g.new("") g.putcells(initCells) return False
def getquad(pbox, n=2): newlist = [] clist = g.getcells(pbox) for i in range(len(clist[0::3])): if 3 * i + 3 <= len(clist): temp = clist[3 * i:3 * i + 3] for x in [pbox[2] * i for i in range(n)]: for y in [pbox[3] * i for i in range(n)]: newlist.append(temp[0] + x) newlist.append(temp[1] + y) newlist.append(temp[2]) newlist.append(0) return newlist
def GunsReader(): result = [] for i in xrange(0, 10000): cells = g.getcells([0, i * 650, 500, 550]) if len(cells) == 0: return result g.select([-200, i * 650 - 10, 800, 550]) g.clear(0) result.append(cells)
def find_and_remove_all(): cells = g.getcells(g.getrect()) l = len(cells) res = [] for i in range(1, l, 2): x = cells[i - 1] y = cells[i] for k in range(-1, 2): for l in range(-1, 2): idx = is_there_glider(x + k, y + l) if idx >= 0: res.append((x + k, y + l, idx)) return res
def CalculateLane(cells): g.new("") g.putcells(cells) cells = g.getcells(g.getrect()) g.new("") g.putcells(cells, -cells[0], -cells[1]) minx = 1000 maxx = -1000 for i in xrange(0, 4): rect = g.getrect() minx = min(minx, rect[0]) maxx = max(maxx, rect[0] + rect[2]) g.run(1) return (minx, maxx)
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 add_shooter(cost, inserter_cells, left_g, right_g=[], flip=True): global shoot_defs g.new('') g.putcells(inserter_cells) g.putcells(left_g) g.putcells(right_g) g.run(2048) reaction_cells = g.getcells([-150,-150,300,300]) g.run(512) if not all(g.getcell(x, y) for x, y in gld_pairs): g.fit() g.update() assert(False) stable_cells = set(zip(reaction_cells[::2], reaction_cells[1::2])) for _ in range(4): g.run(1) for i in range(0, len(reaction_cells), 2): tup = reaction_cells[i], reaction_cells[i+1] if tup in stable_cells and not g.getcell(*tup): stable_cells.remove(tup) stable_cells2 = [] for x, y in stable_cells: stable_cells2.append(x) stable_cells2.append(y) stable_cells = stable_cells2 tup = (cost, inserter_cells, left_g, right_g, reaction_cells, stable_cells) shoot_defs.append(tup) if flip: shoot_defs.append((cost, f(inserter_cells), f(right_g), f(left_g), f(reaction_cells), f(stable_cells)))
def __init__(self, path = None, SLpaths = None, SLExpected = None): self.blockX = 0 self.blockY = 0 self.sequence = [] self.recipe = [] self.block0 = [0,0] self.block1 = [0,0] self.splitterData1 = [[-4, -14],[-8,7],[12,5], g.parse("5$22b2o$22b2o$2b2o$2b2o!", -10, 0)] self.splitterData2 = [[5, 15],[7,-8],[5,12], g.parse("2$7b2o$7b2o19$5b2o$5b2o!", 0, -10)] self.recipeIdxList = [] self.lastGotoIdx = -1 self.SLsMoveTable = [] self.SLsExpected = SLExpected self.init = g.getcells(g.getrect()) if path != None: self.moveTable = self.LoadMoveTable(path, True) if SLpaths != None: for pt in SLpaths: self.SLsMoveTable.append(self.LoadMoveTable(pt, False))
def canon5Sship(ship, maxgen=2000): minpop, rulestr, dx, dy, period, shiprle = ship shipPatt = g.parse(shiprle) # Transform ship to canonical direction if abs(dx) >= abs(dy): a, b, c, d = sign(dx), 0, 0, sign(dy) else: a, b, c, d = 0, sign(dy), sign(dx), 0 dy, dx = minmaxofabs((dx, dy)) shipPatt = g.transform(shipPatt, 0, 0, a, b, c, d) # Clear the layer and place the ship r = g.getrect() if r: g.select(r) g.clear(0) g.putcells(shipPatt) shiprle = giveRLE(g.getcells(g.getrect())) g.setrule(rulestr) # Determine the minimal isotropic rule setminisorule(period) return minpop, g.getrule(), dx, dy, period, shiprle
def EdgeGlider(): for i in xrange(0, 4): rect = g.getrect() x0 = rect[0] + rect[2] - 3 y0 = rect[1] + rect[3] - 3 gldFound = True for j in xrange(0, len(gld), 2): if g.getcell(x0 + gld[j], y0 + gld[j + 1]) == 0: gldFound = False break if gldFound: return g.getcells([x0, y0, 3, 3]) g.run(1) return -1
def FindObj(objData, idx): c = g.getcells(g.getrect()) result = [] for i in xrange(2, len(c), 3): #g.show(str(i) + "/" + str(len(c))) x = c[i - 2] y = c[i - 1] found = True for r in objData: dx, dy, v = r if g.getcell(x + dx, y + dy) != v: found = False break if found: result.append((x, y, idx)) return result
def saveImage( bound, path ): left = bound[0] top = bound[1] width = bound[2] height = bound[3] cellW = 2 # create image img = Image.new( "RGB", ( width, height ) ) cells = g.getcells( bound ) cellLen = len( cells ) white = ( 255, 255, 255 ) for i in xrange( 0, cellLen, 2 ): x = cells[ i ] y = cells[ i + 1 ] img.putpixel( (x-left, y-top), (255, 255, 255) ) # save img.save( path )
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 explode_dense(): num_trial = 2 for i in range(num_trial): g.new("") g.select([0, 0, 32, 32]) g.randfill(50) g.run(128) total = 0 for i in range(32): total += len(g.getcells([0, 0, 32, 32])) / 2 g.run(32) total /= 32 if total >= 300: return True return False
def ReadLetters(x0, y0, l, h): res = [] xs = x0 d = 0 zerocnt = 0 for x in range(x0, x0 + l): if len(g.getcells([x, y0, 1, h])) == 0: zerocnt += 1 if zerocnt == 2: if d > 1: res.append((xs, y0, d + 1, h)) xs = x d = 0 zerocnt = 0 else: d += 1 return res
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 HasEdgeShooter(minx): rect = g.getrect() y = rect[1] + rect[3] if y < 100: return False g.run(4) rect = g.getrect() if y + 2 == rect[1] + rect[3]: maxX = -10000 maxL = -10000 for i in xrange(0, 4): g.run(1) rect = g.getrect() curCells = g.getcells([rect[0], rect[1] + rect[3] - 10, rect[2], 11]) curx = FindRightMost(curCells) curL = len(curCells) if curx > maxX: maxX = curx if curL > maxL: maxL = curL if minx - 2 > maxL: return 100 * maxL return maxL return False
def CanApplyRecipe(self, recipe, expected): g.new("") g.setstep(3) g.putcells(blck) g.putcells(self.init) for r in self.recipe: g.putcells(gld, 80, 80 + r) g.step() g.select([self.block0[0], self.block0[1], 2, 2]) g.clear(0) cells = g.getcells(g.getrect()) g.putcells(blck, self.block0[0], self.block0[1]) delta = self.block0[1] - self.block0[0] for r in recipe: g.putcells(gld, 80, 80 + r + delta) g.step() for i in xrange(0, len(cells), 2): x = cells[i] y = cells[i + 1] if g.getcell(x, y) == 0: return False for i in xrange(0, len(expected), 2): x = expected[i] + self.block0[0] y = expected[i + 1] + self.block0[1] if g.getcell(x, y) == 0: return False return True
def moveselection(): global oldcells, selrect, selpatt # wait for 1st click in selection while True: event = g.getevent() if event.startswith("click"): # event is a string like "click 10 20 left none" evt, xstr, ystr, butt, mods = event.split() x = int(xstr) y = int(ystr) if cellinrect(x, y, selrect): oldmouse = xstr + ' ' + ystr firstx = x firsty = y xoffset = firstx - selrect[0] yoffset = firsty - selrect[1] if mods == "alt": # don't delete pattern in selection oldcells = g.getcells(selrect) break elif event == "key h none": showhelp1() else: g.doevent(event) # wait for 2nd click while moving selection g.show("Move mouse and click again..." + helpmsg) gotclick = False while not gotclick: event = g.getevent() if event.startswith("click"): evt, x, y, butt, mods = event.split() mousepos = x+' '+y gotclick = True else: if len(event) > 0: lookforkeys(event, x - firstx, y - firsty) # update xoffset,yoffset in case selection was rotated xoffset = x - selrect[0] yoffset = y - selrect[1] mousepos = g.getxy() if len(mousepos) > 0 and mousepos != oldmouse: # mouse has moved, so move selection rect and pattern g.clear(0) if len(oldcells) > 0: g.putcells(oldcells) xstr, ystr = mousepos.split() x = int(xstr) y = int(ystr) selrect[0] = x - xoffset selrect[1] = y - yoffset if g.getwidth() > 0: # ensure selrect doesn't move beyond left/right edge of grid if selrect[0] < gridl: selrect[0] = gridl x = selrect[0] + xoffset elif selrect[0] + selrect[2] - 1 > gridr: selrect[0] = gridr + 1 - selrect[2] x = selrect[0] + xoffset if g.getheight() > 0: # ensure selrect doesn't move beyond top/bottom edge of grid 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()
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() aborted = False finally:
# 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()
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): for rotation in rotations: length = len (rotation) for i in range (length): if rotation[i] == state: return rotation[(i + direction) % length] return state for i in range (0, int (math.floor (len (cells) / 3) * 3), 3):
height = rect[3] x = rect[0] y = rect[1] for row in inclusive_range(y+height-1,y): far_right = x+width-1 while g.getcell(far_right,row)==0: far_right -= 1 if far_right<x: g.exit('Empty rows forbidden: '+str(row)) col = x while col <= far_right: if g.getcell(col,row)==1: data_tape+='11' # write 1 col += 1 else: if not g.getcells([col,row,n,1]): # next N cells zero? data_tape+='01' col += n else: data_tape+='10' # write 0 col += 1 data_tape+='001' # end of row #data_tape+='000' # end of construction (actually we skip this command) write_data_string(data_tape[::-1]) #g.warn(str(len(data_tape))) # tell the user how long the tape was # activate the injection receiver for i in range(50,65): g.setcell(i,230,2) g.setcell(i,231,1) g.setcell(i,232,2)
def FindAllHs(cells, minx): g.new("") g.putcells(cells) rect = g.getrect() min = 10000 max = -10000 for i in xrange(1, len(cells), 2): cx = cells[i - 1] cy = cells[i] dx = 40 - cx cy += dx if cy < min: min = cy if cy > max: max = cy answer = [[],[]] if (min - 9) % 2 != 0: min += 1 for i in xrange(min - 9 - 40, max + 6 - 40, 2): g.new("") g.putcells(cells) g.putcells(gld, 40, 40 + i) g.setstep(3) g.step() g.step() if int(g.getpop()) > 60: continue if int(g.getpop()) == 0: continue if g.getrect()[0] < -120: continue edgeType = HasEdgeShooter(minx) if edgeType != False: answer[0].append([i, 0, 0, [edgeType]]) rect = g.getrect() if rect[2] > 12 or rect[3] > 12: continue s = str(g.getcells(g.getrect())) g.run(2) if s == str(g.getcells(g.getrect())): key = str(rect) + ":" + str(g.getpop()) if not (key in existingKeys): existingDic[key] = [] existingKeys.append(key) if s in existingDic[key]: continue else: existingDic[key].append(s) answer[1].append(i) return answer
and g.getname(currindex - 1) == envname : # switch from starting layer to current layer and continue currindex += 1 g.setlayer(currindex) startindex = currindex - 1 envindex = currindex - 2 else: # start a new envelope using pattern in current layer if g.numlayers() + 1 > g.maxlayers(): g.exit("You need to delete a couple of layers.") if g.numlayers() + 2 > g.maxlayers(): g.exit("You need to delete a layer.") # get current layer's starting pattern startpatt = g.getcells(g.getrect()) envindex = g.addlayer() # create layer for remembering all live cells g.setcolors([-1,100,100,100]) # set all states to darkish gray g.putcells(startpatt) # copy starting pattern into this layer startindex = g.addlayer() # create layer for starting pattern g.setcolors([-1,0,255,0]) # set all states to green g.putcells(startpatt) # copy starting pattern into this layer # move currindex to above the envelope and starting pattern g.movelayer(currindex, envindex) g.movelayer(envindex, startindex) currindex = startindex startindex = currindex - 1 envindex = currindex - 2
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]))
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] if (not rulestr.startswith("B")) or (rulestr.find("/S") == -1): g.exit("This script only works with B*/S* rules.") # get the current selection slist = g.getcells(selrect) selwidth = selrect[2] selheight = selrect[3] # create a 2D list of 0s and 1s representing entire selection livecell = [[0 for y in xrange(selheight)] for x in xrange(selwidth)] for i in xrange(0, len(slist), 2): livecell[slist[i] - selrect[0]][slist[i+1] - selrect[1]] = 1 # build a patch pattern based on the current rule # that fixes the appropriate broken eaters in the rules table r1, r2 = rulestr.split("/") if r1[:1] == "B": Bvalues, Svalues = r1.replace("B",""), r2.replace("S","") elif r1[:1] == "S": Svalues, Bvalues = r1.replace("S",""), r2.replace("B","")
#''' #This code synchronize the backward recipes to fit with forward created at 0,0 g.show("synchronize the backward recipes to fit with forward") g.new("") MakeForwardSalvo(step, 0, 0, 0, True, True) forwardRecipe = FindWssByDirection(True, distForward) x0, y0, id = forwardRecipe[0] ConvertToRelative(forwardRecipe, distForward) g.open(path.join(dir, str(step) + "_" + str(period) + "_Back.rle"), False) rect = g.getrect() cells = g.getcells([rect[0], rect[1], rect[2], 4 * distBack]) g.new("") g.putcells(cells) for i in xrange(4): cRecipe = FindWssByDirection(True, distForward) x1, y1, id1 = cRecipe[0] ConvertToRelative(cRecipe, distForward) if str(forwardRecipe) == str(cRecipe): break g.run(1) dgen = int(g.getgen())