def testkey(): if results and g.getevent().startswith("key x"): g.setlayer(results_layer) g.select(g.getrect()) g.copy() g.select([]) g.setlayer(work_layer)
def 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 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 draw_dna(): logging.debug('loading cell pallate') pallate = cellPallate() pallate.load() logging.debug('getting default pallate selection') chosenCell = pallate.getUserChoice() chosenName = pallate.getSelectedCellName() g.show('now drawing with DNA from '+chosenName) logging.debug('now drawing with DNA from '+chosenName+'='+str(chosenCell)) # prepare environment env = environment() logging.debug('turning on golly even script access') event = g.getevent(True) # turn on golly event script access # === let user draw g.setcursor("Draw") try: #this try statement is just to ensure the 'finally' block is run while True: # loop until stop button is pressed event = g.getevent() # event is a string like "click 10 20 left none" if len(event) < 1: # do not try to split empty string continue else: logging.debug('event recieved: "'+event+'"') evt, xstr, ystr, butt, mods = event.split() if evt=="click" and butt=="left" and mods=="none": # left click # logging.debug('left click detected at '+xstr+','+ystr) x = int(xstr) y = int(ystr) env.cellList.setCell(x,y,cell=cell(x,y,chosenCell.DNA)) #add cell to list g.setcell(x,y,1) #fill in functional cell env.drawColor() #update color layer to match g.update() #update golly display logging.info('cell ('+xstr+','+ystr+') painted with "'+chosenName+'"') g.show('cell painted. press "Esc" to stop drawing') else: logging.info('event "'+event+'" not recognized') except: # re-raise any errors encountered logging.error('unexpected error: '+sys.exc_info()[0]) raise finally: g.getevent(False) # return event handling to golly g.show('done drawing '+chosenName+' cells.') logging.debug('done drawing '+chosenName+' cells.') # === teardown env.teardown() return
def getinp(s): ########################### temp = g.getcell(x, y) g.setcell(x, y, 5) g.show(s + "Ptr:" + str(ptr) + " x:" + str(x) + " y:" + str(y)) g.fit() g.update() g.setcell(x, y, temp) # return k = g.getevent() count = 0 while k == "": sleep(.01) k = g.getevent() count += 1 if k == "key q none": g.exit() return
def trygliders(ginfo): gdistance = ginfo / 4 phase = ginfo % 4 bstatus = boxstatus pstatus = popstatus for num in xrange(8): tlist = form(celllist, num) rect = boxform(fullrect, num) g.new('') g.putcells(tlist) gx = rect[0] - 3 - gdistance gy = rect[1] - 3 - gdistance for w in xrange(rect[2] + 5): g.new('') g.putcells(tlist) g.putcells(glider[phase], gx + w, gy) g.fit() g.update() for gen in xrange(1000): g.run(1) if int(g.getpop()) <= 2: g.new('') g.show("Found clean glider destruction.") status = 0, num, phase, [gx + w, gy] putcells_and_fit(result(celllist, status)) g.exit() box = g.getrect()[2:] # Checking the bounding box size and population against the current lowest found. if reduce(mul, box) < reduce(mul, bstatus[0]): bstatus = (box, num, phase, [gx + w, gy]) pop = int(g.getpop()) if pop < pstatus[0]: pstatus = (pop, num, phase, [gx + w, gy]) # Show results if the user presses certain keys event = g.getevent() if event.startswith("key x"): g.new('') put_result_pair(celllist, bstatus, pstatus) g.select(g.getrect()) g.copy() g.select([]) g.note( "Minimum bounding box and population collisions copied to clipboard." ) if event.startswith("key q"): g.new('') g.show("Search stopped.") put_result_pair(celllist, bstatus, pstatus) g.fit() g.exit() g.show( "Searching for a 1-glider destruction... press <x> to copy minimum bounding box and population results to clipboard; press <q> to quit. Stats: minimum bounding box %dx%d, minimum population %d" % (bstatus[0][0], bstatus[0][1], pstatus[0])) return bstatus, pstatus
def Placement(self, movementData, idx, attachedPatList, snip): while True: event = g.getevent() if event == "": self.ManageMove(attachedPatList[idx], movementData) elif "click" in event: if "right" in event: movementData.RevertState() idx = (idx + 1) % len(attachedPatList) movementData = self.GetMovementData(attachedPatList, idx) self.ManageMove(attachedPatList[idx], movementData) elif "left" in event: if snip == None: snip = PlacementSnippet(attachedPatList, idx, movementData) self.snippets.append(snip) else: snip.Update(attachedPatList, idx, movementData) movementData.UpdateCellDictionary(self.smarCells, snip.id) return elif "key" in event: if "space" in event: for i in xrange(0, 30): g.run(60) g.update() g.reset() g.update() elif "right" in event: movementData.delta += 1 elif "left" in event: movementData.delta -= 1 elif "delete" in event: movementData.RevertState() g.update() return
def drawlines(): global oldline, firstcell started = False oldmouse = "" while True: event = g.getevent() if event.startswith("click"): # event is a string like "click 10 20 left altctrlshift" evt, x, y, butt, mods = event.split() oldmouse = x + ' ' + y if started: # draw permanent line from start pos to end pos endx = int(x) endy = int(y) drawline(startx, starty, endx, endy) # this is also the start of another line startx = endx starty = endy oldline = [] firstcell = [] else: # start first line startx = int(x) starty = int(y) firstcell = [startx, starty, g.getcell(startx, starty)] g.setcell(startx, starty, drawstate) g.update() started = True g.show( "Click where to end this line (and start another line)...") else: # event might be "" or "key m none" if len(event) > 0: g.doevent(event) mousepos = g.getxy() if started and len(mousepos) == 0: # erase old line if mouse is not over grid if len(oldline) > 0: eraseline(oldline) oldline = [] g.update() elif started and len(mousepos) > 0 and mousepos != oldmouse: # mouse has moved, so erase old line (if any) and draw new line if len(oldline) > 0: eraseline(oldline) x, y = mousepos.split() oldline = drawline(startx, starty, int(x), int(y)) oldmouse = mousepos
def drawlines(): global oldline, firstcell started = False oldmouse = "" while True: event = g.getevent() if event.startswith("click"): # event is a string like "click 10 20 left altctrlshift" evt, x, y, butt, mods = event.split() oldmouse = x + ' ' + y if started: # draw permanent line from start pos to end pos endx = int(x) endy = int(y) drawline(startx, starty, endx, endy) # this is also the start of another line startx = endx starty = endy oldline = [] firstcell = [] else: # start first line startx = int(x) starty = int(y) firstcell = [ startx, starty, g.getcell(startx, starty) ] g.setcell(startx, starty, drawstate) g.update() started = True g.show("Click where to end this line (and start another line)...") else: # event might be "" or "key m none" if len(event) > 0: g.doevent(event) mousepos = g.getxy() if started and len(mousepos) == 0: # erase old line if mouse is not over grid if len(oldline) > 0: eraseline(oldline) oldline = [] g.update() elif started and len(mousepos) > 0 and mousepos != oldmouse: # mouse has moved, so erase old line (if any) and draw new line if len(oldline) > 0: eraseline(oldline) x, y = mousepos.split() oldline = drawline(startx, starty, int(x), int(y)) oldmouse = mousepos
def check_keyboard(): global runflag while 1: evt = g.getevent() if evt != "": g.show(state + " -- " + nextstate + " :: " + instr + "; regs=" + str(registers) + " -- 'r' to toggle run mode, any key to step") if evt == "key q none": g.setclipstr(s) g.exit() if evt == "key r none": runflag = 1 - runflag elif evt == "key g none": break else: g.doevent(evt) if runflag == 1: break
def EventLoop(): global volume, genspersec nextgen = 0.0 running = True while True: space = False event = g.getevent() if len(event) == 0: sleep(0.005) # don't hog CPU if idle elif event == "key space none": running = False space = True nextgen = 0 elif event == "key return none": running = not running elif event == "key h none": ShowHelp() elif event == "key up none": volume = min(1.0, volume + 0.1) ShowInfo() elif event == "key down none": volume = max(0.0, volume - 0.1) ShowInfo() elif event == "key = none" or event == "key + none": genspersec = min(30, genspersec + 1) ShowInfo() elif event == "key - none": genspersec = max(1, genspersec - 1) ShowInfo() else: g.doevent(event) # might be a keyboard shortcut if (running or space) and time() >= nextgen: g.run(1) if g.empty(): g.exit("The pattern died.") PlaySound() g.update() if not space: nextgen = time() + 1.0 / genspersec
def floodfill(): newstate = g.getoption("drawingstate") oldstate = newstate # wait for user to click a cell g.show("Click the region you wish to fill... (hit escape to abort)") while oldstate == newstate: 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 x < minx or x > maxx or y < miny or y > maxy: # click is outside pattern's bounding box in unbounded universe g.warn("Click within the pattern's bounding box\n"+ "otherwise the fill will be unbounded.") else: # note that user might have changed drawing state newstate = g.getoption("drawingstate") oldstate = g.getcell(x, y) if oldstate == newstate: g.warn("The clicked cell must have a different state\n"+ "to the current drawing state.") else: g.doevent(event) # tell Golly to handle all further keyboard/mouse events g.getevent(False) # do flood fill starting with clicked cell g.show("Filling clicked region... (hit escape to stop)") clist = [ (x,y) ] g.setcell(x, y, newstate) oldsecs = time() while len(clist) > 0: # remove cell from start of clist x, y = clist.pop(0) newsecs = time() if newsecs - oldsecs >= 0.5: # show changed pattern every half second oldsecs = newsecs g.update() # check if any orthogonal neighboring cells are in oldstate if checkneighbor( x, y-1, oldstate): g.setcell( x, y-1, newstate) clist.append( (x, y-1) ) if checkneighbor( x, y+1, oldstate): g.setcell( x, y+1, newstate) clist.append( (x, y+1) ) if checkneighbor( x+1, y, oldstate): g.setcell( x+1, y, newstate) clist.append( (x+1, y) ) if checkneighbor( x-1, y, oldstate): g.setcell( x-1, y, newstate) clist.append( (x-1, y) ) # diagonal neighbors are more complicated because we don't # want to cross a diagonal line of live cells if checkneighbor( x+1, y+1, oldstate) and (g.getcell(x, y+1) == 0 or g.getcell(x+1, y) == 0): g.setcell( x+1, y+1, newstate) clist.append( (x+1, y+1) ) if checkneighbor( x+1, y-1, oldstate) and (g.getcell(x, y-1) == 0 or g.getcell(x+1, y) == 0): g.setcell( x+1, y-1, newstate) clist.append( (x+1, y-1) ) if checkneighbor( x-1, y+1, oldstate) and (g.getcell(x, y+1) == 0 or g.getcell(x-1, y) == 0): g.setcell( x-1, y+1, newstate) clist.append( (x-1, y+1) ) if checkneighbor( x-1, y-1, oldstate) and (g.getcell(x, y-1) == 0 or g.getcell(x-1, y) == 0): g.setcell( x-1, y-1, newstate) clist.append( (x-1, y-1) )
def collect_dna(): # prepare environment env = environment() # ask user to select cell of interest g.setcursor("Pick") g.show('select cell to sample') event = g.getevent(True) #turn on golly event script access while not event.startswith("click"): event = g.getevent() # return event handling to golly # event is a string like "click 10 20 left none" g.getevent(False) # return event handling to golly evt, xstr, ystr, butt, mods = event.split() x = int(xstr) y = int(ystr) logging.info('cell ('+xstr+','+ystr+') selected') try: # retrieve selected cell selectedCell = env.cellList.findCell(x,y) except AttributeError: g.show('cannot find cell!') logging.error('cell not found. len(cellList)='+str(len(cellList.cells))) env.teardown() return # prompt user for name import Tkinter as tk root = tk.Tk() class selectorDisplay: def __init__(self, master, selectedCell): self.pallate = cellPallate() # cell pallate instance for saving cell info self.frame = tk.Frame(master) self.frame.pack() self.cell = selectedCell instructions = tk.Label(root, text='Please enter a name for this cell.\n\ NOTE: names should only consist of letters, numbers, "_", and "-"') instructions.pack() self.entry = tk.Entry(master) self.entry.pack() self.entry.focus_set() button_save = tk.Button(master, text="save", width=10, command=self.submitEntry) button_save.pack() button_cancel = tk.Button(master, text="cancel", width=10, command=self.frame.quit) button_cancel.pack() def submitEntry(self): # save the cell name = self.entry.get() g.show('saving ' + name + ' to ' + CELL_COLLECTION_DIR) self.pallate.saveCell(self.cell,name) self.frame.quit() # close dialog g.show('DNA sample saved to collection') app = selectorDisplay(root,selectedCell) root.mainloop() import _tkinter try: root.destroy() # optional...ish except _tkinter.TclError: pass # ignore failed destroy due to already being destroyed. env.teardown() return
return [-1, obj, x, y] objectArray = [] for d in data: objectArray.extend(GetObjectArray([g.parse(d[0]), d[1]])) moving = False g.show("Select known object with left click, exit with right click") handling = False searching = False while True: event = g.getevent() if handling or searching: continue handling = True if "click" in event: if "right" in event: g.show("finish smart movement") g.exit() if not moving: searching = True
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()
filename = g.getstring("Enter gencols filename:", "3g") symm = g.getstring("Enter symmetries (x, d or xd):", "default") if symm == "default": symm = "" if filename == "3g": symm += "x" if direction == "SE" and filename in ["2g", "3g", "s2g"]: symm += "d" status = "dir: %s; delay %d; inc %d; symm %s; " % (direction, delay, increase, symm) if finalpop >= 0: status += "finalpop %d; " % finalpop status += "cols %s; " % filename g.getevent() [a, b] = [1, 1000] if direction == "S" else [1000, 1001] cells = g.getcells(g.getrect()) cells = zip(cells[::3], cells[1::3], cells[2::3]) mx = -9999999 ox = oy = 0 for x, y, z in cells: if z != 3: continue idx = a * x + b * y if idx > mx: mx = idx
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 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()
genlist = [int(xfunc())] xlimlist = [int(g.getrect()[1])] oldsecs = time() for i in xrange(numsteps): g.step() poplist.append(int(yfunc())) genlist.append(int(xfunc())) newsecs = time() if newsecs - oldsecs >= 1.0: # show pattern every second oldsecs = newsecs fit_if_not_visible() g.update() g.show("Step %i of %i, Topo %i" % (i + 1, numsteps, posi)) event = g.getevent() if event.startswith("key"): evt, ch, mods = event.split() if ch == "q": out = 1 numsteps = i break fit_if_not_visible() # poplist.sort(key=dict(zip(poplist, genlist)).get) # save some info before we switch layers stepsize = "%i^%i" % (g.getbase(), g.getstep()) pattname = g.getname()
def burp(): test_signal=pattern(""" 40bo$41bo$39b3o17$40bo4bo4bo4bo4bo$41bo4bo4bo4bo4bo$39b3o2b3o2b3o2b3o 2b3o3$40bo4bo4bo4bo4bo$41bo4bo4bo4bo4bo$39b3o2b3o2b3o2b3o2b3o3$40bo4bo 4bo4bo4bo$41bo4bo4bo4bo4bo$39b3o2b3o2b3o2b3o2b3o3$40bo4bo4bo4bo4bo$41b o4bo4bo4bo4bo$39b3o2b3o2b3o2b3o2b3o3$bo38bo4bo4bo4bo4bo18bo$2bo38bo4bo 4bo4bo4bo18bo$3o36b3o2b3o2b3o2b3o2b3o16b3o37$40bo$41bo$39b3o!""") prepare_burp() ticks=0 tickstep=5 last_signal=-99999 viewport_speed=16 sel_speed=0.0 delta_sel=0.0 delay=-1.0 run_flag=False ch="" selx=600.0 sely=365.0 place_signal=3 helpstring="""Use ENTER and SPACE to run or halt the pattern; use + and - to change the step size or delay value; use arrow keys and mouse tools to pan and zoom in any pane; T toggles between a tiled view and a single-pane view; S creates another signal fleet near the detection mechanism; R resets the Heisenburp device to its initial state; Q quits out of the script and restores original settings.""" instr="Press H for help. " g.show(instr + str(tickstep)) g.select([selx,sely,50,50]) # keyboard handling while ch<>"q": if place_signal>0: if ticks-last_signal>1846: test_signal.put(-150,60) last_signal=ticks place_signal-=1 if place_signal>0 and run_flag==True: show_status_text("Next signal placement in " \ + str(1847 - ticks + last_signal) + " ticks. " + instr, delay, tickstep) else: show_status_text(instr,delay,tickstep) event = g.getevent() if event.startswith("key"): evt, ch, mods = event.split() else: ch = "" if ch=="r": prepare_burp() ticks=0 last_signal=-99999 viewport_speed=16 sel_speed=0 run_flag=False selx=600.0 sely=365.0 place_signal=3 g.select([selx,sely,50,50]) elif ch=="h": g.note(helpstring) elif ch=="t": g.setoption("tilelayers",1-g.getoption("tilelayers")) elif ch=="=" or ch=="+": if delay>.01: delay/=2 elif delay==.01: delay=-1 else: if tickstep==1: tickstep=3 elif tickstep<250: tickstep=(tickstep-1)*2+1 elif ch=="-" or ch=="_": if delay==-1: if tickstep==1: delay=.01 else: if tickstep==3: tickstep=1 else: tickstep=(tickstep-1)/2+1 else: if delay<1: delay*=2 elif ch=="space": run_flag=False elif ch=="return": run_flag=not run_flag elif ch=="s": place_signal+=1 else: # just pass any other keyboard/mouse event through to Golly g.doevent(event) # generation and selection speed handling if ch=="space" or run_flag==True: g.run(tickstep) currlayer = g.getlayer() if currlayer != 4: # user has switched layer so temporarily change it back # so we only change location of bottom right layer g.check(False) g.setlayer(4) x, y = getposint() oldticks=ticks ticks+=tickstep delta_view=int(ticks/viewport_speed) - int(oldticks/viewport_speed) if delta_view <> 0: # assumes diagonal motion for now setposint(x + delta_view, y + delta_view) sel = g.getselrect() if len(sel)<>0: x, y, w, h = sel if int(selx)<>x: # user changed selection # prepare to move new selection instead (!?!) # -- use floating-point selx, sely to account for fractional speeds selx=x sely=y else: selx+=sel_speed*tickstep sely+=sel_speed*tickstep g.select([selx, sely, w, h]) else: g.select([selx, sely, 50, 50]) if currlayer != 4: g.setlayer(currlayer) g.check(True) # change viewport speed at appropriate times to follow the action if oldticks<4570 and ticks>=4570: sel_speed=.666667 # one-time correction to catch up with the signal at high sim speeds g.select([600+(ticks-4570)*1.5, 365+(ticks-4570)*1.5, w, h]) if selx>2125: sel_speed=0 g.select([2125, sely+2125-selx, w, h]) if oldticks<4750 and ticks>=4750: viewport_speed=1.5 if oldticks<6125 and ticks>=6125: viewport_speed=16 if oldticks>=11995: viewport_speed=99999.9 # stop automatically after the last signal passes through the device if oldticks - last_signal<8705 and ticks - last_signal>=8705: run_flag=False if run_flag==True and delay>0: sleep(delay) g.update()
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()
def floodfill(): newstate = g.getoption("drawingstate") oldstate = newstate # wait for user to click a cell g.show("Click the region you wish to fill... (hit escape to abort)") while oldstate == newstate: 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 x < minx or x > maxx or y < miny or y > maxy: # click is outside pattern's bounding box in unbounded universe g.warn("Click within the pattern's bounding box\n" + "otherwise the fill will be unbounded.") else: # note that user might have changed drawing state newstate = g.getoption("drawingstate") oldstate = g.getcell(x, y) if oldstate == newstate: g.warn("The clicked cell must have a different state\n" + "to the current drawing state.") else: g.doevent(event) # tell Golly to handle all further keyboard/mouse events g.getevent(False) # do flood fill starting with clicked cell g.show("Filling clicked region... (hit escape to stop)") clist = [(x, y)] g.setcell(x, y, newstate) oldsecs = time() while len(clist) > 0: # remove cell from start of clist x, y = clist.pop(0) newsecs = time() if newsecs - oldsecs >= 0.5: # show changed pattern every half second oldsecs = newsecs g.update() # check if any orthogonal neighboring cells are in oldstate if checkneighbor(x, y - 1, oldstate): g.setcell(x, y - 1, newstate) clist.append((x, y - 1)) if checkneighbor(x, y + 1, oldstate): g.setcell(x, y + 1, newstate) clist.append((x, y + 1)) if checkneighbor(x + 1, y, oldstate): g.setcell(x + 1, y, newstate) clist.append((x + 1, y)) if checkneighbor(x - 1, y, oldstate): g.setcell(x - 1, y, newstate) clist.append((x - 1, y)) # diagonal neighbors are more complicated because we don't # want to cross a diagonal line of live cells if checkneighbor(x + 1, y + 1, oldstate) and (g.getcell( x, y + 1) == 0 or g.getcell(x + 1, y) == 0): g.setcell(x + 1, y + 1, newstate) clist.append((x + 1, y + 1)) if checkneighbor(x + 1, y - 1, oldstate) and (g.getcell( x, y - 1) == 0 or g.getcell(x + 1, y) == 0): g.setcell(x + 1, y - 1, newstate) clist.append((x + 1, y - 1)) if checkneighbor(x - 1, y + 1, oldstate) and (g.getcell( x, y + 1) == 0 or g.getcell(x - 1, y) == 0): g.setcell(x - 1, y + 1, newstate) clist.append((x - 1, y + 1)) if checkneighbor(x - 1, y - 1, oldstate) and (g.getcell( x, y - 1) == 0 or g.getcell(x - 1, y) == 0): g.setcell(x - 1, y - 1, newstate) clist.append((x - 1, y - 1))