def reconstruct(gstr, stepback=2): """Reconstruct a pattern representing a glider set from its (canonical) string. The transformation is assumed to be the identity. Returns a single Golly cell list with all gliders at <stepback> gen prior to canonical time. """ fields, at, trans_str = gstr.partition("@") res = [] glider = g.parse("bo$2bo$3o") # SE # Process transformation # XXX unimplemented (but not required here) t, o, shift_x, shift_y = 0, "identity", 0, 0 # Step back to separate gliders (same as Shinjuku uses for realising syntheses) t += stepback # Process glider sets for i, field in enumerate(gstr.split("/")): salvo = [] for (time, lane) in zip(*[iter(field.split())] * 2): time, lane = - int(time) - t - 4, int(lane) dist, time = time // 4, time % 4 salvo += g.evolve(g.transform(glider, dist, dist - lane), time) if i == 1: salvo = g.transform(salvo, 0, 0, r270[0], r270[1], r270[2], r270[3]) # "rot270" elif i == 2: salvo = g.transform(salvo, 0, 0, r180[0], r180[1], r180[2], r180[3]) # "rot180" elif i == 3: salvo = g.transform(salvo, 0, 0, r90[0], r90[1], r90[2], r90[3]) # "rot90" res += salvo return g.transform(res, shift_x, shift_y)
def get_patterns(cells, period): if not cells: return # calculate where the gliders first hit the pattern min_lane = 99999 for i in range(0, len(cells), 2): if LANE1 - 3 <= cells[i] + cells[i+1] <= LANE2 + 6: min_lane = min(min_lane, cells[i] - cells[i+1]) if min_lane == 99999: return minx = min_lane // 2 g1 = g.transform(G1, minx, -minx) g2 = g.transform(G2, minx, -minx) # Singletons for t in range(period): yield cells + g.evolve(g1, t), t, None yield cells + g.evolve(g2, t), None, t # Pairs for phase in range(period): yield cells + g1 + g2, phase, phase tg1 = g1 tg2 = g2 for t in range(1, MAX_DIFF + 1): tg1 = g.transform(g.evolve(tg1, 3), -1, 1) tg2 = g.transform(g.evolve(tg2, 3), -1, 1) yield cells + g1 + tg2, phase, phase - t yield cells + tg1 + g2, phase - t, phase g1 = g.evolve(g1, 1) g2 = g.evolve(g2, 1)
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 getorientation(clist, orientation): A, B, C, D = xformlist[orientation] minx, miny = findTL(g.transform(clist, 0, 0, *xformlist[orientation])) # return a pattern offset by the correct distance from the base pattern, # accounting for the location of the TL corner in the original phase -- # -- but return the actual _pattern_ normalized to (0,0)! newlist = cellsort(g.transform(clist, -minx, -miny, A, B, C, D)) return [newlist, [-minx, -miny, A, B, C, D]]
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 lookforkeys(event): global oldcells, object # look for keys used to flip/rotate object if event == "key x none" or event == "key y none": # flip floating object left-right or top-bottom g.putcells(object, 0, 0, 1, 0, 0, 1, "xor") # erase object if len(oldcells) > 0: g.putcells(oldcells) obox = getminbox(object) if event == "key x none": # translate object so that bounding box doesn't change xshift = 2 * (obox.left + int(obox.wd//2)) if obox.wd % 2 == 0: xshift -= 1 object = g.transform(object, xshift, 0, -1, 0, 0, 1) else: # translate object so that bounding box doesn't change yshift = 2 * (obox.top + int(obox.ht//2)) if obox.ht % 2 == 0: yshift -= 1 object = g.transform(object, 0, yshift, 1, 0, 0, -1) oldcells = underneath(object) g.putcells(object) g.update() return if event == "key > none" or event == "key < none": # rotate floating object clockwise or anticlockwise # about the center of the object's bounding box obox = getminbox(object) midx = obox.left + int(obox.wd//2) midy = obox.top + int(obox.ht//2) newleft = midx + obox.top - midy newtop = midy + obox.left - midx rotrect = [ newleft, newtop, obox.ht, obox.wd ] if not rectingrid(rotrect): g.show("Rotation is not allowed if object would be outside grid.") return g.putcells(object, 0, 0, 1, 0, 0, 1, "xor") # erase object if len(oldcells) > 0: g.putcells(oldcells) if event == "key > none": # rotate clockwise object = g.transform(object, 0, 0, 0, -1, 1, 0) else: # rotate anticlockwise object = g.transform(object, 0, 0, 0, 1, -1, 0) # shift rotated object to same position as rotrect obox = getminbox(object) object = g.transform(object, newleft - obox.left, newtop - obox.top) oldcells = underneath(object) g.putcells(object) g.update() return if event == "key h none": # best not to show Help window while dragging object! return g.doevent(event)
def lookforkeys(event): global oldcells, object # look for keys used to flip/rotate object if event == "key x none" or event == "key y none": # flip floating object left-right or top-bottom g.putcells(object, 0, 0, 1, 0, 0, 1, "xor") # erase object if len(oldcells) > 0: g.putcells(oldcells) obox = getminbox(object) if event == "key x none": # translate object so that bounding box doesn't change xshift = 2 * (obox.left + int(obox.wd/2)) if obox.wd % 2 == 0: xshift -= 1 object = g.transform(object, xshift, 0, -1, 0, 0, 1) else: # translate object so that bounding box doesn't change yshift = 2 * (obox.top + int(obox.ht/2)) if obox.ht % 2 == 0: yshift -= 1 object = g.transform(object, 0, yshift, 1, 0, 0, -1) oldcells = underneath(object) g.putcells(object) g.update() return if event == "key > none" or event == "key < none": # rotate floating object clockwise or anticlockwise # about the center of the object's bounding box obox = getminbox(object) midx = obox.left + int(obox.wd/2) midy = obox.top + int(obox.ht/2) newleft = midx + obox.top - midy newtop = midy + obox.left - midx rotrect = [ newleft, newtop, obox.ht, obox.wd ] if not rectingrid(rotrect): g.warn("Rotation is not allowed if object would be outside grid.") return g.putcells(object, 0, 0, 1, 0, 0, 1, "xor") # erase object if len(oldcells) > 0: g.putcells(oldcells) if event == "key > none": # rotate clockwise object = g.transform(object, 0, 0, 0, -1, 1, 0) else: # rotate anticlockwise object = g.transform(object, 0, 0, 0, 1, -1, 0) # shift rotated object to same position as rotrect obox = getminbox(object) object = g.transform(object, newleft - obox.left, newtop - obox.top) oldcells = underneath(object) g.putcells(object) g.update() return if event == "key h none": showhelp2() return g.doevent(event)
def form(celllist, num): if num not in xrange(8): return celllist if num >= 4: celllist = g.transform(celllist, 0, 0, -1, 0, 0, -1) num -= 4 if num >= 2: celllist = g.transform(celllist, 0, 0, 0, 1, -1, 0) num -= 2 if num >= 1: celllist = g.transform(celllist, 0, 0, -1, 0, 0, 1) return celllist
def deform(celllist, num): if num not in xrange(8): return celllist if num % 2 == 1: celllist = g.transform(celllist, 0, 0, -1, 0, 0, 1) num = num / 2 if num % 2 == 1: celllist = g.transform(celllist, 0, 0, 0, -1, 1, 0) num = num / 2 if num % 2 == 1: celllist = g.transform(celllist, 0, 0, -1, 0, 0, -1) num -= 4 return celllist
def __init__(self): self.signalsFullData = [] self.signals = [] self.components = [g.parse("bo$2bo$3o!", -1, -1)] for idx in xrange(0, len(self.components)): comp = self.components[idx] for i in xrange(-1, 2, 2): for j in xrange(-1, 2, 2): for k in xrange(0, 4): self.signalsFullData.append((g.transform(g.evolve(comp, k), 0, 0, i, 0, 0, j), i, j, k, idx)) self.signals.append(g.transform(g.evolve(comp, k), 0, 0, i, 0, 0, j))
def Add(self, logicPat): for t in self.transList: dxx, dxy, dyx, dyy = t cells = g.transform(logicPat.cells, 0, 0, dxx, dxy, dyx, dyy) if dxx == 0: cells = g.transform(g.evolve(cells, 2), -dxy, 0) inT = TrnasformDirectionList(logicPat.inputs, t) outT = TrnasformDirectionList(logicPat.outputs, t) p = logicPat.period pat = NewLogicalPattern(cells, inT, outT, p, t) self.patterns.append(pat)
def Add(self, logicPat): for t in self.transList: dxx, dxy, dyx, dyy = t cells = g.transform(logicPat.cells,0, 0, dxx, dxy, dyx, dyy) if dxx == 0: cells = g.transform(g.evolve(cells, 2), -dxy, 0) inT = TrnasformDirectionList(logicPat.inputs, t) outT = TrnasformDirectionList(logicPat.outputs, t) p = logicPat.period pat = NewLogicalPattern(cells, inT, outT, p, t) self.patterns.append(pat)
def makerecipe(recipe): clist = gliderlist[0] totaltime=0 for i in recipe[1:]: totaltime+=i clist=g.join(clist,g.transform(gliderlist[totaltime%4],totaltime/4,totaltime/4)) return clist
def __init__(self): self.signalsFullData = [] self.signals = [] self.components = [g.parse("bo$2bo$3o!", -1, -1)] for idx in xrange(0, len(self.components)): comp = self.components[idx] for i in xrange(-1, 2, 2): for j in xrange(-1, 2, 2): for k in xrange(0, 4): self.signalsFullData.append( (g.transform(g.evolve(comp, k), 0, 0, i, 0, 0, j), i, j, k, idx)) self.signals.append( g.transform(g.evolve(comp, k), 0, 0, i, 0, 0, j))
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 delay_construction(obj_list, delay): pat = [] phase = -delay % 4 n = (delay + phase) // 4 for cells, dx, dy in obj_list: pat += g.transform(g.evolve(cells, phase), -n * dx, -n * dy) return pat
def SaveWss(file): g.setrule("b3/s23") wss = [g.parse("bobo$4bo$o3bo$o3bo$4bo$bo2bo$2b3o!"), g.parse("bobo$4bo$o3bo$4bo$bo2bo$2b3o!"), g.parse("obo$3bo$3bo$o2bo$b3o!")] wssList = [] for w in wss: for i in xrange(0, 4): wssList.append(PrepareList(g.evolve(w, i))) wssList.append(PrepareList(g.transform(g.evolve(w, i), 0, 0, 1, 0, 0, -1))) pickle.dump(wssList, open(path.join(g.getdir("data"),file), "wb"))
def findglider(clist): canonical = g.transform(clist, -clist[0], -clist[1]) canoncoords = list(zip(canonical[0::2], canonical[1::2])) for key in gdict: glist = g.transform(gdict[key], -gdict[key][0], -gdict[key][1]) gcoords = list(zip(glist[0::2], glist[1::2])) match = 1 for coord in gcoords: if coord not in canoncoords: match = 0 break if match == 1: for coord in gcoords: # remove the matching glider canoncoords.remove(coord) # return UL bounding box corner of matching glider x, y = min(glist[0::2]) + clist[0], min(glist[1::2]) + clist[1] dir, phase = key[:2], int(key[2]) outlist = [] for a, b in canoncoords: outlist += [a, b] return [dir, phase, x, y], g.transform(outlist, clist[0], clist[1])
def GetObjectArray(iniobj): result = [] transList = GetTransList() period = FindPeriod(iniobj[0]) for i in xrange(0, period): obj = g.evolve(iniobj[0], i) for t in transList: dxx, dxy, dyx, dyy = t curobj = g.transform(obj, 0, 0, dxx, dxy, dyx, dyy) result.extend(GetObjectClickArray(curobj, iniobj[1], t, period)) return result
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 SaveWss(file): g.setrule("b3/s23") wss = [ g.parse("bobo$4bo$o3bo$o3bo$4bo$bo2bo$2b3o!"), g.parse("bobo$4bo$o3bo$4bo$bo2bo$2b3o!"), g.parse("obo$3bo$3bo$o2bo$b3o!") ] wssList = [] for w in wss: for i in xrange(0, 4): wssList.append(PrepareList(g.evolve(w, i))) wssList.append( PrepareList(g.transform(g.evolve(w, i), 0, 0, 1, 0, 0, -1))) pickle.dump(wssList, open(path.join(g.getdir("data"), file), "wb"))
def get_invariants(cells): invariants = [] for t in range(0, 4): gliders = [] temp_cells = cells[:] for gen in range(0, 4): gliders.extend([coords + (gen,) for coords in find_all_gliders(temp_cells)]) temp_cells = g.evolve(temp_cells, 1) glider_pairs = combinations(gliders, 2) invariants.extend([item for pair in glider_pairs for item in compute_invariants(pair)]) cells = g.transform(cells, 0, 0, 0, -1, 1, 0) seen = set() return [ item for item in invariants if item not in seen and not seen.add(item) ]
def Goto(self, x, y, moveTable, expected, maxL): dx = x - self.block0[0] dy = y - self.block0[1] for i in xrange(0, len(moveTable)): if len(moveTable[i][2]) >= maxL: break x1 = moveTable[i][0] y1 = moveTable[i][1] if x1 == dx and y1 == dy: if self.CanApplyRecipe(moveTable[i][2], g.transform(expected, x1, y1)): self.AppendRecipe(moveTable[i][2]) self.block0[0] = x self.block0[1] = y self.lastGotoIdx = i return True return False
def test(pat, gen, loc, x, y): global results if not all(g.getcell(x + loc, y) for x, y in on_cells): return if any(g.getcell(x + loc, y) for x, y in off_cells): return begin = start_cells + g.evolve(g.transform(pat, -x, -y), gen) if finalpop >= 0 and len(g.evolve(begin, 100)) != 2 * finalpop: return results += 1 g.setlayer(results_layer) g.putcells(g.evolve(pat, gen % 8), 50 * results - x, -y) g.putcells(begin, 50 * results, 50) g.putcells(g.evolve(begin, delay), 50 * results, 100) g.setlayer(work_layer)
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 get_invariants(cells): invariants = [] for t in range(0, 4): gliders = [] temp_cells = cells[:] for gen in range(0, 4): gliders.extend( [coords + (gen, ) for coords in find_all_gliders(temp_cells)]) temp_cells = g.evolve(temp_cells, 1) glider_pairs = combinations(gliders, 2) invariants.extend([ item for pair in glider_pairs for item in compute_invariants(pair) ]) cells = g.transform(cells, 0, 0, 0, -1, 1, 0) seen = set() return [ item for item in invariants if item not in seen and not seen.add(item) ]
def get_g0(lane): x = lane // 2 - 5 glider = g.transform(G_NE, x, lane - x) return g.evolve(glider, 2 * (1 + lane % 2))
Brle = Srle = "b10$b10$b26$b10$b10$b26$b10$b10$b!" for ch in Bvalues: ind = 32 - int(ch) * 4 # because B and S values are highest at the top! Brle = Brle[:ind] + "o" + Brle[ind + 1:] for ch in Svalues: ind = 32 - int(ch) * 4 Srle = Srle[:ind] + "o" + Srle[ind + 1:] RuleBits = pattern(Brle, 148, 1404) + pattern(Srle, 162, 1406) # load or generate the OFFcell tile: OFFcellFileName = g.getdir("data") + "metapixel-OFF.rle" ONcellFileName = g.getdir("data") + "metapixel-ON.rle" if os.access(OFFcellFileName, os.R_OK) and os.access(ONcellFileName, os.R_OK): g.show("Opening metapixel-OFF and metapixel-ON from saved pattern file.") OFFcell = pattern(g.transform(g.load(OFFcellFileName), -5, -5, 1, 0, 0, 1)) ONcell = pattern(g.transform(g.load(ONcellFileName), -5, -5, 1, 0, 0, 1)) else: g.show("Building OFF metacell definition...") # slide #21: programmables -------------------- LWSS = pattern("b4o$o3bo$4bo$o2bo!", 8, 0) DiagProximityFuse = pattern( """ bo$obo$bo2$4b2o$4b2o$59b2o$59b2o3$58b2o2b2o$9b2o3bo5bo5bo5bo5bo5bo5bo 7b2o2b2o$9bo3bobo3bobo3bobo3bobo3bobo3bobo3bobo$10bo2bo2bo2bo2bo2bo2bo 2bo2bo2bo2bo2bo2bo2bo2bo$11bobo3bobo3bobo3bobo3bobo3bobo3bobo3bo5b2o$ 12bo5bo5bo5bo5bo5bo5bo5bo3bobo$55bo2bo$56bobo$57bo! """, -5, -5)
Brle = Srle = "b10$b10$b26$b10$b10$b26$b10$b10$b!" for ch in Bvalues: ind = 32-int(ch)*4 # because B and S values are highest at the top! Brle = Brle[:ind] + "o" + Brle[ind+1:] for ch in Svalues: ind = 32-int(ch)*4 Srle = Srle[:ind] + "o" + Srle[ind+1:] RuleBits = pattern(Brle, 148, 1404) + pattern(Srle, 162, 1406) # load or generate the OFFcell tile: OFFcellFileName = g.getdir("data") + "metapixel-OFF.rle" ONcellFileName = g.getdir("data") + "metapixel-ON.rle" if os.access(OFFcellFileName, os.R_OK) and os.access(ONcellFileName, os.R_OK): g.show("Opening metapixel-OFF and metapixel-ON from saved pattern file.") OFFcell = pattern(g.transform(g.load(OFFcellFileName),-5,-5,1,0,0,1)) ONcell = pattern(g.transform(g.load(ONcellFileName),-5,-5,1,0,0,1)) else: g.show("Building OFF metacell definition...") # slide #21: programmables -------------------- LWSS = pattern("b4o$o3bo$4bo$o2bo!", 8, 0) DiagProximityFuse = pattern(""" bo$obo$bo2$4b2o$4b2o$59b2o$59b2o3$58b2o2b2o$9b2o3bo5bo5bo5bo5bo5bo5bo 7b2o2b2o$9bo3bobo3bobo3bobo3bobo3bobo3bobo3bobo$10bo2bo2bo2bo2bo2bo2bo 2bo2bo2bo2bo2bo2bo2bo2bo$11bobo3bobo3bobo3bobo3bobo3bobo3bobo3bo5b2o$ 12bo5bo5bo5bo5bo5bo5bo5bo3bobo$55bo2bo$56bobo$57bo! """, -5, -5)
def __call__(self, x, y, A = identity): """The same as 'apply(A).translate(x, y)'.""" return pattern(golly.transform(self, x, y, *A))
# -------------------------------------------------------------------- ########################### def makeRLEline(pat): return giveRLE(list(itertools.chain(*pat))) patdict = {} objlist = [] for i in range(len(objs)): # normalize so that the first ON cell in the list is always (0,0) templist = g.parse(objs[i]) objlist += [g.transform(templist, -templist[0], -templist[1])] numobjs = len(objlist) zonelist = [] for item in objlist: g.setrule("B12345678/S012345678") neighbors = g.evolve(item, 1) g.setrule("B12345678/S012345678" ) ######### this is "B2345678/S012345678" for Conway's Life zone = g.evolve(neighbors, 1) zonelist += [zone] # includes cells for object also g.setrule("LifeHistory") nearlist = [[i, j] for i in range(-1, xsize + 1) for j in range(-1, ysize + 1) if i < 0 or i >= xsize or j < 0 or j >= ysize] count, x, y, ptr, filledlist, searchlist = 0, 0, 0, 0, [], [] while y == 0 or len(searchlist) > 0:
#Get the Value of gun which should be the only thing present in the current Document #Make sure you've saved your work. This script deletes history. #This script is made to evaluate glider gun value easier. #Written by Michael Simkin 2014 import golly as g import glob '''Number Placement''' snakeLineHor = g.parse("2obob2obo$ob2obob2o!") snakeLineVer = g.transform(snakeLineHor, -3, 3, 0, 1, 1, 0) figure8 = [snakeLineVer, g.transform(snakeLineVer, 0, 13), snakeLineHor, g.transform(snakeLineHor, 0, 13), g.transform(snakeLineHor, 0, 26), g.transform(snakeLineVer, 13, 0), g.transform(snakeLineVer, 13, 13)] def PlaceDigit(digit, x = 0, y = 0): digitIdx = [[0,1,2,4,5,6], [5,6],[1,2,3,4,5],[2,3,4,5,6],[0,3,5,6],[0,2,3,4,6],[0,1,2,3,4,6],[2,5,6],[0,1,2,3,4,5,6],[0,2,3,4,5,6]] if digit >= 0 and digit <= 9: for idx in digitIdx[digit]: g.putcells(figure8[idx], x, y) def NumDigit(num): if num < 10: return 1 else: return 1 + NumDigit(int((num - (num % 10))/10)) def PlaceNumber(number, x = 0, y = 0): if number < 0: g.putcells(figure8[3], x, y) PlaceNumber(-number, x, y) return
def DevolveGlider(glider, delta): return g.evolve(g.transform(glider, -delta, -delta), 3 * delta)
parity=1 if s[0]=="O" else 0 input+=[[int(s[1:]),parity]] for i,p in input: if elbowloc%2==0: # which recipe to use depends on current elbow chirality targetlane = i else: targetlane = -i if elbowloc<-48: # -32 doesn't work for the end of the recipe move,recipe,parity = posdict[targetlane] else: move,recipe,parity = negdict[targetlane] elbowloc+=move adjustedrecipe = recipe[2:] # skip the initial "0" # g.note(str([targetlane, move, recipe, parity])) if (total+parity+p)%2==1: # change the last number in the previous recipe, to flip the parity of the current recipe output[-1]+=1 total+=1 # now add the current recipe to the total for s in adjustedrecipe.split(","): total+=int(s) output+=eval("["+adjustedrecipe+"]") # build the resulting recipe and display in a new layer g.setclipstr(str(output).replace("["," ").replace("]","").replace(" ","")) pat=makerecipe(output[:-1]) g.addlayer() g.putcells(g.join(elbow,g.transform(pat,5,2))) g.setalgo("HashLife")
def f(cells): return g.evolve(g.transform(cells, 1, 2, 0, -1, -1, 0), 2)
patnames = f.readlines() f.close() matchtype = 0 for name in patnames: tickstorun = 0 basename = removecomments(name) temp = basename.split(" ") if len(temp) == 2: basename, tickstorun = temp if len(temp) == 3: basename, tickstorun, matchtype = temp base = g.load(libpath + basename + ".rle") # oddly, g.load() doesn't pay attention to CXRLE -- it just # loads the pattern at (0,0). So we have to normalize anyway...! offx, offy = findTL(base) base = g.transform(base, -offx, -offy) # move upper left live cell to (0,0) writepatdef( basename, base ) #TODO: write script in two phases, including only patterns actually used g.show("Loading pattern '" + basename + "' into memory.") n, p, x, o, t = getallorientations(basename, base, int(tickstorun), int(matchtype)) namelist += n patlist += p xformlist += x orientlist += o ticklist += t remainder = g.getcells(g.getrect()) while len(remainder): matchflag = 0
def moveobject(): global oldcells, object, object1 # wait for 1st click in live cell 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() result = findlivecell(int(xstr), int(ystr)) if len(result) > 0: prevx = int(xstr) prevy = int(ystr) oldmouse = xstr + ' ' + ystr g.show("Extracting object...") x, y = result object = getobject(x, y) object1 = list(object) # save in case user aborts script if mods == "alt": # don't delete object oldcells = list(object) break else: g.warn("Click on or near a live cell belonging to the desired object.") elif event == "key h none": showhelp1() else: g.doevent(event) # wait for 2nd click while moving object 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) mousepos = g.getxy() if len(mousepos) > 0 and mousepos != oldmouse: # mouse has moved, so move object g.putcells(object, 0, 0, 1, 0, 0, 1, "xor") # erase object if len(oldcells) > 0: g.putcells(oldcells) xstr, ystr = mousepos.split() x = int(xstr) y = int(ystr) if g.getwidth() > 0: # ensure object doesn't move beyond left/right edge of grid obox = getminbox( g.transform(object, x - prevx, y - prevy) ) if obox.left < gridl: x += gridl - obox.left elif obox.right > gridr: x -= obox.right - gridr if g.getheight() > 0: # ensure object doesn't move beyond top/bottom edge of grid obox = getminbox( g.transform(object, x - prevx, y - prevy) ) 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()
91, 90, 116, 90, 113, 90 ] # 7move-29 -- widen the space between the two elbows # The final number in each recipe below represents the amount of time that must elapse # before another recipe can be safely appended. # To string recipes together, remove all leading "0"s except for the first, and # remove the final number from the last recipe to avoid a pi explosion at the end # (or append the elbowdestroy recipe to delete the elbow block completely). g.addlayer() g.setrule("LifeHistory") g.putcells(g.transform(elbow, -5, -2)) g.setstep(4) g.fit() g.setmag(1) makerecipe(recipe) """ # Sample recipes from slmake repository: https://gitlab.com/apgoucher/slmake/blob/master/data/simeks/pp.txt recipe = [0, 109, 90, 93, 91, 90, 90, 90, 90] # elbowdestroy # elbow duplicators recipe = [0, 109, 91, 93, 91, 127, 91, 90, 145, 91, 90, 90, 146, 90, 91, 91, 92, 90] # 7move9 7move-7 recipe = [0, 109, 90, 93, 91, 91, 90, 90, 100, 90, 90, 146, 96, 90, 90, 90, 92, 156, 144, 90] # 7move19 0move-12 recipe = [0, 109, 91, 94, 91, 91, 128, 126, 90, 152, 91, 176, 125, 90, 90, 90, 91, 90, 90, 108, 90, 99, 90] # 0move-4 0move-30 recipe = [0, 109, 91, 94, 91, 91, 128, 126, 90, 152, 91, 176, 125, 90, 90, 90, 91, 90, 90, 108, 90, 109, 90] # 0move-4 7move-33 recipe = [0, 109, 90, 93, 91, 90, 95, 90, 90, 91, 90, 91, 90, 147, 90, 151, 126, 90, 107, 90, 111, 90, 99, 90] # 0move-18 7move-37
CLEANUP_DEPTH = 1 MAX_POP = [40, 40, 40, 40, 30, 30, 30, 30] GENS = 200 MAX_DIFF = 72 OUTFILE = "/home/user/life/elbow_0hd_%d.txt" % time() def to_pairs(cells): return zip(cells[::2], cells[1::2]) G_NE = g.parse("3o$2bo$bo!") G_NW = g.parse("3o$o$bo!") G_SW = g.transform(g.parse("bo$o$3o!"), 0, -2) G_SE = g.transform(g.parse("bo$2bo$3o!"), -2, -2) LWSS_W = g.transform(g.parse("bo2bo$o$o3bo$4o!"), 0, -1) LWSS_S = g.transform(g.parse("bobo$o$o$o2bo$3o!"), -2, -4) GLIDERS_SW = [to_pairs(g.evolve(G_SW, i)) for i in range(4)] GLIDERS_SE = [to_pairs(g.evolve(G_SE, i)) for i in range(4)] GLIDERS_NW = [to_pairs(g.evolve(G_NW, i)) for i in range(4)] LWSSES_W = [to_pairs(g.evolve(LWSS_W, i)) for i in range(4)] LWSSES_S = [to_pairs(g.evolve(LWSS_S, i)) for i in range(4)] assert all((0, 0) in gl for gl in GLIDERS_SW) assert all((0, 0) in gl for gl in GLIDERS_SE) assert all((0, 0) in gl for gl in GLIDERS_NW) assert all((0, 0) in lwss for lwss in LWSSES_W)
g.exit('Nothing in selection.') if g.getrule() != 'LifeHistory': g.exit('The rule should be in LifeHistory.') # Get catalyst in various positions if g.getselrect() != []: g.shrink() pattern = g.getcells(r) patrlelist = [] translist =[(1,0,0,1), (1,0,0,-1), (-1,0,0,1), (-1,0,0,-1), (0,1,1,0), (0,-1,1,0), (0,1,-1,0), (0,-1,-1,0)] # Get unique transformed patterns for trans in translist: g.new('') g.putcells(g.transform(pattern, 0, 0, *trans)) g.select(g.getrect()) g.copy() patrle = ''.join(g.getclipstr().split('\n')[1:]) if patrle not in patrlelist: patrlelist.append(patrle) patrles = '\n'.join(patrlelist) # Save data to file catpath = g.savedialog('Catalyst File', 'all files(*.*)|*', catdir) try: with open(catpath, 'w') as catfile: catfile.write(patrles) g.exit('Catalyst file successfully generated at {}'.format(catpath)) except: if catpath == '':
if len(sel) == 0: g.exit("Nothing in selection.") if len(sel) % 2: g.exit("Can't do the rewinding trick on multistate rules.") all = g.getcells(g.getrect()) allcoords = [] for i in range(0, len(all), 2): allcoords.append([all[i], all[i + 1]]) # g.show("Processing object library...") odict = dict() for i in range(len(lib)): # g.show("Processing object " + lib[i][0]) # run and normalize each library object until a duplicate of the original pattern appears # The number of ticks to duplication, and the offset, give all the information needed to rewind... obj = g.parse(lib[i][1]) basex, basey, ticks, newobj = obj[0], obj[1], 0, [] baseobj = g.transform(obj, -basex, -basey) basepat = pattern( baseobj) # use glife to avoid having to add a layer in Golly while cmp(baseobj, newobj) != 0: ticks += 1 newpat = basepat[ticks] newlist = list(newpat) newobj = g.transform(newpat, -newlist[0], -newlist[1]) if ticks > 999: g.exit(obj[0] + " in library has no reasonable repeat time.") stridex, stridey = newlist[0], newlist[1] # odict key is name+phase, and there's an entry for each phase of each object # Contains list of repeat, stridex, stridey, dx, dy, clist, envclist. # By convention, the first ON cell in phase 0 is at (0,0) and dx and dy are also 0,0. # The first ON cell in other phases is also 0,0 but dx and dy will be altered appropriately.
def moveobject(): global oldcells, object, object1 # wait for click in or near a live cell 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() result = findlivecell(int(xstr), int(ystr)) if len(result) > 0: prevx = int(xstr) prevy = int(ystr) oldmouse = xstr + ' ' + ystr g.show("Extracting object...") x, y = result object = getobject(x, y) object1 = list(object) # save in case user aborts script if mods == "alt": # don't delete object oldcells = list(object) break else: g.warn("Click on or near a live cell belonging to the desired object.") elif event == "key h none": showhelp() else: g.doevent(event) # wait for mouse-up while moving object g.show("Move mouse and release button...") mousedown = True while mousedown: event = g.getevent() if event.startswith("mup"): mousedown = False elif len(event) > 0: lookforkeys(event) mousepos = g.getxy() if len(mousepos) > 0 and mousepos != oldmouse: # mouse has moved, so move object g.putcells(object, 0, 0, 1, 0, 0, 1, "xor") # erase object if len(oldcells) > 0: g.putcells(oldcells) xstr, ystr = mousepos.split() x = int(xstr) y = int(ystr) if g.getwidth() > 0: # ensure object doesn't move beyond left/right edge of grid obox = getminbox( g.transform(object, x - prevx, y - prevy) ) if obox.left < gridl: x += gridl - obox.left elif obox.right > gridr: x -= obox.right - gridr if g.getheight() > 0: # ensure object doesn't move beyond top/bottom edge of grid obox = getminbox( g.transform(object, x - prevx, y - prevy) ) 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()
for gen in range(0, 4): gliders.extend(find_all_gliders(temp_cells)) temp_cells = g.evolve(temp_cells, 1) if len(gliders) < 2: continue sample = get_glider_color(gliders[0]) if not all([get_glider_color(glider) == sample for glider in gliders[1:]]): continue # check that pattern emits exactly one orthogonal glider new_cells = g.evolve(cells, 700) emitted_gliders = [] for t in range(0, 4): emitted_gliders.append(0) temp_cells = new_cells for gen in range(0, 4): emitted_gliders[-1] += len(find_all_gliders(temp_cells)) temp_cells = g.evolve(temp_cells, 1) new_cells = g.transform(new_cells, 0, 0, 0, -1, 1, 0) if emitted_gliders[0] + emitted_gliders[2] == 0 and emitted_gliders[ 1] + emitted_gliders[3] == 1: outfile.write(line) infile.close() outfile.close()
LANE2 = 5 FULL_DEPTH = 4 CLEANUP_DEPTH = 1 MAX_POP = [40, 40, 40, 40, 30, 30, 30, 30] GENS = 200 MAX_DIFF = 60 OUTFILE = '/home/user/life/outfile%d.txt' % time() def to_pairs(cells): return zip(cells[::2], cells[1::2]) G_NE = g.parse('3o$2bo$bo!') G_NW = g.parse('3o$o$bo!') G_SW = g.transform(g.parse('bo$o$3o!'), 0, -2) G_SE = g.transform(g.parse('bo$2bo$3o!'), -2, -2) LWSS_W = g.transform(g.parse('bo2bo$o$o3bo$4o!'), 0, -1) LWSS_S = g.transform(g.parse('bobo$o$o$o2bo$3o!'), -2, -4) GLIDERS_SW = [to_pairs(g.evolve(G_SW, i)) for i in range(4)] GLIDERS_SE = [to_pairs(g.evolve(G_SE, i)) for i in range(4)] GLIDERS_NW = [to_pairs(g.evolve(G_NW, i)) for i in range(4)] LWSSES_W = [to_pairs(g.evolve(LWSS_W, i)) for i in range(4)] LWSSES_S = [to_pairs(g.evolve(LWSS_S, i)) for i in range(4)] assert(all((0,0) in gl for gl in GLIDERS_SW)) assert(all((0,0) in gl for gl in GLIDERS_SE)) assert(all((0,0) in gl for gl in GLIDERS_NW)) assert(all((0,0) in lwss for lwss in LWSSES_W))
temp_cells = cells[:] for gen in range(0, 4): gliders.extend(find_all_gliders(temp_cells)) temp_cells = g.evolve(temp_cells, 1) if len(gliders) < 2: continue sample = get_glider_color(gliders[0]) if not all([get_glider_color(glider) == sample for glider in gliders[1:]]): continue # check that pattern emits exactly one orthogonal glider new_cells = g.evolve(cells, 700) emitted_gliders = [] for t in range(0, 4): emitted_gliders.append(0) temp_cells = new_cells for gen in range(0, 4): emitted_gliders[-1] += len(find_all_gliders(temp_cells)) temp_cells = g.evolve(temp_cells, 1) new_cells = g.transform(new_cells, 0, 0, 0, -1, 1, 0) if emitted_gliders[0] + emitted_gliders[2] == 0 and emitted_gliders[1] + emitted_gliders[3] == 1: outfile.write(line) infile.close() outfile.close()
def GotoAdvanced(self, x, y, tableIdx, targetL = -1): if self.GotoSmart(x, y, tableIdx): self.recipeIdxList.append("MOVE") self.recipeIdxList.append(self.lastGotoIdx) self.recipeIdxList.append(tableIdx) return True xtemp0 = self.block0[0] ytemp0 = self.block0[1] tempRecipe0 = copy.copy(self.recipe) besti = -1 bestL = 10000000 lastx = -1 lasty = -1 worked = [] for i in xrange(0, len(self.moveTable )): x1 = self.moveTable[i][0] y1 = self.moveTable[i][1] if (str(x1) + "," + str(y1)) in worked: continue g.show(str(x) + "," + str(y) + "," + str(i) + "/" + str( len(self.moveTable )) + " BESTi = {0}, BESTL {1}".format(besti, bestL)) g.update() self.block0[0] = xtemp0 self.block0[1] = ytemp0 self.recipe = copy.copy(tempRecipe0) if self.CanApplyRecipe(self.moveTable[i][2], g.transform(blck, x1, y1)): worked.append(str(x1) + "," + str(y1)) self.AppendRecipe(self.moveTable[i][2]) self.block0[0] += x1 self.block0[1] += y1 recipeLength = bestL - len(self.recipe) if self.GotoSmartConstrained(x, y, tableIdx, recipeLength): if bestL > len(self.recipe) and targetL == -1: bestL = len(self.recipe) besti = i if len(self.recipe) == targetL: bestL = len(self.recipe) besti = i break self.block0[0] = xtemp0 self.block0[1] = ytemp0 self.recipe = tempRecipe0 if besti == -1: return False else: self.AppendRecipe(self.moveTable[besti][2]) x1 = self.moveTable[besti][0] y1 = self.moveTable[besti][1] self.block0[0] += x1 self.block0[1] += y1 self.recipeIdxList.append("MOVE") self.recipeIdxList.append(besti) self.recipeIdxList.append(-1) self.GotoSmart(x, y, tableIdx) self.recipeIdxList.append("MOVE") self.recipeIdxList.append(self.lastGotoIdx) self.recipeIdxList.append(tableIdx) return True