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 rand_rule(prob): isotropicsetS = isotropicsetB = { "0", "1c", "1e", "2c", "2e", "2k", "2a", "2i", "2n", "3c", "3e", "3k", "3a", "3i", "3n", "3y", "3q", "3j", "3r", "4c", "4e", "4k", "4a", "4i", "4n", "4y", "4q", "4j", "4r", "4t", "4w", "4z", "5c", "5e", "5k", "5a", "5i", "5n", "5y", "5q", "5j", "5r", "6c", "6e", "6k", "6a", "6i", "6n", "7c", "7e", "8" } isotropicsetB.remove("2a") isotropicsetB.remove("0") rulestr = "B" for i in isotropicsetB: if random.random() > prob: rulestr += i rulestr = rulestr + "/S" for i in isotropicsetS: if random.random() > prob: rulestr += i g.setrule(rulestr)
def slideshow (): oldalgo = g.getalgo() oldrule = g.getrule() message = "Hit space to continue or escape to exit the slide show..." g.show(message) for root, dirs, files in os.walk(g.getdir("app") + "Patterns"): for name in files: if name.startswith("."): # ignore hidden files (like .DS_Store on Mac) pass else: fullname = join(root, name) g.open(fullname, False) # don't add file to Open/Run Recent submenu g.update() if name.endswith(".pl") or name.endswith(".py"): # reshow message in case it was changed by script g.show(message) while True: event = g.getevent() if event == "key space none": break g.doevent(event) # allow keyboard/mouse interaction sleep(0.01) # avoid hogging cpu if "CVS" in dirs: dirs.remove("CVS") # don't visit CVS directories # if all patterns have been displayed then restore original algo and rule # (don't do this if user hits escape in case they want to explore pattern) g.new("untitled") g.setalgo(oldalgo) g.setrule(oldrule)
def slideshow(): oldalgo = g.getalgo() oldrule = g.getrule() message = "Hit space to continue or escape to exit the slide show..." g.show(message) for root, dirs, files in os.walk(g.getdir("app") + "Patterns"): for name in files: if name.startswith("."): # ignore hidden files (like .DS_Store on Mac) pass else: g.new("") g.setalgo("QuickLife") # nicer to start from this algo fullname = join(root, name) g.open(fullname, False) # don't add file to Open/Run Recent submenu g.update() if name.endswith(".lua") or name.endswith(".py"): # reshow message in case it was changed by script g.show(message) while True: event = g.getevent() if event == "key space none": break g.doevent(event) # allow keyboard/mouse interaction sleep(0.01) # avoid hogging cpu # if all patterns have been displayed then restore original algo and rule # (don't do this if user hits escape in case they want to explore pattern) g.new("untitled") g.setalgo(oldalgo) g.setrule(oldrule)
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 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 PlaceAdjustment(slv): vals = [[11, 32], [11, 249], [12, 138], [12, 123], [13, 29], [13, 27], [14, 89], [14, 15]] g.setrule("LifeHistory") for i in xrange(0, len(vals)): slv.ApplyRecipeSmart(vals[i][1], vals[i][0]) slv.PlaceRecipe(i * 100, 0, i == 0) slv.Reset()
def setminisorule(period): if g.empty(): return if period < 1: return b_need, s_need, b_OK, s_OK = getRuleRangeElems(period, ruleRange='min') minrulestr = 'B' + ''.join(sorted(b_need)) + '/S' + ''.join(sorted(s_need)) g.setrule(minrulestr) return minrulestr
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 PlaceAllRecipesForIdx(slv, idx): g.setrule("LifeHistory") if idx >= 0: moveTable = slv.SLsMoveTable[idx] else moveTable = slv.MoveTable for i in xrange(0, len(moveTable)): slv.ApplyRecipeSmart(i, idx) slv.PlaceRecipe(i * 1000, 0, i == 0) slv.Reset()
def writeRuleTree(self,name): # create a .tree file in user's rules directory f=open(golly.getdir("rules")+name+".tree", 'w') f.write("# Automatically generated by make-ruletree.py.\n") f.write("num_states=" + str(self.numStates)+"\n") f.write("num_neighbors=" + str(self.numNeighbors)+"\n") f.write("num_nodes=" + str(len(self.r))+"\n") for rule in self.r: f.write(rule+"\n") f.flush() # ensure file is complete (only on Windows?) f.close() golly.setalgo("RuleTree") # in case name.table exists golly.setrule(name) golly.show("Created "+name+".tree in "+golly.getdir("rules"))
def PlaceReadingHeads(hwssRecipe): global fenseX g.new("") g.setrule("LifeHistoryNoMark") if directionType == "B": dist = int(1.5 * len(hwssRecipe) / speed) for y in xrange(-dist, 1): MakeBackwardSalvo(step, 0, distBack * y, step * len(hwssRecipe) + 100, y == 0, y == 0) MakeBackwardRecipe(step, 0, 0, hwssRecipe) rect = g.getrect() cells = [] for i in xrange(1200, step * len(hwssRecipe) + 1501): cells.append(rect[0] - 50) cells.append(i) cells.append(6) g.putcells(cells) g.putcells(cells, rect[0] - 1000, 0) else: helixD = CalcHelix(hwssRecipe) dist = int(1.5 * len(hwssRecipe) / speed) for y in xrange(0, dist + 1): MakeForwardSalvo(step, 0, distForward * y, helixD, y == 0, y == 0) MakeForwardRecipe(helixD, step, 0, 0, hwssRecipe) rect = g.getrect() cells = [] fenseX = rect[0] + rect[2] + 50 for i in xrange(fenseY, -helixD + 201): cells.append(rect[0] + rect[2] + 50) cells.append(i + helixD) cells.append(6) g.putcells(cells)
def PlaceReadingHeads(hwssRecipe): global fenseX g.new("") g.setrule("LifeHistoryNoMark") if directionType == "B": dist = int(1.5 * len(hwssRecipe) / speed) for y in xrange(-dist, 1): MakeBackwardSalvo(step, 0, distBack * y, step * len(hwssRecipe) + 100, y == 0, y == 0) MakeBackwardRecipe(step, 0, 0, hwssRecipe) rect = g.getrect() cells = [] for i in xrange(1200, step * len(hwssRecipe) + 1501): cells.append(rect[0]-50) cells.append(i) cells.append(6) g.putcells(cells) g.putcells(cells, rect[0]-1000, 0) else: helixD = CalcHelix(hwssRecipe) dist = int(1.5 * len(hwssRecipe) / speed) for y in xrange(0, dist + 1): MakeForwardSalvo(step, 0, distForward * y, helixD, y == 0, y == 0) MakeForwardRecipe(helixD, step, 0, 0, hwssRecipe) rect = g.getrect() cells = [] fenseX = rect[0] + rect[2] + 50 for i in xrange(fenseY, -helixD + 201): cells.append(rect[0] + rect[2] + 50) cells.append(i + helixD) cells.append(6) g.putcells(cells)
def 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 render(length, x, y, generation): g.setgen("0") g.setalgo("Generations") g.setrule(generate_rule(x, y, generation)) pop, extinction = get_pop(length, x, y) if extinction < 4410: g.show("Rule {} extinct at generation {}.".format( g.getrule(), extinction)) with open("snd/short_lived_rules", "a") as short_lived: short_lived.write(g.getrule() + "\n") return with open("snd/long_lived_rules", "a") as long_lived: long_lived.write(g.getrule() + "\n") filename = create_name("snd") write_wave(filename, pop) g.show("Wave saved to " + filename)
def golly_main(): bounding_box = g.getrect() g.show('Installing rule file...') src_rule = os.path.join(scriptdir, 'grills-examples', 'Grills.rule') dst_rule = os.path.join(g.getdir('rules'), 'Grills.rule') shutil.copyfile(src_rule, dst_rule) g.show('...installed.') if (len(bounding_box) == 0): g.setrule("Grills") g.exit("Please draw or load an input pattern.") elif (g.getrule() == "Grills"): golly_grills() elif (g.getrule() == "LifeHistory"): golly_lhistory() else: g.exit("Pattern has the incorrect rule: '%s' != '%s'" % (g.getrule(), 'Grills'))
def construct(self): g.new('') g.setrule("LifeHistory") events = sorted(self.timeline, reverse=True) time = -240 * 20 nextrow = time + 240 top_y = 0 for y in range(60): g.setcell(self.left, y, 6) g.setcell(self.right, y, 6) rephasing = [0] * len(self.columns) while events: if events[-1][0] < nextrow: t, c = events.pop() g.run(t-time) time = t x, y, excess = self.columns[c] #place bhep, reflecting in the odd columns g.putcells(self.b_hep, x + (c%2), rephasing[c] + y, -1 if (c%2) else 1) #add blocks to absorb excess gliders for i in range(excess): g.putcells(self.absorber, x + (c%2), rephasing[c] + y - 31 * i, -1 if (c%2) else 1) rephasing[c] += 31 - 9 else: for x, y, _ in self.columns: g.putcells(g.parse("2o$2o!", x, 2*top_y+y)) g.putcells(g.parse("2o$2o!", x, 2*top_y-31+y)) for _ in range(31): top_y -= 1 g.setcell(self.left, top_y, 6) g.setcell(self.right, top_y, 6) g.run(nextrow-time) time = nextrow nextrow += 240
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 golly_lhistory(): ngens = int(g.getstring('How many generations to run the pattern?', '1')) d = threes_and_fours(0) g.setstep(0) for i in range(ngens): g.step() d.update(threes_and_fours(i + 1)) exes = [k[0] for k in d] whys = [k[1] for k in d] zeds = [k[2] for k in d] minx = min(exes) maxx = max(exes) miny = min(whys) maxy = max(whys) width = (maxx - minx) + 10 height = maxy - miny g.addlayer() g.setrule('Grills') for (k, v) in d.iteritems(): x = (k[0] - minx) + (k[2] * width) y = k[1] - miny c = {3: LIVE_VARIABLE_STATE, 4: DEAD_VARIABLE_STATE}[v] g.setcell(x, y, c) for i in range(1, max(zeds) + 1): for j in range(height + 1): g.setcell(i * width - 5, j, VERTICAL_LINE_STATE) for i in range(max(zeds) + 1): g.setcell(i * width + 3, -3, ORIGIN_STATE) g.setcell(i * width + 3, -4, ZEROTH_GENERATION_STATE + i)
def FinadOptimalRecipe(slv, idx): moveTable = slv.SLsMoveTable[idx] bests = [-1, -1] slCount = [1000, 1000] g.setrule("B3/S23") g.setalgo("HashLife") for i in xrange(0, len(moveTable)): g.new("") slv.ApplyRecipeSmart(i, idx) slv.PlaceRecipe() g.setstep(5) g.step() numSL = len(CountSL()) laneID = (moveTable[i][1] + 10000) % 2 if slCount[laneID] > numSL: slCount[laneID] = numSL bests[laneID] = i slv.Reset() g.setrule("LifeHistory") for i in xrange(0, len(bests)): slv.ApplyRecipeSmart(bests[i], idx) slv.PlaceRecipe(i * 100, 0, i == 0) slv.Reset() g.show(str(bests)) #11 - [32, 249] #12 - [138, 123] #13 - [29, 27] #14 - [89, 15] return bests
for nh in nhoods.keys(): if nh in spec: nhood = nhoods[nh] n = int(spec.replace(nh, "")) break if nhood == "": golly.exit("Unsupported string: " + spec) if n < 2 or n > 255: golly.exit("Value of N must lie between 2 and 255.") # assemble the transitions nbors = {"vonNeumann": 4, "Moore": 8, "hexagonal": 6, "triangularVonNeumann": 3, "triangularMoore": 12} transitions = [] for sl in product(range(n), repeat=nbors[nhood]): transitions += [[range(n)] + [[s] for s in sl] + [[sum(sl) % n]]] rule_name = "Fredkin_mod" + str(n) + "_" + nhood Converters = { "vonNeumann": ConvertRuleTableTransitionsToRuleTree, "Moore": ConvertRuleTableTransitionsToRuleTree, "triangularVonNeumann": EmulateTriangular, "triangularMoore": EmulateTriangular, "hexagonal": EmulateHexagonal, } golly.show("Building rule tree...") rule_name = Converters[nhood](nhood, n, transitions, rule_name + ".tree") golly.setrule(rule_name) golly.show("Created " + rule_name + ".tree and .colors, and selected this rule.")
# any Win line endings (CR+LF) or Mac line endings (CR) to LF CR = chr(13) LF = chr(10) try: exec(golly.getclipstr().replace(CR+LF,LF).replace(CR,LF)) MakeRuleTreeFromTransitionFunction( n_states, n_neighbors, transition_function, golly.getdir("rules")+name+".tree" ) # use name.tree to create name.rule (with no icons); # note that if name.rule already exists then we only replace the info in # the @TREE section to avoid clobbering any other info added by the user ConvertTreeToRule(name, n_states, []) golly.setalgo("RuleLoader") golly.setrule(name) golly.show("Created "+golly.getdir("rules")+name+".rule and switched to that rule.") except: import sys import traceback exception, msg, tb = sys.exc_info() golly.warn(\ '''To use this script, copy a Python format rule definition into the clipboard, e.g.: name = "ParityNWE" n_states = 5 n_neighbors = 4 # order for 4 neighbors is N, W, E, S, C def transition_function ( s ) : return ( s[0] + s[1] + s[2] ) % 5
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 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: overlap = ([x, y] in nearlist) # place current object ############################################# # TODO: if there's an overlap, set ptr to max value, then handle all cases with same code at the bottom
import sys import golly visual_execution = True #False for faster programs, True required for infinitely looping ones file = golly.opendialog() f = open(file).read() golly.new("Executing " + file.split("/")[-1]) golly.setrule("B/S012345678") golly.autoupdate(visual_execution) commands = [] for line in f.splitlines(): important = line.split("#")[0].strip() if not important: continue important = important.split()[0:5] commands.append((important[0], int(important[1]), int(important[2]), important[3], important[4])) pointer = [0, 0] instruction_pointer = "start" while True: command = commands[[i[0] for i in commands].index(instruction_pointer)] pointer = [pointer[0] + command[1], pointer[1] + command[2]] x = pointer[0]
if x == "S" or x == "B": totalistic_context = "none" if x == "S": bs = "1," if x == "B": bs = "0," elif x == "-": positive_or_inverse = "inverse" elif x in ["c", "a", "e", "k", "i", "v", "j", "y", "q", "r", "w", "t", "z"] and totalistic_context != "none": if positive_or_inverse == "positive": notation_letter = x f.write(create_table_row(bs, totalistic_context, notation_letter, [])) else: notation_letter = x inverse_list.append(x) f.write("# Death otherwise"+"\n") f.write("1,a,b,c,d,e,f,g,h,0"+"\n\n") f.flush() f.close() golly.setalgo("RuleTable") golly.setrule(rule_name) if pastepattern != "none": golly.setclipstr(pastepattern) golly.show("Paste the pattern when you are ready....") else: golly.show("Created "+rule_name+".table in "+golly.getdir("rules"))
bb, usebb = [], 0 # g.note(str([basegun+"_special_p" + ("0000"+period)[-5:], (basegun+"_special_p" + ("0000"+period)[-5:] in specialguns)])) if basegun == "fixed" or basegun + "_special_p" + ( "0000" + period)[-5:] in specialguns: if basegun == "fixed": fixedname = "p" + ("0000" + period)[-5:] folder = fixedfolder else: # g.note(basegun) ################# fixedname = basegun + "_special_p" + ("0000" + period)[-5:] + ",0,0,0" folder = specialfolder g.open(os.path.join(folder, fixedname + ".rle")) bb = g.getrect() usebb = 1 g.setrule("LifeHistoryToLife") g.run(1) g.setrule("Life") if basegun == "fixed": g.save(os.path.join(outfolder, fixedname) + "_fixed.rle", "rle") g.show("[fixed]") countfixed += 1 else: g.save( os.path.join(outfolder, "p" + ("0000" + period)[-5:] + "_custom") + ".rle", "rle") countspecial += 1 r = g.getrect() else: datalist = basegun.split("_")
# 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()
import golly as g import glife import operator ptbdir = "/home/scorbie/Apps/ptbsearch-test" catfilename = g.opendialog("Choose catalyst file to verify", "All files(*)|*", ptbdir) cats = [] size = 20 def iscomment(line): return line.strip() == "" or line.lstrip().startswith("#") g.setrule("LifeHistory") try: currcats = [] with open(catfilename) as catfile: for line in catfile: if iscomment(line): # Organize all the previous cats. if currcats: currcat = reduce(operator.add, (cat.translate(0, idx * size) for idx, cat in enumerate(currcats))) cats.append(currcat) # Prepare new cat container currcats = [] else: currcats.append(glife.pattern(line)) currcat = reduce(operator.add, (cat.translate(0, idx * size) for idx, cat in enumerate(currcats)))
# save some info before we switch layers stepsize = "%i^%i" % (g.getbase(), g.getstep()) pattname = g.getname() # create population plot in separate layer g.setoption("stacklayers", 0) g.setoption("tilelayers", 0) g.setoption("showlayerbar", 1) if poplayer == -1: poplayer = g.addlayer() else: g.setlayer(poplayer) g.new(layername) # use same rule but without any suffix (we don't want a bounded grid) g.setrule(g.getrule().split(":")[0]) deadr, deadg, deadb = g.getcolor("deadcells") if (deadr + deadg + deadb) / 3 > 128: # use black if light background g.setcolors([1,0,0,0]) else: # use white if dark background g.setcolors([1,255,255,255]) minpop = min(poplist) maxpop = max(poplist) if minpop == maxpop: # avoid division by zero minpop -= 1 popscale = float(maxpop - minpop) / float(ylen)
return glife.pattern(line) def parsecensus(census): '''Get census of the form (freq, cat) and convert it to glife.pattern.''' freq, cat = census catpat = parsepat(cat) freqpat = parsefreq(freq) # Align them to the center. _, _, _, fonth = glife.getminbox(freqpat) _, _, w, h = glife.getminbox(catpat) return (catpat.translate((patw-w)//2, (height-h)//2) + freqpat.translate(patw, (height-fonth)//2)) # Main g.new('ptbtest results') g.setrule('LifeHistory') # Generate list of frequecies and sort them in descending order. freqlist = [] with open(ptbresult) as ptbresultfile: for line in ptbresultfile: cat, freq = line.split(': ') freqlist.append((float(freq), cat)) freqlist.sort(reverse=True) # Parse the census and put them in golly. for idx, census in enumerate(freqlist): i, j = idx//rows, idx%rows parsecensus(census).put(i*(patw+freqw), j*height) g.fit()
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)
return "Pattern load data: width={}, height={} startx={}, starty={}, xval={}, yval={}, bytes={}".format(minbox.wd, minbox.height, startx, starty, xval, yval, len(input_str)) attempt_id = os.getenv("GOLLY_ATTEMPT_ID") if attempt_id is None and os.getenv("LIFEBOX_DEBUG") is not None: attempt_id = "aaaaaaaa-bbbb-cccc-dddd-eeeeeeffffff" BASE_RESULTS_PATH = os.path.join(os.sep, "tmp", attempt_id) if not os.path.exists(BASE_RESULTS_PATH): os.makedirs(BASE_RESULTS_PATH) RESULTS_FN = os.path.join(BASE_RESULTS_PATH, "results.log") open(RESULTS_FN,"a").write("Opening up MC file..\n") g.open("adventure_lifebooox.mc") g.setrule('Varlife') g.show("Starting....") g.update() g.setstep(6) start_time = time.time() open(RESULTS_FN,"a").write("BOOTING..\n") PATTERN_FN = os.path.join(BASE_RESULTS_PATH, "pattern.dat") results = add_data(PATTERN_FN) open(RESULTS_FN,"a").write(results + "\n") boot_completed = False for x in range(0, 40):
i-=1 break xFF, yFF, diFF = wssFront[i] idx = len(wssBack) - 1 xt, yt, it = wssBack[idx] if (yt - yFF) % 4 != dY % 4: idx -= 1 xt, yt, it = wssBack[idx] if (yt - yFF) > dY: yt -= 2 * distBack iter = dY - (yt - yFF) yFF -= iter / 2 moveX = xFF - xFT moveY = yFF - yFT g.open(path.join(dir, str(step) + "_" + str(period) + "_Front.rle"), False) g.run(iter) rect = g.getrect() cells = g.getcells([rect[0], rect[1], rect[2], yFF + 30 - rect[1]]) g.open(path.join(dir, str(step) + "_" + str(period) + "_Back.rle"), False) g.putcells(cells, -moveX, -moveY) g.setrule("b3/s23") g.save(str(step) + "_" + str(period) + "_Caterloopillar.rle", "rle", False) g.show("Finish! Here's the " + str(step) + "/" + str(period) + " caterloopillar!! Hooray") #'''
def score_pair(g, seed1, seed2, width_factor, height_factor, \ time_factor, num_trials): """ Put seed1 and seed2 into the Immigration Game g and see which one wins and which one loses. Note that this function does not update the histories of the seeds. """ # # Make copies of the original two seeds, so that the following # manipulations do not change the originals. # s1 = copy.deepcopy(seed1) s2 = copy.deepcopy(seed2) # # Initialize scores # score1 = 0.0 score2 = 0.0 # # Run several trials with different rotations and locations. # for trial in range(num_trials): # # Randomly rotate and flip s1 and s2 # s1 = s1.random_rotate() s2 = s2.random_rotate() # # Switch cells in the second seed (s2) from state 1 (red) to state 2 (blue) # s2.red2blue() # # Rule file is "Immigration.rule" # Set toroidal universe of height yspan and width xspan # Base the s1ze of the universe on the s1zes of the seeds # # g = the Golly universe # [g_width, g_height, g_time] = dimensions(s1, s2, \ width_factor, height_factor, time_factor) # # set algorithm -- "HashLife" or "QuickLife" # g.setalgo("QuickLife") # use "HashLife" or "QuickLife" g.autoupdate(False) # do not update the view unless requested g.new("Immigration") # initialize cells to state 0 g.setrule("Immigration:T" + str(g_width) + "," + str(g_height)) # make a toroid # # Find the min and max of the Golly toroid coordinates # [g_xmin, g_xmax, g_ymin, g_ymax] = get_minmax(g) # # Set magnification for Golly viewer # g.setmag(set_mag(g)) # # Randomly place seed s1 somewhere in the left s1de of the toroid # s1.insert(g, g_xmin, -1, g_ymin, g_ymax) # # Randomly place seed s2 somewhere in the right s1de of the toroid # s2.insert(g, +1, g_xmax, g_ymin, g_ymax) # # Run for a fixed number of generations. # Base the number of generations on the sizes of the seeds. # Note that these are generations ins1de one Game of Life, not # generations in an evolutionary sense. Generations in the # Game of Life correspond to growth and decay of a phenotype, # whereas generations in evolution correspond to the reproduction # of a genotype. # g.run(g_time) # run the Game of Life for g_time time steps g.update() # need to update Golly to get counts # # Count the populations of the two colours. State 1 = red = seed1. # State 2 = blue = seed2. # [count1, count2] = count_pops(g) # if (count1 > count2): score1 = score1 + 1.0 elif (count2 > count1): score2 = score2 + 1.0 else: score1 = score1 + 0.5 score2 = score2 + 0.5 # # # Normalize the scores # score1 = score1 / num_trials score2 = score2 / num_trials # return [score1, score2]
while var_val_to_change<len(vars_used): var_label = vars_used[var_val_to_change] if var_val_indices[var_label]<len(vars[var_label])-1: var_val_indices[var_label] += 1 break else: var_val_indices[var_label] = 0 var_val_to_change += 1 if var_val_to_change >= len(vars_used): break # we also need a generic case for no-change g.write('# default: no change (but partition moves)\n') for s in range(n_states): # case 0: central cell is the top-left (but not next time) g.write('%d,_b1,_b2,_b3,_b4,_b5,_b6,_b7,_b8,%d # TL -> BR\n'\ %(as_top_left(s),as_not_top_left(s))) # case 1: central cell is the top-right g.write('%d,_b1,_b2,_a1,_b3,_b4,_b5,_a2,_b6,%d # TR -> BL\n'\ %(as_not_top_left(s),as_not_top_left(s))) # case 2: central cell is the bottom-left g.write('%d,_a1,_b1,_b2,_b3,_a2,_b4,_b5,_b6,%d # BL -> TR\n'\ %(as_not_top_left(s),as_not_top_left(s))) # case 3: central cell is the bottom-right (becomes top-left next time) g.write('%d,_b1,_a1,_b2,_a2,_b3,_a3,_b4,_a4,%d # BR -> TL\n'\ %(as_not_top_left(s),as_top_left(s))) g.close() f.close() golly.setrule(rule_name+'-emulated')
table += "\n# Birth\n" for n in self.allneighbours_flat: if self.bee[n]: table += "off," table += self.notationdict2[n] table += ",1\n" table += "\n# Survival\n" for n in self.allneighbours_flat: if self.ess[n]: table += "1," table += self.notationdict2[n] table += ",1\n" table += "\n# Death\n" table += self.scoline("","",1,2,0) colours = "" self.saverule(self.rulename, comments, table, colours) rulestring = g.getstring("To make a History rule, enter rule string in Alan Hensel's isotropic rule notation", "B2-a/S12") rg = RuleGenerator() rg.setrule(rulestring) rg.saveIsotropicRule() g.setrule(rg.rulename) g.show("Created rule in file: " + rg.rulename + ".rule")
mdx, mdy = putcells(results[i][0], (dx, dy)) AddText(fname, dx + int(mdx / 2), dy - 10) dx += mdx + 60 dy += 60 + mdy dx = 0 AddText(path, 0, -100) #Start Here CreateRule() g.new("") g.setrule("LifeBellman") file_path = os.path.join(g.getdir("data"), "LastBellmanOutputDir.txt") dir = "" if os.path.exists(file_path): with open (file_path, "r") as f: dir=f.readline() dir = g.getstring("Enter output directory", dir) with open(file_path, "w") as text_file: text_file.write(dir) Place(dir)
S.append(str(8-int(i))) if not str(i) in ruleS: B.append(str(8-int(i))) B=''.join(B) S=''.join(S) gen=int(g.getgen()) rules=['',''] invrule='/'.join([B,S]) if str(0) not in ruleB: tp=rule rule=invrule invrule=tp rules[gen%2]=rule; rules[(gen+1)%2]=invrule; # g.note(rule) #g.setrule(invrule) speed=2 rules=[rule,invrule] while True: gen=int(g.getgen()) g.setrule(rules[gen%2]) g.run(1) if gen%speed==0: g.update()
# Output an adjacency matrix for current selection to clipborad in a "Mathematica" list fomart # Use AdjacencyGraph[] in Mathematica for downstream processing. # Author: Feng Geng([email protected]), May 2016. import golly as g from glife import * import numpy as np import hashlib pt = g.getcells(g.getrect()) width = g.getstring('width of torus', '200') rule = g.getrule() nrule = rule.split(':')[0] + ':T{},512'.format(width) g.note(nrule) g.setrule(nrule)
169, 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
import golly as g import quiescentauton as q soupfilepath = "/home/scorbie/Apps/ptbtest/random" nsoups = int(g.getstring("How many soups?", "1000")) soupsize = 10 # int(g.getstring('Soup size?', '10')) if g.getrule() == "LifeHistory": g.setrule("B3/S23") if g.numstates() > 2: g.exit("This script only works with two-state rules.") soups = [] x, y, w, h = r = [0, 0, soupsize, soupsize] cellchar = [".", "a"] while len(soups) < nsoups: g.new("Generating Soups") g.select(r) g.randfill(40) g.run(250) # To avoid 'Empty Pattern!' messages in status bar. if int(g.getpop()) == 0: continue if not q.testquiescence(60): g.reset() soupstr = "!".join( "".join(cellchar[g.getcell(i, j)] for j in xrange(0, soupsize + 1)) for i in xrange(0, soupsize + 1) ) soups.append(soupstr) g.show("Soup {}/{}".format(len(soups), nsoups)) with open(soupfilepath, "w") as soupfile:
def dmprinter(pdy, copies=1): ''' Generate & display a dot matrix printer for named bitmap pattern ''' #Horizontal pixel separation between LineMakers. minimum = 5 LMsx = 5 #Horizontal distance between bitmap pixels. Constant, due to LineMaker period pdx = 15 #Distance between LineMakers LMdx, LMdy = -LMsx * pdx, pdy #Get bitmap pattern from current selection. bm = get_bitmap() #Make printer in a new layer golly.duplicate() golly.setoption("syncviews", False) #Build new window title from old title = golly.getname().split('.')[0] title = '%s_Printer [%d] v0.10' % (title, pdy) golly.new(title) #Make sure we're using the standard Life generation rule golly.setrule("B3/S23") #Bitmap dimensions. Width MUST be of form 4m, for m >=1 bmheight = len(bm) bmwidth = len(bm[0]) mid = (bmheight + 1) // 2 loopw = (bmwidth - 8) // 4 loopm = pdx * loopw #Gliders, heading north-east g0 = pattern('2bo$2o$b2o!') g1 = pattern('obo$2o$bo!') gliders = [ g0, g1, g1(0, 2, rccw), g0(0, 2, rccw), g0(2, 2, flip), g1(2, 2, flip), g1(2, 0, rcw), g0(2, 0, rcw) ] #Create full Glider loop. gg = [] ox, oy = 35, 23 for j in xrange(loopw + 1): dd = pdx * j gg += [ gliders[0](ox + dd, oy - dd), gliders[1](ox + 8 + dd, oy - 7 - dd) ] dd = loopm gg += [gliders[2](45 + dd, 4 - dd), gliders[3](37 + dd, -3 - dd)] ox, oy = 26 + loopm, -4 - loopm for j in xrange(loopw + 1): dd = pdx * j gg += [ gliders[4](ox - dd, oy + dd), gliders[5](ox - 8 - dd, oy + 7 + dd) ] dd = loopm gg += [gliders[6](16, 15), gliders[7](24, 22)] parity = 2 * ((loopw + 1) * (0, 0) + (1, 1)) def buildLM(): ''' Build a complete LineMaker ''' #Populate glider loop. (jj, ii) are bitmap coords gloop = pattern() for j in xrange(bmwidth): jj = (j - delta + bmwidth - 1) % bmwidth #Is there a pixel at this location? if bm[ii][jj] == parity[j]: gloop += gg[j] #Add glider to the loop #Only put LineMaker if glider loop isn't empty if len(gloop) > 0: (LMBlank + gloop).put(Lx, Ly, trans) #Assemble blank LineMaker LMBlank = linemaker(loopm) #Do upper LineMakers trans = identity for i in xrange(mid): ii = mid - (i + 1) io = mid + (i + 1) Lx, Ly = io * LMdx, ii * LMdy delta = LMsx * io buildLM() #Do lower LineMakers trans = flip_y for i in xrange(mid, bmheight): ii = i io = i + 2 Lx, Ly = io * LMdx + pdx, ii * LMdy + 128 delta = LMsx * io - 1 buildLM() #Eaters facing south-east & north-east eaterSE = pattern('2o$bo$bobo$2b2o!') eaterNE = eaterSE(0, 10, flip_y) eY = 59 eaters = (eaterNE(0, eY), eaterSE(0, eY)) #Eater horizontal displacement. Must be odd #bmwidth muliplier determines number of copies visible 'outside' printer. eX = (bmheight + 1) * LMdx - (copies * bmwidth - 1) * pdx eX = 1 + eX // 2 * 2 #Adjust parity all = pattern() for i in xrange(bmheight): all += eaters[i % (1 + LMsx % 2)](eX, i * LMdy) all.put() #Centre view over bitmap output area golly.setpos(str(-pdx * bmwidth // 2 + (bmheight - 1) * LMdx), str(Ly // 2)) #golly.setmag(-2) #Aliasing effects happen at smaller scales than -2 :( golly.fit()
break xFF, yFF, diFF = wssFront[i] idx = len(wssBack) - 1 xt, yt, it = wssBack[idx] if (yt - yFF) % 4 != dY % 4: idx -= 1 xt, yt, it = wssBack[idx] if (yt - yFF) > dY: yt -= 2 * distBack iter = dY - (yt - yFF) yFF -= iter / 2 moveX = xFF - xFT moveY = yFF - yFT g.open(path.join(dir, str(step) + "_" + str(period) + "_Front.rle"), False) g.run(iter) rect = g.getrect() cells = g.getcells([rect[0], rect[1], rect[2], yFF + 30 - rect[1]]) g.open(path.join(dir, str(step) + "_" + str(period) + "_Back.rle"), False) g.putcells(cells, -moveX, -moveY) g.setrule("b3/s23") g.save(str(step) + "_" + str(period) + "_Caterloopillar.rle", "rle", False) g.show("Finish! Here's the " + str(step) + "/" + str(period) + " caterloopillar!! Hooray") #'''
def export_icons(iconsection, rulename): global multi_color_icons if multi_color_icons: # prepend a new @COLORS section with the average colors in each icon iconsection = create_average_colors(iconsection) + iconsection # replace any illegal filename chars with underscores filename = rulename.replace("/","_").replace("\\","_") # we will only create/update a .rule file in the user's rules folder # (ie. we don't modify the supplied Rules folder) rulepath = g.getdir("rules") + filename + ".rule" fileexists = os.path.isfile(rulepath) if fileexists: # .rule file already exists so replace or add @ICONS section rulefile = open(rulepath,"rU") # create a temporary file for writing new rule info temphdl, temppath = mkstemp() tempfile = open(temppath,"w") wroteicons = False skiplines = False for line in rulefile: if line.startswith("@ICONS"): # replace the existing @ICONS section tempfile.write(iconsection) wroteicons = True skiplines = True elif line.startswith("@COLORS") and multi_color_icons: # skip the existing @COLORS section # (iconsection contains a new @COLORS section) skiplines = True elif skiplines and line.startswith("@"): if wroteicons: tempfile.write("\n") skiplines = False if not skiplines: tempfile.write(line) if not wroteicons: # .rule file had no @ICONS section tempfile.write("\n") tempfile.write(iconsection) # close files rulefile.close() tempfile.flush() tempfile.close() os.close(temphdl) # remove original .rule file and rename temporary file os.remove(rulepath) move(temppath, rulepath) else: # .rule file doesn't exist so create it rulefile = open(rulepath,"w") rulefile.write("@RULE " + filename + "\n\n") if not multi_color_icons: # grayscale icons, so check if Rules/filename.rule exists # and if so copy any existing @COLORS section suppliedrule = g.getdir("app") + "Rules/" + filename + ".rule" if os.path.isfile(suppliedrule): colordata = get_color_section(suppliedrule) if len(colordata) > 0: rulefile.write(colordata) rulefile.write(iconsection) rulefile.flush() rulefile.close() # create another layer for displaying the new icons if g.numlayers() < g.maxlayers(): g.addlayer() g.new("icon test") g.setrule(rulename) for i in xrange(g.numstates()-1): g.setcell(i, 0, i+1) g.fit() g.setoption("showicons",True) g.update() if fileexists: g.note("Updated the icon data in " + rulepath) else: g.note("Created " + rulepath)
def rule(s = "B3/S23"): """\ Set the rule for the Game of Life. Although it affects subsequent calls to pattern.evolve(), only the last call to this function matters for the viewer.""" golly.setrule(s)
def setrule(self, text): """ Sets the rule in Golly to the specified rule :param text: the name of the rule to be changed to """ g.setrule(text)
import_icons(rulename) iconnote = "" if len(iconcolors) == 0: iconnote = "There are currently no icons for this rule.\n\n" # check if icons are grayscale grayscale_icons = not multi_color_icons(iconcolors) g.new(layerprefix + rulename) livestates = g.numstates() - 1 deadcolor = g.getcolors(0) deadrgb = (deadcolor[1], deadcolor[2], deadcolor[3]) # switch to a Generations rule so we can have lots of colors g.setrule("//256") if grayscale_icons and deadrgb == (255,255,255): # if icons are grayscale and state 0 color was white then switch # to black background to avoid confusion (ie. we want black pixels # to be transparent) g.setcolors([0,0,0,0]) else: g.setcolors(deadcolor) graystate = init_colors() # if icons are grayscale then change deadrgb to black so that draw_icons # will treat black pixels as transparent if grayscale_icons: deadrgb = (0,0,0) draw_icon_boxes(livestates, graystate) draw_icons(iconinfo31, deadrgb)
deads, deadr, deadg, deadb = g.getcolors(0) # create histogram in separate layer g.setoption("stacklayers", 0) g.setoption("tilelayers", 0) g.setoption("showlayerbar", 1) if histlayer == -1: histlayer = g.addlayer() else: g.setlayer(histlayer) g.new(histname) g.setcursor(currcursor) # use a Generations rule so we can append extra state for drawing text & lines g.setrule("//" + str(currstates + 1)) extrastate = currstates currcolors.append(extrastate) if (deadr + deadg + deadb) / 3 > 128: # use black if light background currcolors.append(0) currcolors.append(0) currcolors.append(0) else: # use white if dark background currcolors.append(255) currcolors.append(255) currcolors.append(255) g.setcolors(currcolors) # draw axes with origin at 0,0
update = rules(x, y, update) y += 1 x += 1 while i < w: j = 0 while j < h: g.setcell(i, j, update[i][j]) j += 1 i += 1 g.update() return update try: g.new("Conway's Game of life") g.setrule("Life") g.setcolors([1, 255, 255, 255]) g.setcolors([0, 0, 0, 0]) maxsize = 100000 count = 0 width = int( g.getstring("Enter a width for the game of life:", "100") ) height = int( g.getstring("Enter a height for the game of life:", "100") ) g.select([0, 0, width, height]) g.randfill(50) update = [[0 for x in range(width + 1)] for x in range(height + 1)] while count < maxsize: g.show("In main " + str(count)) update = main(width, height, update) count += 1