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 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 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 draw(self, addstr = ""): xy = [] xz = [] yz = [] proj = [] for (k, v) in self.cur_state.items(): x, y, z = k xy.append(x) xy.append(y) xz.append(x + 128) xz.append(z) yz.append(y) yz.append(z + 128) proj.append(x + y + z + 128) proj.append(- x + y + z + 128) if len(g.getrect()) > 0: g.select(g.getrect()) g.clear(0) g.select([]) g.putcells(xy) g.putcells(xz) g.putcells(yz) g.putcells(proj) g.setpos("64", "64") g.setmag(1) g.show("Size: {0}, (w, d, h): {1}".format(self.get_pop(), str(self.get_wdh())) + addstr) g.update()
def SaveForwardSalvoData(dir): g.new("") MakeBackwardSalvo(step, 0, 0, 0, True, True) rectB = g.getrect() g.new("") MakeForwardSalvo(step, 0, 0, 0, True, True) rectF = g.getrect() g.run(3) forwardRecipe = FindWssByDirection(True, distForward) forwardRecipe.reverse() fRecipe = [] dx = rectB[0] - (rectF[0] + rectF[2]) - 100 dx = int(dx / 8) * 8 for i in xrange(0, len(forwardRecipe)): x, y, d = forwardRecipe[i] fRecipe.append((x + dx, y + 1, d)) pickle.dump( fRecipe, open(path.join(dir, str(step) + "_ForwardSalvoAuto.pkl"), "wb"))
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 bijoscar(maxsteps): initpop = int(g.getpop()) initrect = g.getrect() if (len(initrect) == 0): return 0, None inithash = g.hash(initrect) for i in range(maxsteps): g.run(1) if (int(g.getpop()) == initpop): prect = g.getrect() phash = g.hash(prect) if (phash == inithash): period = i + 1 if (prect == initrect): return period, (0, 0) else: dx = prect[0] - initrect[0] dy = prect[1] - initrect[1] return period, (dx, dy) return -1, None
def draw(self): xy = [] xz = [] yz = [] proj = [] for (k, v) in self.cur_state.items(): x, y, z = k xy.append(x) xy.append(y) xz.append(x + 128) xz.append(z) yz.append(y) yz.append(z + 128) proj.append(x + y + z + 128) proj.append(-x + y + z + 128) if len(g.getrect()) > 0: g.select(g.getrect()) g.clear(0) g.select([]) g.putcells(xy) g.putcells(xz) g.putcells(yz) g.putcells(proj) g.setpos("64", "64") g.setmag(1) g.update()
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 bijoscar(maxsteps): initpop = int(g.getpop()) initrect = g.getrect() if (len(initrect) == 0): return 0 inithash = g.hash(initrect) for i in xrange(maxsteps): g.run(1) if (int(g.getpop()) == initpop): prect = g.getrect() phash = g.hash(prect) if (phash == inithash): period = i + 1 if (prect == initrect): return period else: return -period return -1
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 trygliders(ginfo): gdistance = ginfo / 4 phase = ginfo % 4 bstatus = boxstatus pstatus = popstatus for num in xrange(8): tlist = form(celllist, num) rect = boxform(fullrect, num) g.new('') g.putcells(tlist) gx = rect[0] - 3 - gdistance gy = rect[1] - 3 - gdistance for w in xrange(rect[2] + 5): g.new('') g.putcells(tlist) g.putcells(glider[phase], gx + w, gy) g.fit() g.update() for gen in xrange(1000): g.run(1) if int(g.getpop()) <= 2: g.new('') g.show("Found clean glider destruction.") status = 0, num, phase, [gx + w, gy] putcells_and_fit(result(celllist, status)) g.exit() box = g.getrect()[2:] # Checking the bounding box size and population against the current lowest found. if reduce(mul, box) < reduce(mul, bstatus[0]): bstatus = (box, num, phase, [gx + w, gy]) pop = int(g.getpop()) if pop < pstatus[0]: pstatus = (pop, num, phase, [gx + w, gy]) # Show results if the user presses certain keys event = g.getevent() if event.startswith("key x"): g.new('') put_result_pair(celllist, bstatus, pstatus) g.select(g.getrect()) g.copy() g.select([]) g.note( "Minimum bounding box and population collisions copied to clipboard." ) if event.startswith("key q"): g.new('') g.show("Search stopped.") put_result_pair(celllist, bstatus, pstatus) g.fit() g.exit() g.show( "Searching for a 1-glider destruction... press <x> to copy minimum bounding box and population results to clipboard; press <q> to quit. Stats: minimum bounding box %dx%d, minimum population %d" % (bstatus[0][0], bstatus[0][1], pstatus[0])) return bstatus, pstatus
def is_static(): global prev_world bbox = rect(g.getrect()) if bbox.empty: return False cur_world = g.hash(g.getrect()) if prev_world and prev_world == cur_world: return True else: prev_world = cur_world
def PlaceReadingHeads(hwssRecipe): global fenseX g.new("") g.setrule("LifeHistoryNoMark") if directionType == "B": dist = int(1.5 * len(hwssRecipe) / speed) for y in xrange(-dist, 1): MakeBackwardSalvo(step, 0, distBack * y, step * len(hwssRecipe) + 100, y == 0, y == 0) MakeBackwardRecipe(step, 0, 0, hwssRecipe) rect = g.getrect() cells = [] for i in xrange(1200, step * len(hwssRecipe) + 1501): cells.append(rect[0] - 50) cells.append(i) cells.append(6) g.putcells(cells) g.putcells(cells, rect[0] - 1000, 0) else: helixD = CalcHelix(hwssRecipe) dist = int(1.5 * len(hwssRecipe) / speed) for y in xrange(0, dist + 1): MakeForwardSalvo(step, 0, distForward * y, helixD, y == 0, y == 0) MakeForwardRecipe(helixD, step, 0, 0, hwssRecipe) rect = g.getrect() cells = [] fenseX = rect[0] + rect[2] + 50 for i in xrange(fenseY, -helixD + 201): cells.append(rect[0] + rect[2] + 50) cells.append(i + helixD) cells.append(6) g.putcells(cells)
def PlaceReadingHeads(hwssRecipe): global fenseX g.new("") g.setrule("LifeHistoryNoMark") if directionType == "B": dist = int(1.5 * len(hwssRecipe) / speed) for y in xrange(-dist, 1): MakeBackwardSalvo(step, 0, distBack * y, step * len(hwssRecipe) + 100, y == 0, y == 0) MakeBackwardRecipe(step, 0, 0, hwssRecipe) rect = g.getrect() cells = [] for i in xrange(1200, step * len(hwssRecipe) + 1501): cells.append(rect[0]-50) cells.append(i) cells.append(6) g.putcells(cells) g.putcells(cells, rect[0]-1000, 0) else: helixD = CalcHelix(hwssRecipe) dist = int(1.5 * len(hwssRecipe) / speed) for y in xrange(0, dist + 1): MakeForwardSalvo(step, 0, distForward * y, helixD, y == 0, y == 0) MakeForwardRecipe(helixD, step, 0, 0, hwssRecipe) rect = g.getrect() cells = [] fenseX = rect[0] + rect[2] + 50 for i in xrange(fenseY, -helixD + 201): cells.append(rect[0] + rect[2] + 50) cells.append(i + helixD) cells.append(6) g.putcells(cells)
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 canonise(): p = bijoscar(4) representation = "#" for i in range(abs(p)): rect = g.getrect() representation = compare_representations(representation, canonise_orientation(rect[2], rect[3], rect[0], rect[1], 1, 0, 0, 1)) representation = compare_representations(representation, canonise_orientation(rect[2], rect[3], rect[0]+rect[2]-1, rect[1], -1, 0, 0, 1)) representation = compare_representations(representation, canonise_orientation(rect[2], rect[3], rect[0], rect[1]+rect[3]-1, 1, 0, 0, -1)) representation = compare_representations(representation, canonise_orientation(rect[2], rect[3], rect[0]+rect[2]-1, rect[1]+rect[3]-1, -1, 0, 0, -1)) representation = compare_representations(representation, canonise_orientation(rect[3], rect[2], rect[0], rect[1], 0, 1, 1, 0)) representation = compare_representations(representation, canonise_orientation(rect[3], rect[2], rect[0]+rect[2]-1, rect[1], 0, -1, 1, 0)) representation = compare_representations(representation, canonise_orientation(rect[3], rect[2], rect[0], rect[1]+rect[3]-1, 0, 1, -1, 0)) representation = compare_representations(representation, canonise_orientation(rect[3], rect[2], rect[0]+rect[2]-1, rect[1]+rect[3]-1, 0, -1, -1, 0)) g.run(1) if (p<0): prefix = "q"+str(abs(p)) elif (p==1): prefix = "s"+str(g.getpop()) else: prefix = "p"+str(p) return "x"+prefix+"_"+representation
def fit_if_not_visible(): try: r = rect(g.getrect()) if (not r.empty) and (not r.visible()): g.fit() except: # getrect failed because pattern is too big g.fit()
def FindActive(): rect = g.getrect() cells = g.getcells([rect[0], rect[1], rect[2], 1]) return [cells[0], cells[1]]
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 testkey(): if results and g.getevent().startswith("key x"): g.setlayer(results_layer) g.select(g.getrect()) g.copy() g.select([]) g.setlayer(work_layer)
def getwhp(): bbox = g.getrect() if len(bbox) == 0: return 0, 0, 0 return bbox[2], bbox[3], int(g.getpop())
def rule_boring(): explode = 0 die = 0 num_trial = 8 for i in range(num_trial): g.new("") g.select([0, 0, 32, 32]) g.randfill(50) g.run(16) if int(g.getpop()) == 0: die += 1 continue r = g.getrect() if r[2] > 60 and r[3] > 60: explode += 1 continue return -1 if explode == num_trial: return 0 if die == num_trial: return 1 return -1
def canonise(): p = bijoscar(1000) representation = "#" for i in range(abs(p)): rect = g.getrect() representation = compare_representations(representation, canonise_orientation(rect[2], rect[3], rect[0], rect[1], 1, 0, 0, 1)) representation = compare_representations(representation, canonise_orientation(rect[2], rect[3], rect[0]+rect[2]-1, rect[1], -1, 0, 0, 1)) representation = compare_representations(representation, canonise_orientation(rect[2], rect[3], rect[0], rect[1]+rect[3]-1, 1, 0, 0, -1)) representation = compare_representations(representation, canonise_orientation(rect[2], rect[3], rect[0]+rect[2]-1, rect[1]+rect[3]-1, -1, 0, 0, -1)) representation = compare_representations(representation, canonise_orientation(rect[3], rect[2], rect[0], rect[1], 0, 1, 1, 0)) representation = compare_representations(representation, canonise_orientation(rect[3], rect[2], rect[0]+rect[2]-1, rect[1], 0, -1, 1, 0)) representation = compare_representations(representation, canonise_orientation(rect[3], rect[2], rect[0], rect[1]+rect[3]-1, 0, 1, -1, 0)) representation = compare_representations(representation, canonise_orientation(rect[3], rect[2], rect[0]+rect[2]-1, rect[1]+rect[3]-1, 0, -1, -1, 0)) g.run(1) if (p<0): prefix = "q"+str(abs(p)) elif (p==1): prefix = "s"+str(g.getpop()) else: prefix = "p"+str(p) rule = str.replace(g.getrule(),"/","").lower() webbrowser.open_new("http://catagolue.appspot.com/object?apgcode=x"+prefix+"_"+representation+"&rule="+rule)
def calculate_density(): bbox = gl.rect(g.getrect()) if bbox.empty: d = 0 else: d = float(g.getpop()) / float(bbox.wd*bbox.ht) return d
def canonise(): p = bijoscar(MAXPERIOD) if p == -1: # In rules with photons the pattern may be periodic, but not in CGoL return "" representation = "#" for i in range(abs(p)): rect = g.getrect() representation = compare_representations(representation, canonise_orientation(rect[2], rect[3], rect[0], rect[1], 1, 0, 0, 1)) representation = compare_representations(representation, canonise_orientation(rect[2], rect[3], rect[0]+rect[2]-1, rect[1], -1, 0, 0, 1)) representation = compare_representations(representation, canonise_orientation(rect[2], rect[3], rect[0], rect[1]+rect[3]-1, 1, 0, 0, -1)) representation = compare_representations(representation, canonise_orientation(rect[2], rect[3], rect[0]+rect[2]-1, rect[1]+rect[3]-1, -1, 0, 0, -1)) representation = compare_representations(representation, canonise_orientation(rect[3], rect[2], rect[0], rect[1], 0, 1, 1, 0)) representation = compare_representations(representation, canonise_orientation(rect[3], rect[2], rect[0]+rect[2]-1, rect[1], 0, -1, 1, 0)) representation = compare_representations(representation, canonise_orientation(rect[3], rect[2], rect[0], rect[1]+rect[3]-1, 0, 1, -1, 0)) representation = compare_representations(representation, canonise_orientation(rect[3], rect[2], rect[0]+rect[2]-1, rect[1]+rect[3]-1, 0, -1, -1, 0)) g.run(1) if (p<0): prefix = "xq" + str(abs(p)) elif (p==1): prefix = "xs" + str(g.getpop()) else: prefix = "xp" + str(p) return prefix + "_" + representation
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 SnakeReader(let): g.new("") g.setrule("LifeHistory") cl = let2cells[let][0] g.putcells(cl) emptyline = True dir = 1 rect = g.getrect() y0 = 0 h = rect[1] + rect[3] + 2 l = rect[0] + rect[2] + 3 x0 = rect[0] - 1 y = y0 x = x0 code = "" while True: y += dir if y < y0: if emptyline == True: code += "Y+;" break dir = 1 y += dir code += "Y+;" x += 1 emptyline = True elif y >= y0 + h: dir = -1 y += dir code += "Y+;" x += 1 emptyline = True else: if dir == -1: code += "X-;" else: code += "X+;" if g.getcell(x, y) != 0: code += "SET;" emptyline = False if x >= x0 + l: break for i in range(h): code = code.replace("X+;Y+;X-;", "Y+;") code = code.replace("X-;Y+;X+;", "Y+;") return code
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 checkFit(): r = g.getrect() if not r: return if not g.visrect(r): g.setpos(str(r[0] + r[2] / 2), str(r[1] + r[3] / 2)) if not g.visrect(r): g.setmag(g.getmag() - 1)
def clearlayer(): r = g.getrect() if r: g.select(r) g.clear(0) if withB0: # Needed with B0 rules to ensure pattern runs correctly g.setgen('0')
def EvolveRecipe(recipe): g.new("") g.setstep(3) g.putcells(blck) minx = g.getrect()[0] for r in recipe: g.putcells(gld, 40, 40 + r) g.step() g.step() if minx > g.getrect()[0]: minx > g.getrect()[0] return minx
def analyse (gogen, glcnt, minpop, maxpop, mingl): if glcnt < mingl: return (False, 0) g.run (gogen) inrect = g.getrect () clean (inrect) endpop = int (g.getpop ()) if endpop < minpop or endpop > maxpop: return (False, 0) rect = g.getrect () if rect == []: return (True, 0) else: addmarkers (inrect) return (True, g.hash (inrect))
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 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 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 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 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 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 LeftMost(recipe): g.putcells(block_cells) idx = 1 for r in recipe: #g.putcells(glider_cells, 80, 80 + r ) g.putcells(glider_cells, 160 * idx, 160 * idx + int(r)) idx += 1 #g.step() rect = g.getrect() return rect[0]
def SaveForwardSalvoData(dir): g.new("") MakeBackwardSalvo(step, 0, 0, 0, True, True) rectB = g.getrect() g.new("") MakeForwardSalvo(step, 0, 0, 0, True, True) rectF = g.getrect() g.run(3) forwardRecipe = FindWssByDirection(True, distForward) forwardRecipe.reverse() fRecipe = [] dx = rectB[0] - (rectF[0] + rectF[2]) - 100 dx = int(dx / 8) * 8 for i in xrange(0, len(forwardRecipe)): x, y, d = forwardRecipe[i] fRecipe.append((x + dx, y + 1, d)) pickle.dump(fRecipe, open(path.join(dir, str(step) + "_ForwardSalvoAuto.pkl"), "wb"))
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 LeftMost(recipe): g.new("") g.setstep(3) g.putcells(block_cells) for r in recipe: #g.putcells(glider_cells, 80, 80 + r ) g.putcells(glider_cells, 80, 80 + 2 - r ) g.step() g.step() rect = g.getrect() return rect[0]
def Validate(recipe): g.new("") g.setstep(3) g.putcells(block_cells) for r in recipe: g.putcells(glider_cells, 120, 120 + r) #g.putcells(glider_cells, 80, 80 + 2 - r ) g.step() g.step() rect = g.getrect() return rect
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 __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 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 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 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
def oscillating(): # return True if the pattern is empty, stable or oscillating # first get current pattern's bounding box prect = g.getrect() 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 (int(g.getpop()) == poplist[pos]) and \ (pbox.wd == boxlist[pos].wd) and \ (pbox.ht == boxlist[pos].ht): 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
def fit_if_not_visible(): # fit pattern in viewport if not empty and not completely visible r = rect(g.getrect()) if (not r.empty) and (not r.visible()): g.fit()
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
# Change the entire pattern from emulated-Margolus states to N-state: from glife import rect import golly as g r = rect( g.getrect() ) if r.empty: g.exit("There is no pattern.") for row in xrange(r.top, r.top + r.height): for col in xrange(r.left, r.left + r.width): s = g.getcell(col,row) g.setcell(col, row, (s+s%2)/2-1)
if obox.top < gridt: y += gridt - obox.top elif obox.bottom > gridb: y -= obox.bottom - gridb object = g.transform(object, x - prevx, y - prevy) oldcells = underneath(object) g.putcells(object) prevx = x prevy = y oldmouse = mousepos g.update() # ------------------------------------------------------------------------------ if len(g.getrect()) == 0: g.exit("There are no objects.") g.show("Click on or near live cell in object, move mouse and click again..." + helpmsg) oldcursor = g.getcursor() g.setcursor("Move") oldcells = [] # cells under moved object object = [] # cells in moving object object1 = [] # cells in initial object try: aborted = True moveobject() aborted = False finally: g.setcursor(oldcursor) if aborted: