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 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 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 add_data(PATTERN_FN): g.select([-2753, 891, 1092, 1397]) g.clear(0) g.select([]) input_str = open(PATTERN_FN, "r").read() firstbreak = input_str.find("\n") if firstbreak == -1: g.show("Error, no newlines found, invalid format") g.exit() info_line = input_str[0:firstbreak] input_str = input_str[firstbreak:] #x = 1581, y = 1396, rule = Varlife dataptrn = re.compile( br'x = (?P<xval>[0-9]{1,4}), y = (?P<yval>[0-9]{1,4}), rule = .*') match = dataptrn.match(info_line) xval = 0 yval = 0 if (match): xval = int(match.group("xval"), 10) yval = int(match.group("yval"), 10) else: g.show("ERROR invalid format {}".format(info_line)) g.exit() ipat = pattern(input_str) minbox = getminbox(ipat) if max(xval, minbox.x) > 1200: g.show("ERROR inserted cell area too wide, max width is 1090") g.exit() if max(yval, minbox.y) > 1397: g.show("ERROR inserted cell area too tall, max height is 1397") g.exit() startx = -1661 - xval starty = 891 #blankptrn.put(startx, starty) g.show( "width={}, height={} startx={}, starty={}, xval={}, yval={}, bytes={}". format(minbox.wd, minbox.height, startx, starty, xval, yval, len(input_str))) ipat.put(startx, starty) g.save("/tmp/output.mc", "rle", False) return "Pattern load data: width={}, height={} startx={}, starty={}, xval={}, yval={}, bytes={}".format( minbox.wd, minbox.height, startx, starty, xval, yval, len(input_str))
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 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 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 write(asm): binary = translateAll(asm) g.open("computer.mc") g.duplicate() g.setname("programmed", 0) g.movelayer(1, 0) g.dellayer() g.select([-25950, 1890, 450, 240]) g.cut() for i in range(len(binary)): for j in range(21): if int(binary[i][j]): g.select([-23639+i*600+j*300, 2159+i*600-j*300, 450, 240]) g.clear(0) g.paste(-23639+i*600+j*300, 2159+i*600-j*300, "or")
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 tileit(clist,tilewd): global inc,pbox cliplist=clist # g.select([boxsel[0]-20,boxsel[1]-20,20,20]) # g.clear(0) # make_text(str(posi)).put(boxsel[0]-20,boxsel[1]) pbox = rect( [0, 0] + cliplist[0 : 2] ) wd=tilewd*pbox.wd ht=tilewd*pbox.ht boxsel=[-int(wd/2),-int(wd/2),wd,ht] g.select(boxsel) selrect = rect( g.getselrect() ) inc=2 cliplist[0 : 2] = [] # remove wd,ht p = pattern( cliplist ) if len(cliplist) & 1 == 1: inc = 3 # multi-state? g.clear(inside) if len(cliplist) > 0: # tile selrect with p, clipping right & bottom edges if necessary y = selrect.top while y <= selrect.bottom: bottom = y + pbox.height - 1 x = selrect.left while x <= selrect.right: right = x + pbox.width - 1 if (right <= selrect.right) and (bottom <= selrect.bottom): p.put(x, y) else: clip_rb( p(x, y), selrect.right, selrect.bottom ).put() x += pbox.width y += pbox.height if not selrect.visible(): g.fitsel()
def 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 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
mode = "or" # abort shift if the new selection would be outside a bounded grid if g.getwidth() > 0: gridl = -int(g.getwidth()/2) gridr = gridl + g.getwidth() - 1 newl = selrect[0] + x newr = newl + selrect[2] - 1 if newl < gridl or newr > gridr: g.exit("New selection would be outside grid.") if g.getheight() > 0: gridt = -int(g.getheight()/2) gridb = gridt + g.getheight() - 1 newt = selrect[1] + y newb = newt + selrect[3] - 1 if newt < gridt or newb > gridb: g.exit("New selection would be outside grid.") # do the shift by cutting the current selection and pasting it into # the new position without changing the current clipboard pattern selcells = g.getcells(selrect) g.clear(inside) selrect[0] += x selrect[1] += y g.select(selrect) if mode == "copy": g.clear(inside) g.putcells(selcells, x, y, 1, 0, 0, 1, mode) if not g.visrect(selrect): g.fitsel()
return pattern(clist) # ------------------------------------------------------------------------------ selrect = rect( g.getselrect() ) if selrect.empty: g.exit("There is no selection.") cliplist = g.getclip() # 1st 2 items are wd,ht pbox = rect( [0, 0] + cliplist[0 : 2] ) cliplist[0 : 2] = [] # remove wd,ht p = pattern( cliplist ) if len(cliplist) & 1 == 1: inc = 3 # multi-state? g.clear(inside) if len(cliplist) > 0: # tile selrect with p, clipping right & bottom edges if necessary y = selrect.top while y <= selrect.bottom: bottom = y + pbox.height - 1 x = selrect.left while x <= selrect.right: right = x + pbox.width - 1 if (right <= selrect.right) and (bottom <= selrect.bottom): p.put(x, y) else: clip_rb( p(x, y), selrect.right, selrect.bottom ).put() x += pbox.width y += pbox.height
# 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()
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()
def getRuleRangeElems(period, ruleRange='minmax'): if g.empty(): return if period < 1: return rule = g.getrule().split(':')[0] if not (rule[0] == 'B' and '/S' in rule): g.exit('Please set Golly to an isotropic 2-state rule.') # Parse rule string to list of transitions for Birth and Survival oldrule = rule Bstr, Sstr = rule.split('/') Bstr = Bstr.lstrip('B') Sstr = Sstr.lstrip('S') b_need = parseTransitions(Bstr) b_OK = list(b_need) s_need = parseTransitions(Sstr) s_OK = list(s_need) patt = g.getcells(g.getrect()) # Record behavior of pattern in current rule clist = [] poplist = [] for i in range(0, period): g.run(1) clist.append(g.getcells(g.getrect())) poplist.append(g.getpop()) finalpop = g.getpop() if 'min' in ruleRange: # Test all rule transitions to determine if they are required for t in b_OK: b_need.remove(t) g.setrule('B' + ''.join(b_need) + '/S' + Sstr) r = g.getrect() if r: g.select(r) g.clear(0) g.putcells(patt) for j in range(0, period): g.run(1) try: if not (clist[j] == g.getcells(g.getrect())): b_need.append(t) break except: b_need.append(t) break b_need.sort() for t in s_OK: s_need.remove(t) g.setrule('B' + Bstr + '/S' + ''.join(s_need)) r = g.getrect() if r: g.select(r) g.clear(0) g.putcells(patt) for j in range(0, period): g.run(1) try: if not (clist[j] == g.getcells(g.getrect())): s_need.append(t) break except: s_need.append(t) break s_need.sort() if 'max' in ruleRange: # Test unused rule transitions to determine if they are allowed allRuleElem = [t for l in Hensel for t in l] for t in allRuleElem: if t in b_OK: continue b_OK.append(t) g.setrule('B' + ''.join(b_OK) + '/S' + Sstr) r = g.getrect() if r: g.select(r) g.clear(0) g.putcells(patt) for j in range(0, period): g.run(1) try: if not (clist[j] == g.getcells(g.getrect())): b_OK.remove(t) break except: b_OK.remove(t) break b_OK.sort() for t in allRuleElem: if t in s_OK: continue s_OK.append(t) g.setrule('B' + Bstr + '/S' + ''.join(s_OK)) r = g.getrect() if r: g.select(r) g.clear(0) g.putcells(patt) for j in range(0, period): g.run(1) try: if not (clist[j] == g.getcells(g.getrect())): s_OK.remove(t) break except: s_OK.remove(t) break s_OK.sort() r = g.getrect() if r: g.select(r) g.clear(0) g.putcells(patt) g.setrule(oldrule) return b_need, s_need, b_OK, s_OK
def randfill(x, y): g.select([-int(x / 2), -int(y / 2), x, y]) g.clear(0) g.randfill(50) g.select([])
if g.getcell(signal[0], signal[1]) == 1: done = 1 g.run(finaladjustment) g.run(100 * iperiod / subperiod) if subperiod > 1 and outputmatch(output) != 1: countdown = subperiod g.setgen("0") while countdown >= 0: countdown -= 1 g.run(iperiod / subperiod) if outputmatch(output) == 1: break if outputmatch(output) != 1: g.exit("Looks like something went wrong at period " + period \ + ". Output is not showing up after any reasonable number of subperiod cycles.") g.select(r) g.clear(1) g.select([]) g.setgen("0") g.show("Done! " + os.path.join(outfolder, str(period))) g.putcells(fixedbb) g.putcells(movablebb, iadjustment * dx, iadjustment * dy) g.save( os.path.join( outfolder, "p" + str(iperiod + 100000)[1:] + "_" + basegun + ".rle"), "rle") countbuilt += 1 #check we get the expected size if usebb == 1: r = bb # guns not built from template should use their LifeHistory bounds
def setupR(val, dx, dy): g.select([dx, dy, 2, 2]) g.clear(0) g.putcells(blck, dx - val, dy - val)
def Main(self): g.show("left click on a pattern to change, 'h' for help") gollyMode = False while True: event = g.getevent() if ("key" in event and "return" in event) or (gollyMode and " a " in event): gollyMode = not gollyMode if gollyMode: g.show("In golly mode") g.update() else: g.show("left click on a pattern, right click to finish") g.setrule("B3/S23") g.setalgo("HashLife") g.reset() g.update() continue if gollyMode: if " delete " in event: g.clear(0) if "click" in event and "ctrl" in event and g.getxy() != "": x, y = g.getxy().split() cell = g.getcell(int(x), int(y)) if cell >= 0 and cell <= 1: g.setcell(int(x), int(y), 1 - cell) g.update() if " c " in event and "ctrl" in event and g.getselrect() != []: g.copy() if " v " in event and "ctrl" in event and g.getxy() != "": x, y = g.getxy().split() g.paste(int(x), int(y), "or") if " space " in event: if "ctrl" in event: g.run(10) else: g.run(1) g.doevent(event) continue if "click" in event: if "left" in event: if self.ExistinCircuitHandler() == None: if self.SignalClickHandler(event) == None: g.show("left click on a pattern, h for help") elif "key" in event: if " space " in event: for i in xrange(0, 30): g.run(60) g.update() g.reset() g.update() if " a " in event: if g.getrule() == "Perrier": g.setrule("B3/S23") g.setalgo("HashLife") g.update() else: g.setrule("Perrier") for key in self.smarCells: x, y = key.split(":") g.setcell(int(x), int(y), self.smarCells[key] + 2) gollyMode = True g.show("In golly mode") g.update() if " s " in event: fname = os.path.join(g.getdir("data"), "MetadataManager.json") #self.Save(fname) if " h " in event: noteMessage = "Viewing and Selecting\n\n" noteMessage += "'left click' to chose gun or glider\n" noteMessage += "'a' to see in colors, a to go back \n" noteMessage += "'space' see ahead 1800 generations \n" noteMessage += "'enter' gollyMode, stays in the script \n" noteMessage += "\n Editing Gun \n\n" noteMessage += "'left click' to place\n" noteMessage += "'right click' to switch gun/orientation \n" noteMessage += "'delete' to delete the gun \n" noteMessage += "'left-right arrow' - one step adjustment\n" noteMessage += "\n In Golly Mode \n\n" noteMessage += "'delete' to clear selection\n" noteMessage += "'ctrl' + 'click' to draw \n" noteMessage += "'ctrl' + 'c' to copy selection \n" noteMessage += "'ctrl' + 'v' to paste in mouse location \n" noteMessage += "'space' + to run 1 generation \n" noteMessage += "'ctrl' +'space' to run 10 generations \n" g.note(noteMessage)
def __init__(self): try: g.show('setting up test') testSize = 100 #this is the size of one side of the square testing area g.select([-testSize/2,-testSize/2,testSize,testSize]) #clear the canvas g.clear(1) g.clear(0) g.randfill(50) g.update() g.show('stressTest started') startTime = time() lg_envmt = lifegenes_environment() endTime = time() logging.debug('\tsetup t\t=\t\t'+str(endTime-startTime)) g.update() startTime = time() lg_envmt.drawColor() endTime = time() logging.debug('\tcolorDraw t\t=\t' + str( endTime - startTime)) g.update() startTime = time() lg_envmt.cellMotions() endTime = time() logging.debug('\tmovement t\t=\t' + str( endTime - startTime)) g.update() startTime = time() lg_envmt.drawColor() endTime = time() logging.debug('\tcolor update t \t= ' + str( endTime - startTime)) g.update() g.step() startTime = time() lg_envmt.update() endTime = time() logging.debug('\tevolve update t\t= ' + str( endTime - startTime)) startTime = time() lg_envmt.cellMotions() endTime = time() logging.debug('\tmovement t\t=\t' + str( endTime - startTime)) g.update() startTime = time() lg_envmt.drawColor() endTime = time() logging.debug('\tcolor update t\t= ' + str( endTime - startTime)) g.update() g.update() g.show('test complete') finally: logging.info('cycling halted from external source (probably golly)')
# 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()
iters = int(l / speed + l * 2 + l * (1 + 2 * speed) / (0.5 - speed)) iters = (1 + int(iters / distForward)) * distForward g.show("Iterating Tail to reach " + str(iters) + " iter") g.fit() g.update() #The speed is negative Head = -speed * iters + 576 Tail = -speed * (iters - l * 2) + l + 576 GotoLimited(iters, 5) rect = g.getrect() g.select([rect[0], Head - 3 * distBack, rect[2], Tail - Head + 3 * distBack + 1500]) g.clear(1) g.save(path.join(dir, str(step) + "_" + str(period) + "_Back.rle"), "rle", False) #''' #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)
def testShip(rlepatt, rule, maxgen=2000): # Clear the layer and place the ship r = g.getrect() if rlepatt: patt = g.parse(rlepatt) # If rlepatt is in a multistate representation then patt will be # a multistate cell list. testShip() only works for ships in two # state rules, so convert to two state cell list. if (len(patt) % 2): # This assumes all cells have non-zero state - which is reasonable # for the results of g.parse() patt = [patt[i] for j, i in enumerate(patt[:-1]) if (j + 1) % 3] else: # Use the current pattern if not r: return (0, tuple()) patt = g.getcells(r) patt = g.transform(patt, -r[0], -r[1]) # g.note(str((rlepatt, rule))) if r: g.select(r) g.clear(0) g.putcells(patt) # g.note(str(len(patt)) + ", " + str(patt)) # rlepatt might be different to the rle representation determined by # giveRLE(), so ensure we have the correct representation testrle = giveRLE(patt) if rule: g.setrule(rule) speed = () startpop = int(g.getpop()) bbox = g.getrect() minpop = startpop minbboxarea = bbox[2] * bbox[3] mingen = 0 # Keep track of the total bbox maxx = bbox[2] maxy = bbox[3] maxpop = startpop # Ignore ship if rule is not a 2-state rule if not g.numstates() == 2: return (minpop, speed) for ii in xrange(maxgen): g.run(1) r = g.getrect() if not r: # Pattern has died out and is therefore not a ship mingen = 0 break pop = int(g.getpop()) bboxarea = r[2] * r[3] if pop < minpop: # Find phase with minimimum population minpop = pop minbboxarea = r[2] * r[3] mingen = ii + 1 elif pop == minpop: # Amongst phases with min pop, find one with minimum bbox area # bboxarea = r[2]*r[3] if bboxarea < minbboxarea: minbboxarea = bboxarea mingen = ii + 1 # Track the bounding box of the pattern's evolution maxx = max(maxx, r[2]) maxy = max(maxy, r[3]) maxpop = max(maxpop, pop) if (pop == startpop and r[2:4] == bbox[2:4]): if (giveRLE(g.getcells(r)) == testrle): # Starting ship has reappeared speed = (r[0] - bbox[0], r[1] - bbox[1], ii + 1 ) # displacement and period break # Check for rotated pattern elif (pop == startpop and r[2:4] == bbox[3:1:-1]): # For 2-cell oscillators this is sufficient if minpop == 2: speed = (0, 0, 2 * (ii + 1)) mingen = ii + 1 break g.run(mingen) # Evolve ship to generation with minimum population # return (minpop, speed) # return (minpop, speed, maxpop) return (minpop, speed, maxx * maxy)
def CreateWssMovementData(recipes, dir, isUp = True): result = [] for i in xrange(0, len(recipes.WssCreator)): recipes.Reset() if isUp: recipes.Goto(-23, 1) recipes.AddWss(i) PlaceReadingHeads(recipes.recipe) if isUp: gen = period * (len(recipes.recipe) + 10) while gen % (2 * distForward) != 0: gen += 1 goto(gen) g.fit() g.update() rect = g.getrect() g.select([rect[0], -6 * distBack, rect[2], 7 * distBack]) g.clear(1) x, y, res = FindWssByDirection(isUp, distForward)[0] x += 23 y += -21 y = y % distForward else: gen = period * (len(recipes.recipe) + 10) while gen % (2 * distBack) != 0: gen += 1 goto(gen) g.fit() g.update() rect = g.getrect() helixy = CalcHelix(recipes.recipe) g.select([rect[0], helixy - distBack, rect[2], 7 * distBack]) g.clear(1) x, y, res = FindWssByDirection(isUp, distBack)[0] y = y % distBack result.append((x, y, res)) if isUp: pickle.dump(result, open(path.join(dir, str(step) + "_" + str(period) + "_ForwardWssBaseAuto.pkl"), "wb")) else: pickle.dump(result, open(path.join(dir, str(step) + "_" + str(period) + "_BackwardWssBaseAuto.pkl"), "wb")) recipes.Reset()
def CreateWssMovementData(recipes, dir, isUp=True): result = [] for i in xrange(0, len(recipes.WssCreator)): recipes.Reset() if isUp: recipes.Goto(-23, 1) recipes.AddWss(i) PlaceReadingHeads(recipes.recipe) if isUp: gen = period * (len(recipes.recipe) + 10) while gen % (2 * distForward) != 0: gen += 1 goto(gen) g.fit() g.update() rect = g.getrect() g.select([rect[0], -6 * distBack, rect[2], 7 * distBack]) g.clear(1) x, y, res = FindWssByDirection(isUp, distForward)[0] x += 23 y += -21 y = y % distForward else: gen = period * (len(recipes.recipe) + 10) while gen % (2 * distBack) != 0: gen += 1 goto(gen) g.fit() g.update() rect = g.getrect() helixy = CalcHelix(recipes.recipe) g.select([rect[0], helixy - distBack, rect[2], 7 * distBack]) g.clear(1) x, y, res = FindWssByDirection(isUp, distBack)[0] y = y % distBack result.append((x, y, res)) if isUp: pickle.dump( result, open( path.join( dir, str(step) + "_" + str(period) + "_ForwardWssBaseAuto.pkl"), "wb")) else: pickle.dump( result, open( path.join( dir, str(step) + "_" + str(period) + "_BackwardWssBaseAuto.pkl"), "wb")) recipes.Reset()
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(" ")
def update5StoSSS(rleFile, collection): sssFile = rleFile.replace('.txt', '.sss.txt') if sssFile == rleFile: g.exit('Error: failed to create new file name.') updateFile = sssFile.replace('.sss.txt', '.ss2.txt') shipDict = {} newSpeeds, updateSpeeds = set(), set() global updateShips global newShipsList header = '' status = 'Importing 5S %s collection from file: %s ...' % \ (collectionNames[collection], rleFile) N = 0 with open(sssFile) as fIn: for line in fIn: # Trust the data in the sss file, no need to test ships ship = sss.parseshipstr(line) if not ship: # Should only get here if the line was empty, or is a comment if (line and (not line[0] == '#')): g.note('Ignoring line:\n\n' + line) header += line continue speed = ship[2:5] shipDict[speed] = ship N += 1 if (N % 500 == 0): g.show('%s %d ships found.' % (status, N)) status = '5S %s collection imported, %d ships found. Testing %d new ships ...' % \ (collectionNames[collection], N, len(newShipsList)) g.show(status) N = 0 # New ship counter NN = 0 # New ship of current type counter for newship in newShipsList: minpop, rulestr, dx, dy, period, shiprle = newship dy, dx = sss.minmaxofabs((dx, dy)) if dx == 0: continue # oscillator if dy == 0: shiptype = 'o' elif dy == dx: shiptype = 'd' else: shiptype = 'k' # g.note(str((minpop, rulestr, dx, dy, period, shiprle, shiptype, newship))) if shiptype == collection: bUpdate = True speed = (dx, dy, period) # Replace current ship in collection if minimum population is reduced # or add the smallest (by minpop and bbox) ship for each new speed if speed in shipDict: if minpop < shipDict[speed][0]: if speed not in newSpeeds: updateSpeeds.add(speed) elif minpop == shipDict[speed][0]: # If the speed is not yet in the collection then make sure # to update with the ship that has the smallest bounding box # as well as the lowest minpop if speed in newSpeeds: # Check bounding box areas g.select([-1, -1, 1, 1]) g.clear(1) g.putcells(g.parse(shipDict[speed][5])) r = g.getrect() bbox = r[2] * r[3] g.select([-1, -1, 1, 1]) g.clear(1) g.putcells(g.parse(shiprle)) r = g.getrect() if bbox <= (r[2] * r[3]): bUpdate = False else: bUpdate = False else: bUpdate = False else: # New speed newSpeeds.add(speed) if bUpdate: # Canonise ship and update collection shipDict[speed] = sss.canon5Sship(newship) NN += 1 N += 1 if (N % 100 == 0): found = len(newSpeeds) + len(updateSpeeds) g.show('%s %d record ships found of %d/%d ships tested.' % (status, found, NN, N)) # Convert to list and sort # ship format: (minpop, 'rulestr', dx, dy, period, 'shiprle') # For orthogonal and diagonal: sort order is first by period, then decreasing displacement # For oblique: sort order is first by slope, then period - specifically first dx, then dy, then period # if collection == 'k': # shipList = sorted(shipDict.values(), key=lambda x: (x[2], x[3], x[4])) # newSpeeds = sorted(newSpeeds, key=lambda x: (x[0], x[1], x[2])) # updateSpeeds = sorted(updateSpeeds, key=lambda x: (x[0], x[1], x[2])) # else: # shipList = sorted(shipDict.values(), key=lambda x: (x[4], -x[2])) # newSpeeds = sorted(newSpeeds, key=lambda x: (x[2], -x[0])) # updateSpeeds = sorted(updateSpeeds, key=lambda x: (x[2], -x[0])) # Sort order now consistent for all three collections: # First by period, then decreasing X displacement, then decreasing Y displacement shipList = sorted(shipDict.values(), key=lambda x: (x[4], -x[2], -x[3])) newSpeeds = sorted(newSpeeds, key=lambda x: (x[2], -x[0], -x[1])) updateSpeeds = sorted(updateSpeeds, key=lambda x: (x[2], -x[0], -x[1])) # Write ships to file if (newSpeeds or updateSpeeds): g.show('Writing to SSS file: ' + updateFile) with open(updateFile, 'w') as fOut: fOut.write(header) for ship in shipList: fOut.write(', '.join(map(str, ship))+'\n') if UPDATE: try: # Update the current project file os.remove(sssFile) os.rename(updateFile, sssFile) except: g.exit('Error updating SSS file: ' + sssFile) # Return list of new and updated speeds and update list of ships added to database updateShips += [shipDict[speed] for speed in itertools.chain(newSpeeds, updateSpeeds)] return (newSpeeds, updateSpeeds)
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 main (): g.update () g.check (False) path = g.getstring ("Output directory:") files = glob.glob (os.path.join (path, "*.out")) mingls = g.getstring ("Min number of gliders at accept:") if mingls == "": mingl = 0 minpop = 0 maxpop = 1024 else: mingl = int (mingls) minpops = g.getstring ("Min population except catalyzers:") if minpops == "": minpop = 0 maxpop = 1024 else: minpop = int (minpops) maxpop = int (g.getstring ("Max population except catalyzers:")) if g.getname () != "catbellman_temp": g.addlayer () hashdir = {} catlist = [] catix = 0 g.new ("catbellman_temp") g.setrule ("LifeBellman") for fix, filename in enumerate (files): patt = g.getrect () if patt != []: g.select (patt) g.clear (0) g.setgen ("0") with open(filename, 'r') as f: filetext = f.read () if fix % 16 == 0: g.show ("Analysing " + str (fix) + "/" + str (len (files))) (gogen, glcnt) = convbellman (filetext, 0, 0) if gogen == -1: gogen = 128 (use, hash) = analyse (gogen, glcnt, minpop, maxpop, mingl) if use: if not hash in hashdir: catlist.append ([]) hashdir [hash] = catix catix += 1 cat = hashdir [hash] catlist [cat].append (filetext) g.new ("catbellman_temp") g.setrule ("LifeBellman") fix = 0 y = 0 for cat in catlist: x = 96 * (len (cat) - 1) for filetext in cat: convbellman (filetext, x, y) x -= 96 fix += 1 if fix % 32 == 0: g.show ("Rendering " + str (fix) + "/" + str (len (files))) g.fit () g.check (True) g.update () g.check (False) y += 96 g.show ("Done") g.fit () g.setstep (-1) g.check (True)
''' setconf2.py clears grid and sets just as specified by configuration conf2 in parameters.py ''' import parameters reload(parameters) from parameters import conf2, nstates from golly import setcell, clear, select, getrect, fit, show if len(getrect()) > 0: select(getrect()) clear(0) for i in range(0,len(conf2),2): c = conf2[i] if i+1 < len(conf2): c += conf2[i+1] * nstates setcell(i//2,0,c) show(str(i)) select([]) fit()
def sof_canonise(duration, dxdy): sof = '' moving = 's' # Stationary # For spaceships the pattern needs to be oriented in the standard direction # N, NW, or in between. if not dxdy == (0, 0): dx, dy = dxdy if abs(dx) > abs(dy): a, b, c, d = 0, -sign(dy), -sign(dx), 0 else: a, b, c, d = -sign(dx), 0, 0, -sign(dy) rect = g.getrect() ship = g.getcells(rect) g.select(rect) g.clear(0) g.putcells(ship, 0, 0, a, b, c, d) dx, dy = (dx * a + dy * b, dx * c + dy * d) if dx == 0: moving = 'o' # Orthogonal elif dx == -dy: moving = 'd' # Diagonal else: moving = 'k' # Oblique # We need to compare each phase to find the one used to determine the # pattern's standard form. The standard form is selected from a phase # with the minimum population minpop = int(g.getpop()) if (duration > 1): for t in range(duration): minpop = min(minpop, int(g.getpop())) g.run(1) if minpop == 0: return '0' for t in range(duration): if int(g.getpop()) == minpop: rect = g.getrect() ox = rect[0] oy = rect[1] x_length = rect[2] y_breadth = rect[3] # Choose the orientation which comes first according to sof comparison rules: sof = sof_compare(sof, sof_representation(x_length, y_breadth, ox, oy, 1, 0, 0, 1)) # Identity if moving in ('s', 'o'): sof = sof_compare(sof, sof_representation(x_length, y_breadth, ox + x_length - 1, oy, -1, 0, 0, 1)) # flip_x if moving in ('s', 'd'): sof = sof_compare(sof, sof_representation(y_breadth, x_length, ox + x_length - 1, oy + y_breadth - 1, 0, -1, -1, 0)) # swap_xy_flip if moving == 's': sof = sof_compare(sof, sof_representation(x_length, y_breadth, ox, oy + y_breadth - 1, 1, 0, 0, -1)) # flip_y sof = sof_compare(sof, sof_representation(x_length, y_breadth, ox + x_length - 1, oy + y_breadth - 1, -1, 0, 0, -1)) # 180 sof = sof_compare(sof, sof_representation(y_breadth, x_length, ox, oy, 0, 1, 1, 0)) # swap_xy sof = sof_compare(sof, sof_representation(y_breadth, x_length, ox + x_length - 1, oy, 0, -1, 1, 0)) # cw 90 sof = sof_compare(sof, sof_representation(y_breadth, x_length, ox, oy + y_breadth - 1, 0, 1, -1, 0)) # ccw 90 if (duration > 1): g.run(1) return sof