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 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 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 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 PlaceReadingHeads(hwssRecipe): g.new("") g.setrule("LifeHistoryNoMark") if directionType == "B": for y in xrange(-3 * len(hwssRecipe), 1): MakeBackwardSalvo(step, 0, distBack * y, step * len(hwssRecipe) + 100, y == 0, y == 0) MakeBackwardRecipe(step, 0, 0, hwssRecipe) else: helixD = -step * len(hwssRecipe) - 1000 while helixD % 7500 != 0: helixD -= 1 for y in xrange(0, 3 * len(hwssRecipe) + 1): MakeForwardSalvo(step, 0, distForward * y, helixD, y == 0, y == 0) MakeForwardRecipe(helixD, step, 0, 0, hwssRecipe) cells = [] for i in xrange(fenseY, -helixD + 201): cells.append(240) cells.append(i + helixD) cells.append(6) g.putcells(cells)
def envelope(): # draw stacked layers using same location and scale g.setoption("stacklayers", 1) g.show("Hit escape key to stop script...") while True: g.run(1) if g.empty(): g.show("Pattern died out.") break # copy current pattern to envelope layer; # we temporarily disable event checking so thumb scrolling # and other mouse events won't cause confusing changes currpatt = g.getcells(g.getrect()) g.check(0) g.setlayer(envindex) g.putcells(currpatt) g.setlayer(currindex) g.check(1) step = 1 exp = g.getstep() if exp > 0: step = g.getbase()**exp if int(g.getgen()) % step == 0: # display all 3 layers (envelope, start, current) g.update()
def envelope (): # draw stacked layers using same location and scale g.setoption("stacklayers", 1) g.show("Hit escape key to stop script...") while True: g.run(1) if g.empty(): g.show("Pattern died out.") break # copy current pattern to envelope layer; # we temporarily disable event checking so thumb scrolling # and other mouse events won't cause confusing changes currpatt = g.getcells(g.getrect()) g.check(0) g.setlayer(envindex) g.putcells(currpatt) g.setlayer(currindex) g.check(1) step = 1 exp = g.getstep() if exp > 0: step = g.getbase()**exp if int(g.getgen()) % step == 0: # display all 3 layers (envelope, start, current) g.update()
def 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 GunPlacer(gunCollection): g.new("") for i in xrange(0, len(gunCollection)): g.putcells(gunCollection[i], 0, 0); PlaceNumber(i + 14, -150, i * 650)
def PlaceRecipeList(recipes): if len(recipes) == 0: return g.new("") dx = 0 recipes.sort(key=lambda f: str(f[3])) curF = str(recipes[0][3]) f = open(destinationPath + str(len(recipes)) + curF + ".txt",'w') for res in recipes: recipe = res[0] x1 = res[1] y1 = res[2] slL = res[3] g.putcells(blck, dx, 0) d = 0 for r in recipe: g.putcells(gld, 40 + d * 256 + dx, 40 + r + d * 256) d += 1 dx += 256 if curF != str(slL): f.close() curF = str(slL) f = open(destinationPath + str(len(recipes)) + curF + ".txt",'w') f.write("{0},{1}:".format(x1, y1) + str(recipe).strip("]").strip("[") + "\n")
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 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 makerecipe(background, gliderlist): g.new("Recipe") g.putcells(background) offset = max(background[1::2]) + 4 for glider, delta in gliderlist: clist, lane = glider g.putcells(clist, (lane + 1) // 2 + offset, offset) offset += delta
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 makerecipe(recipe): g.putcells(gliderlist[0]) totaltime = 0 for i in recipe[1:]: totaltime += i g.putcells( g.transform(gliderlist[totaltime % 4], totaltime / 4, totaltime / 4)) g.show(str(totaltime))
def EvolveRecipe(recipe): g.new("") g.setstep(3) g.putcells(blck) for r in recipe: g.putcells(gld, 40, 40 + r) g.step() g.step()
def PlaceRecipe(self, x = 0, y = 0, makenew = True): if makenew: g.new("Results") g.show(str(self.recipeIdxList)) g.setclipstr(str(self.recipeIdxList)) g.putcells(blck, x, y) i = 0 for r in self.recipe: g.putcells(gld, x + 80 + i * 128, y + 80 + i * 128 + r) i += 1
def main(): apgcode = canonise() if not apgcode: g.warn( 'Failed to detect periodic behaviour after {} generations.'.format( MAXPERIOD)) # 2G collisions if apgcode in twoGcols: cols = twoGcols[apgcode] else: cols = [] # 3G and 4G collisions for cFile in compFiles: with open(cFile) as cF: found_code = False for l in cF: line = l.strip() if not found_code: if line == apgcode: found_code = True continue elif '>' in line: in_code, gstr, _ = line.split(">") if in_code: g.warn( 'Non-empty starting target in glider collision - Not implemented' ) else: cols.append(gstr) else: break Ncols = len(cols) if Ncols: try: cols = [reconstruct(col) for col in cols] except Exception: g.note(str(cols)) g.new("solutions") g.show("{} collisions found".format(Ncols)) g.setname(apgcode) if Ncols <= 20: N = 5 else: N = math.ceil(math.sqrt(Ncols)) + 1 offset = 100 for i, col in enumerate(cols): g.putcells(col, int((i % N) * offset), int((i // N) * offset)) g.fit() else: g.note( "No glider collisions found for constellation {}. Better luck next time" .format(apgcode))
def fill_void(): # sample incremental 46P4H1V0 synthesis pat = g.parse( """1422bo$1422bobo$1422b2o6$1217bo$1218bo191bo$1216b3o141bo50b2o$1226bo 133bobo47b2o$1226bobo127bo3b2o$1226b2o53bo75b2o37bobo29bobo$1276bobo2b obo72b2o39b2o15bo13b2o$1277b2o2b2o70bo43bo14bobo14bo$1277bo73bobo59b2o $1343bo8b2o53bo11bo$1284bo57bobo3bo57bobo3bo5bobo$642bo517bo123bo58b2o 3bo39bobo16b2o3bo5b2o16bobo$62bo13bo54bo510bobo513bobo123bo63bo40b2o6b o14bo16bo6b2o$60bobo13bobo52bobo3bobo365bo132bo3b2o397bo117b2o3bo224bo 5bobo31bobo5bo$61b2o13b2o53b2o4b2o43bobo133bo58bo125bobo133b2o81bobo 119bo68bo127bobo108b2o8b2o52b2o7b2o44b3o6b2o7b2o53b2o7b2o41b2o10b2o7b 2o10b2o$138bo44b2o133bobo57b2o124b2o68bo63b2o82b2o118bobo66b2o128b2o 57bo50bobo9b2o50bobo7bobo45bo5bobo7bobo51bobo7bobo51bobo7bobo$140bo42b o13bo63bo56b2o5bo51b2o10bo63bo63bo54bobo6bo63bo63bo13bo49bo63bo5b2o56b o10b2o51bo63bo63bo6bobo48bo5bo57bo5bo5bo44bo6bo5bo5bo51bo5bo5bo51bo5bo 5bo$o60b3o11b3o53bo3bo3b2o45bobo7bobo61bobo53bo7bobo61bobo61bobo61bobo 54b2o5bobo61bobo61bobo7bobo51bobo61bobo7bo53bobo61bobo61bobo61bobo5b2o 48b2o4bobo55b2o4bobo4b2o49b2o4bobo4b2o49b2o4bobo4b2o49b2o4bobo4b2o$b2o 60bo11bo54bobobobo2bobo45b2o7bobo61bobo51bobo7bobo53b2o6bobo61bobo61bo bo61bobo61bobo61bobo7b2o52bobo61bobo7bobo51bobo6b2o53bobo61bobo61bobo 61bobo61bobo61bobo61bobo61bobo$2o60bo13bo54b2ob2o51bo7b2ob2o59b2ob2o 51b2o6b2ob2o51bo2bo4b2ob2o59b2ob2o59b2ob2o54bo4b2ob2o59b2ob2o59b2ob2o 7bo51b2ob2o59b2ob2o6b2o51b2ob2o4bo2bo51b2ob2o54bo4b2ob2o54bo4b2ob2o4bo 54b2ob2o59b2ob2o59b2ob2o59b2ob2o59b2ob2o$257bo7bo55bo7bo50b2o3bo7bo55b o7bo55bo7bo51bobobo7bo52bo2bo7bo55bo63bo7bo55bo7bo55bo7bo3b2o50bo7bo 51bobobo7bo51bobobo7bobobo48bo2bo7bo2bo42bo6bo2bo7bo2bo6bo42bo2bo7bo2b o49bo2bo7bo2bo49bo2bo7bo2bo$6bo42b2o5bo25bo5b2o39b4ob4o45bo9b4ob4o55b 4ob4o55b4ob4o45bo9b4ob4o55b4ob4o55b4ob4o52b2ob4ob4o52b7ob4o55b4ob4o9bo 45b4ob4o55b4ob4o55b4ob4o9bo45b4ob4o52b2ob4ob4o52b2ob4ob4ob2o49b7ob7o 40bobo6b7ob7o6bobo40b7ob7o49b7ob7o49b7ob7o$6bobo39bobo6bo9bo3bo9bo6bob o38bo2bobo2bo46bo8bo2bobo2bo58bobo61bobo49b2o10bobo61bobo61bobo61bobo 61bobo61bobo2bo8bo49bobo61bobo61bobo10b2o49bobo61bobo61bobo61bobo47b2o 12bobo12b2o47bobo61bobo41bo19bobo19bo$2bo3b2o42bo4b3o8bobobobo8b3o4bo 41bobobobo45b3o3bo5bobobobo56b2obobob2o55b2obobob2o45b2o2b3o3b2obobob 2o53b4obobob2o53b4obobob2o52b5obobob2o52b5obobob2o55b2obobobo5bo3b3o 42b4obobob2o53b4obobob2o53b4obobob2o3b3o2b2o43b4obobob4o50b5obobob4o 50b5obobob5o49b5obobob5o44b2o3b5obobob5o3b2o40b2o2b5obobob5o2b2o41b2o 2b5obobob5o2b2o31b2o8b2o2b5obobob5o2b2o8b2o$3b2o62b2ob2o59b2ob2o53bo5b 2ob2o57bob2ob2obo55bob2ob2obo51bo3bob2ob2obo52bo2bob2ob2obo52bo2bob2ob 2obo52bo2bob2ob2obo52bo2bob2ob2obo55bob2ob2o5bo48bo2bob2ob2obo52bo2bob 2ob2obo52bo2bob2ob2obo3bo48bo2bob2ob2obo2bo49bo2bob2ob2obo2bo49bo2bob 2ob2obo2bo49bo2bob2ob2obo2bo43bobo3bo2bob2ob2obo2bo3bobo39b2o2bo2bob2o b2obo2bo2b2o41b2o2bo2bob2ob2obo2bo2b2o30bobo8b2o2bo2bob2ob2obo2bo2b2o 8bobo$2b2o183b3o182b3o5bo65b2o61bobo205b3o46b2o62b2o62b2o14bo5b3o38bob o11b2o62bobo172bo21bo$54b3o25b3o289bo67bo67bo405bo41bo17bo59bo$56bo25b o105bo184bo8b2o59b2o273bo188b2o8bo56b2o$55bo27bo103b2o65b2o121b2o2bo2b o57b2o8b2o264b2o59b2o125bo2bo2b2o51b2o8b2o$187bobo59b3ob2o121bobo2bo2b o63bo2b2o50b2o212bobo60b2ob3o120bo2bo2bobo51b2o2bo71b2o$194b2o55bo3bo 122bo3b2o64b2o3bo50b2o205b2o66bo3bo123b2o3bo52bo3b2o70b2o$194bobo53bo 196bobo53bo3b2o201bobo71bo184bobo66b2o3bo348b3o21b3o13b3o$194bo245b3o 56b2o5b2o204bo263b3o60b2o5b2o346bo6b2o13bo7b2o6bo$442bo57b2o6bo467bo 61bo6b2o346bo8b2o8b2o3bo5b2o8bo$441bo57bo477bo69bo353bo9bobo11bo$443b 3o527b3o437bo$443bo531bo$444bo529bo!""") g.putcells(pat)
def MakeForwardRecipe(helixSLdy, distance, dx, dy, recipe): d = (distance - 98) / 2 frontSL = g.parse("bo$obo$o2bo$b2o!", 132 + d + dx, 314 + d + dy) curd = helixSLdy + distance for r in recipe: if r != 'SKIP': g.putcells(frontSL, 0, curd + r) curd += distance
def MakeBackwardRecipe(distance, dx, dy, recipe): d = (distance - 144) / 2 backSL = g.parse("b2o$o2bo$obo$bo!", 6 - d + dx, 629 - d + dy) curd = distance + 2 recipe.insert(0, -4) for r in recipe: if r != 'SKIP': g.putcells(backSL, 0, curd - r) curd += distance
def FinishMove(d, w, h, x0, y0, p, t): under = d[0] obj = d[1] x = d[2] y = d[3] if under != -1: g.putcells(under) g.putcells(g.evolve(obj, p + GetEvolveDirection(t) * ((4 * (x - x0)) % p)), x, y) g.update()
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 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 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 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 AdaptiveGoto(hwssRecipe, enablePrinting=True): #g.setrule("LifeHistory") fense50 = g.parse( "F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F!" ) helixD = CalcHelix(hwssRecipe) curgen = -helixD * 2 curgen += 2 * distForward goto(curgen) g.setbase(8) g.setstep(3) delta = 10 lastmaxi = delta idx = 0 for i in hwssRecipe: if enablePrinting and (100 * (idx + 1)) / len(hwssRecipe) != ( 100 * idx) / len(hwssRecipe): percent = (100 * (idx + 1)) / len(hwssRecipe) g.update() g.show("Iterating forward progress " + str(percent) + "%") curgen += 2 * distForward idx += 1 while int(g.getgen()) < curgen: g.step() if i == 'SKIP': continue if i > lastmaxi: g.select([fenseX, helixD + fenseY + lastmaxi - delta, 1, delta]) g.clear(0) lastmaxi += delta #g.update() if i < lastmaxi - delta: g.putcells(fense50, fenseX, helixD + fenseY + lastmaxi - 2 * delta) lastmaxi -= delta
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 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 AddText(val, x, y): t = make_text(val, "mono") newt = [] cnt = 0 for i in t: cnt += 1 newt.append(i) if cnt % 2 == 0: newt.append(4) if len(newt) % 2 == 0: newt.append(0) g.putcells(newt, x, y)
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 PlaceNumber(number, x = 0, y = 0): if number < 0: g.putcells(figure8[3], x, y) PlaceNumber(-number, x, y) return curNum = number d = 20 * NumDigit(number) while True: PlaceDigit(curNum%10, x + d, y) curNum = (curNum - curNum%10) / 10 if curNum == 0: return d -= 20
def show_it(recipe, lane, move, elbow_type, start_elbow): global offset start_cells, start_type, start_lane = start_elbow res = "" phase = 0 if lane is not None: direction = lane[1] phase = lane[2] if direction == 0: res = "Rev%d" % lane[0] elif direction == 1: res = "R%d" % (lane[0] - start_lane) elif direction == 2: res = "L%d" % (lane[0] - start_lane) # elif direction == 3: # res = "LWSS_W" # elif direction == 4: # res = "LWSS_S" if move is None: res += "k" else: res += "m%d%s%s" % (move - start_lane, str(start_type), elbow_type) g.putcells(make_text(res, "mono"), offset, -80) g.putcells(start_cells, offset, 0) for i, t in enumerate(recipe[::2]): if t is not None: d = 80*i + MAX_DIFF / 4 + 20 g.putcells(g.evolve(G1, t + MAX_DIFF), offset-d, d) for i, t in enumerate(recipe[1::2]): if t is not None: d = 80*i + MAX_DIFF / 4 + 20 g.putcells(g.evolve(G2, t + MAX_DIFF), offset-d, d) res += ": " for i in range(0, len(recipe), 2): if recipe[i] is None: res += "eo"[(recipe[i+1]+phase)%2] + "-9999 " elif recipe[i+1] is None: res += "eo"[(recipe[i]+phase)%2] + "9999 " else: res += "eo"[(recipe[i]+phase)%2] + str(recipe[i]-recipe[i+1]) + " " f.write(res + "\n") f.flush() offset += 100 g.update()
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 AdaptiveGoto(hwssRecipe, enablePrinting = True): #g.setrule("LifeHistory") fense50 = g.parse("F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F!") helixD = CalcHelix(hwssRecipe) curgen = -helixD * 2 curgen += 2 * distForward goto(curgen) g.setbase(8) g.setstep(3) delta = 10 lastmaxi = delta idx = 0 for i in hwssRecipe: if enablePrinting and (100 * (idx + 1)) / len(hwssRecipe) != (100 * idx) / len(hwssRecipe): percent = (100 * (idx + 1)) / len(hwssRecipe) g.update() g.show("Iterating forward progress " + str(percent) + "%") curgen += 2 * distForward idx += 1 while int(g.getgen()) < curgen: g.step() if i == 'SKIP': continue if i > lastmaxi: g.select([fenseX, helixD + fenseY + lastmaxi - delta, 1, delta]) g.clear(0) lastmaxi += delta #g.update() if i < lastmaxi - delta: g.putcells(fense50, fenseX, helixD + fenseY + lastmaxi - 2 * delta) lastmaxi -= delta
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 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 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 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 setupT(dhead, binaryStr, dx, dy): setupR(dhead, dx, dy) setupR(len(binaryStr) - 1 - dhead, dx + 310, dy - 506) setupR(dhead * 16, dx + 130, dy - 3286) setupR(dhead * 16, dx - 1113, dy - 2062) if len(binaryStr) == 0: return x = dx + 142 y = dy - 3305 g.select([x, y, 3, 3]) g.clear(0) for i in range(len(binaryStr)): if binaryStr[i] == '0': g.putcells(boat, x, y) else: g.putcells(boat, x - 3, y - 3) x -= 16 y -= 16
def AdaptiveGoto(hwssRecipe): #g.setrule("LifeHistory") fense50 = g.parse("F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F!") helixD = -step * len(hwssRecipe) - 1000 while helixD % 7500 != 0: helixD -= 1 curgen = -helixD * 2 curgen += 2 * distForward goto(curgen) g.setstep(3) delta = 10 lastmaxi = delta for i in hwssRecipe: curgen += 2 * distForward while int(g.getgen()) < curgen: g.step() if i == 'SKIP': continue if i > lastmaxi: g.select([240, helixD + fenseY + lastmaxi - delta, 1, delta]) g.clear(0) lastmaxi += delta #g.update() if i < lastmaxi - delta: g.putcells(fense50, 240, helixD + fenseY + lastmaxi - 2 * delta) lastmaxi -= delta
def getobject(x, y): object = [] ncells.append( (x, y, g.getcell(x,y)) ) g.setcell(x, y, 0) while len(ncells) > 0: # remove cell from end of ncells and append to object x, y, s = ncells.pop() object.append(x) object.append(y) object.append(s) # add any live neighbors to ncells checkneighbor(x , y+1) checkneighbor(x , y-1) checkneighbor(x+1, y ) checkneighbor(x-1, y ) checkneighbor(x+1, y+1) checkneighbor(x+1, y-1) checkneighbor(x-1, y+1) checkneighbor(x-1, y-1) # append padding int if necessary if len(object) > 0 and (len(object) & 1) == 0: object.append(0) g.putcells(object) return object
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) dvdy = params['dvdy'] dudy = params['dudy'] dvdt = params['dvdt'] cells = g.getcells(g.getrect()) cells = zip(cells[::2], cells[1::2]) gcells = [] for (u, v) in cells: for t in xrange(p): xp = dvdy * u - dudy * v - a * t yq = v - t * dvdt if (xp % p != 0): continue if (yq % dvdy != 0): continue x = xp // p y = yq // dvdy gcells.append((t, x, y)) spacing = max([x for (_, x, _) in gcells]) - min([x for (_, x, _) in gcells]) spacing += 10 gcells = [(x + spacing * t, y) for (t, x, y) in gcells] g.setlayer(g.addlayer()) g.putcells([x for y in gcells for x in y]) g.fit()
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 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 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 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 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()
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: g.setcursor(oldcursor) if aborted: g.clear(0) if len(oldcells) > 0: g.putcells(oldcells) g.putcells(firstpatt) g.select(firstrect) else: g.show(" ")