Beispiel #1
0
def PrepareList(cells):
    g.new("")
    g.putcells(cells)
    cells = g.getcells(g.getrect())
    g.new("")
    g.putcells(cells, -cells[0], -cells[1])
    c = g.getcells(g.getrect())

    result = []

    for i in xrange(0, len(c), 2):
        x = c[i]
        y = c[i + 1]

        for dx in xrange(-1, 2):
            for dy in xrange(-1, 2):
                val = g.getcell(x + dx, y + dy)

                if (x + dx, y + dy, val) in result:
                    continue

                result.append((x + dx, y + dy, val))

    random.shuffle(result)

    return result
def GunArea(cells, curGunPeriod):

	maxBox = []
	minpop = -100000
	
	for i in xrange(0, curGunPeriod, 4):
		
		g.new(str(i))
		g.putcells(g.evolve(cells, i))
		
		g.setbase(8)
		g.setstep(3)
		g.step()
		g.step()
		
		edgeGlider = EdgeGlider()

		while PerformDelete(edgeGlider, curGunPeriod):
			edgeGlider = DevolveGlider(edgeGlider, curGunPeriod)
		
		for j in xrange(0, 4):
		
			if g.getpop() > minpop:
				maxpop = g.getpop()
				maxpopgun = g.getcells(g.getrect())
				
			maxBox = AppendBox(maxBox, g.getrect())
			g.run(1)
		
	return [BoxValue(maxBox), maxpopgun, maxBox]
Beispiel #3
0
def PrepareList(cells):
	g.new("")
	g.putcells(cells)
	cells = g.getcells(g.getrect())
	g.new("")
	g.putcells(cells, -cells[0], -cells[1])
	c = g.getcells(g.getrect())
	
	result = []
	
	for i in xrange(0, len(c), 2):
		x = c[i]
		y = c[i + 1]
		
		for dx in xrange(-1,2):
			for dy in xrange(-1, 2):
				val = g.getcell(x + dx, y + dy)
				
				if (x + dx, y + dy, val) in result:
					continue
					
				result.append((x + dx, y + dy, val))

	random.shuffle(result)
	
	return result
Beispiel #4
0
def UpdateMove(d, w, h, x0, y0, p, t):
   
   under = d[0]
   obj = d[1]
   x = d[2]
   y = d[3]
   
   
   if under != -1:
      ClearRect(x - w, y - h, 2 * w + 1, 2 * h + 1)
      g.putcells(under)
   
   
   val = g.getxy()
   
   if val == "":
      return 
      
   
   x1 = int(val.split()[0])
   y1 = y0 + GetDirection(t) * (x1 - x0)
   
   d[0] = g.getcells([x1 - w, y1 - h, 2 * w + 1, 2 * h + 1])
   
   #ClearRect(x1 - w, y1 - h, 2 * w + 1, 2 * h + 1)
   
   g.putcells(g.evolve(obj, p + GetEvolveDirection(t) * ((4 * (x1 - x0)) % p)), x1, y1)
   
   g.update()
   
   d[2] = x1
   d[3] = y1
def PlaceReadingHeads(hwssRecipe):

	g.new("")
	g.setrule("LifeHistoryNoMark")
	
	if directionType == "B":
		for y in xrange(-3 * len(hwssRecipe), 1):
			MakeBackwardSalvo(step, 0, distBack * y, step * len(hwssRecipe) + 100, y == 0, y == 0)
		
		MakeBackwardRecipe(step, 0, 0, hwssRecipe)
		
	else:
		helixD = -step * len(hwssRecipe) - 1000
		
		while helixD % 7500 != 0:
			helixD -= 1
			
		for y in xrange(0, 3 * len(hwssRecipe) + 1):
		   MakeForwardSalvo(step, 0, distForward * y, helixD, y == 0, y == 0)
		
		MakeForwardRecipe(helixD, step, 0, 0, hwssRecipe)
		
		cells = []
		for i in xrange(fenseY, -helixD + 201):
			
			cells.append(240)
			cells.append(i + helixD)
			cells.append(6)
		
		g.putcells(cells)
Beispiel #6
0
def envelope():
    # draw stacked layers using same location and scale
    g.setoption("stacklayers", 1)

    g.show("Hit escape key to stop script...")
    while True:
        g.run(1)
        if g.empty():
            g.show("Pattern died out.")
            break

        # copy current pattern to envelope layer;
        # we temporarily disable event checking so thumb scrolling
        # and other mouse events won't cause confusing changes
        currpatt = g.getcells(g.getrect())
        g.check(0)
        g.setlayer(envindex)
        g.putcells(currpatt)
        g.setlayer(currindex)
        g.check(1)

        step = 1
        exp = g.getstep()
        if exp > 0:
            step = g.getbase()**exp
        if int(g.getgen()) % step == 0:
            # display all 3 layers (envelope, start, current)
            g.update()
Beispiel #7
0
def envelope ():
    # draw stacked layers using same location and scale
    g.setoption("stacklayers", 1)

    g.show("Hit escape key to stop script...")
    while True:
        g.run(1)
        if g.empty():
            g.show("Pattern died out.")
            break

        # copy current pattern to envelope layer;
        # we temporarily disable event checking so thumb scrolling
        # and other mouse events won't cause confusing changes
        currpatt = g.getcells(g.getrect())
        g.check(0)
        g.setlayer(envindex)
        g.putcells(currpatt)
        g.setlayer(currindex)
        g.check(1)

        step = 1
        exp = g.getstep()
        if exp > 0:
            step = g.getbase()**exp
        if int(g.getgen()) % step == 0:
            # display all 3 layers (envelope, start, current)
            g.update()
def GunArea(cells, curGunPeriod):

	maxBox = [10000, 10000, -1000, -1000]
	
	for i in xrange(0, curGunPeriod, 4):
		
		g.new(str(i))
		g.putcells(g.evolve(cells, i))
		
		g.setbase(8)
		g.setstep(3)
		g.step()
		g.step()
		g.step()
		g.step()
		
		
		edgeGlider = EdgeGlider()

		while PerformDelete(edgeGlider, curGunPeriod):
			edgeGlider = DevolveGlider(edgeGlider, curGunPeriod)
		
		for j in xrange(0, 4):
			maxBox = AppendBox(maxBox, g.getrect())
			g.run(1)
		
		if i == 0:
			somegun = g.getcells(g.getrect())
		
	return [BoxValue(maxBox), somegun, maxBox]
def GunPlacer(gunCollection):

	g.new("")
	
	for i in xrange(0, len(gunCollection)):
		g.putcells(gunCollection[i], 0, 0);
		PlaceNumber(i + 14, -150, i * 650)
Beispiel #10
0
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)
Beispiel #11
0
def PlaceRecipeList(recipes):
	
	if len(recipes) == 0:
		return 
	
	g.new("")
	dx = 0
	
	recipes.sort(key=lambda f: str(f[3]))
	curF = str(recipes[0][3])
	f = open(destinationPath + str(len(recipes)) + curF + ".txt",'w')
	
	for res in recipes:
		recipe = res[0]
		x1 = res[1]
		y1 = res[2]
		slL = res[3]
				
		g.putcells(blck, dx, 0)
		d = 0 
		for r in recipe:
			g.putcells(gld, 40 + d * 256 + dx, 40 + r + d * 256)
			d += 1
			
		dx += 256
		
		if curF != str(slL):
			f.close() 
			curF = str(slL)
			f = open(destinationPath + str(len(recipes)) + curF + ".txt",'w')
			
		f.write("{0},{1}:".format(x1, y1) + str(recipe).strip("]").strip("[") + "\n")
Beispiel #12
0
def main():

    g.setstep(0)
    g.setalgo('QuickLife')

    velocity = g.getstring('Please specify velocity', '(2,1)c/6')
    a, b, p = parse_velocity(velocity)
    params = partial_derivatives(a, b, p)

    dvdx = params['dvdx']
    dudx = params['dudx']
    dvdy = params['dvdy']
    dudy = params['dudy']
    dvdt = params['dvdt']
    dudt = params['dudt']

    cells = []

    for t in xrange(p):

        things = g.getcells(g.getrect())
        things = zip(things[::2], things[1::2])
        cells += [(dudx * x + dudy * y + dudt * t,
                   dvdx * x + dvdy * y + dvdt * t) for (x, y) in things]
        g.step()

    g.setlayer(g.addlayer())
    g.putcells([x for y in cells for x in y])
Beispiel #13
0
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 
Beispiel #14
0
def makerecipe(background, gliderlist):
    g.new("Recipe")
    g.putcells(background)
    offset = max(background[1::2]) + 4
    for glider, delta in gliderlist:
        clist, lane = glider
        g.putcells(clist, (lane + 1) // 2 + offset, offset)
        offset += delta
Beispiel #15
0
def testRule(rulestr):
    r = g.getrect()
    if r:
        g.select(r)
        g.clear(0)
    g.putcells(origPatt)
    g.setrule(rulestr)
    g.run(stabGen)
    if g.empty():
        return ()
    pop = int(g.getpop())
    if (pop < minPop or pop > maxPop):
        return ()
    r = g.getrect()
    testPatt = g.transform(g.getcells(r), -r[0], -r[1])
    testPop = int(g.getpop())
    testRect = g.getrect()
    stabPatt = list(testPatt)
    stabPop = testPop
    for ii in xrange(maxGen):
        g.run(1)
        pop = int(g.getpop())
        if (pop < minPop or pop > maxPop):
            break
        if (pop == testPop):
            # Test for periodicity
            r = g.getrect()
            if testPatt == g.transform(g.getcells(r), -r[0], -r[1]):
                period = ii + 1
                dy, dx = sss.minmaxofabs(
                    (r[0] - testRect[0], r[1] - testRect[1]))
                if (dx == 0):
                    # Oscillator (reject if low period or bOsc is False)
                    if bOsc and period >= minOscP:
                        return (0, 0, period)
                elif (period >= minShipP):
                    # Spaceship
                    return (dx, dy, period)
                elif ((dx + dy / 1.9) / (period * 1.0) > minSpeed
                      and period >= fastShipP):
                    # Fast spaceship
                    return (dx, dy, period)
                break  # Pattern is a low period oscillator or spaceship
        # Stability check
        if (ii % stabCheckP == 0):
            r = g.getrect()
            # First check for BBox expansion
            if maxDim > 0 and max(r[2:4]) > maxDim:
                # Pattern is expanding
                # XXX Attempt to separate components expanding in different directions
                break
            currPatt = g.transform(g.getcells(r), -r[0], -r[1])
            if (pop == stabPop and currPatt == stabPatt):
                # Pattern has stabilised to low period oscillator / spaceship
                break
            stabPop = pop
            stabPatt = list(currPatt)
    return ()
def 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))
Beispiel #17
0
def EvolveRecipe(recipe):
	g.new("")
	g.setstep(3)
	
	g.putcells(blck)
	
	for r in recipe:
		g.putcells(gld, 40, 40 + r)
		g.step()
		g.step()
	def PlaceRecipe(self, x = 0, y = 0, makenew = True):
		if makenew:
			g.new("Results")
			
		g.show(str(self.recipeIdxList))
		g.setclipstr(str(self.recipeIdxList))
		g.putcells(blck, x, y)
		i = 0 
		for r in self.recipe:
			g.putcells(gld, x + 80 + i * 128, y + 80 + i * 128 + r)
			i += 1
Beispiel #19
0
def main():
    apgcode = canonise()
    if not apgcode:
        g.warn(
            'Failed to detect periodic behaviour after {} generations.'.format(
                MAXPERIOD))

    # 2G collisions
    if apgcode in twoGcols:
        cols = twoGcols[apgcode]
    else:
        cols = []
    # 3G and 4G collisions
    for cFile in compFiles:
        with open(cFile) as cF:
            found_code = False
            for l in cF:
                line = l.strip()
                if not found_code:
                    if line == apgcode:
                        found_code = True
                    continue
                elif '>' in line:
                    in_code, gstr, _ = line.split(">")
                    if in_code:
                        g.warn(
                            'Non-empty starting target in glider collision - Not implemented'
                        )
                    else:
                        cols.append(gstr)
                else:
                    break

    Ncols = len(cols)
    if Ncols:
        try:
            cols = [reconstruct(col) for col in cols]
        except Exception:
            g.note(str(cols))
        g.new("solutions")
        g.show("{} collisions found".format(Ncols))
        g.setname(apgcode)
        if Ncols <= 20:
            N = 5
        else:
            N = math.ceil(math.sqrt(Ncols)) + 1
        offset = 100
        for i, col in enumerate(cols):
            g.putcells(col, int((i % N) * offset), int((i // N) * offset))
        g.fit()
    else:
        g.note(
            "No glider collisions found for constellation {}. Better luck next time"
            .format(apgcode))
def fill_void():
    # sample incremental 46P4H1V0 synthesis
    pat = g.parse(
        """1422bo$1422bobo$1422b2o6$1217bo$1218bo191bo$1216b3o141bo50b2o$1226bo
133bobo47b2o$1226bobo127bo3b2o$1226b2o53bo75b2o37bobo29bobo$1276bobo2b
obo72b2o39b2o15bo13b2o$1277b2o2b2o70bo43bo14bobo14bo$1277bo73bobo59b2o
$1343bo8b2o53bo11bo$1284bo57bobo3bo57bobo3bo5bobo$642bo517bo123bo58b2o
3bo39bobo16b2o3bo5b2o16bobo$62bo13bo54bo510bobo513bobo123bo63bo40b2o6b
o14bo16bo6b2o$60bobo13bobo52bobo3bobo365bo132bo3b2o397bo117b2o3bo224bo
5bobo31bobo5bo$61b2o13b2o53b2o4b2o43bobo133bo58bo125bobo133b2o81bobo
119bo68bo127bobo108b2o8b2o52b2o7b2o44b3o6b2o7b2o53b2o7b2o41b2o10b2o7b
2o10b2o$138bo44b2o133bobo57b2o124b2o68bo63b2o82b2o118bobo66b2o128b2o
57bo50bobo9b2o50bobo7bobo45bo5bobo7bobo51bobo7bobo51bobo7bobo$140bo42b
o13bo63bo56b2o5bo51b2o10bo63bo63bo54bobo6bo63bo63bo13bo49bo63bo5b2o56b
o10b2o51bo63bo63bo6bobo48bo5bo57bo5bo5bo44bo6bo5bo5bo51bo5bo5bo51bo5bo
5bo$o60b3o11b3o53bo3bo3b2o45bobo7bobo61bobo53bo7bobo61bobo61bobo61bobo
54b2o5bobo61bobo61bobo7bobo51bobo61bobo7bo53bobo61bobo61bobo61bobo5b2o
48b2o4bobo55b2o4bobo4b2o49b2o4bobo4b2o49b2o4bobo4b2o49b2o4bobo4b2o$b2o
60bo11bo54bobobobo2bobo45b2o7bobo61bobo51bobo7bobo53b2o6bobo61bobo61bo
bo61bobo61bobo61bobo7b2o52bobo61bobo7bobo51bobo6b2o53bobo61bobo61bobo
61bobo61bobo61bobo61bobo61bobo$2o60bo13bo54b2ob2o51bo7b2ob2o59b2ob2o
51b2o6b2ob2o51bo2bo4b2ob2o59b2ob2o59b2ob2o54bo4b2ob2o59b2ob2o59b2ob2o
7bo51b2ob2o59b2ob2o6b2o51b2ob2o4bo2bo51b2ob2o54bo4b2ob2o54bo4b2ob2o4bo
54b2ob2o59b2ob2o59b2ob2o59b2ob2o59b2ob2o$257bo7bo55bo7bo50b2o3bo7bo55b
o7bo55bo7bo51bobobo7bo52bo2bo7bo55bo63bo7bo55bo7bo55bo7bo3b2o50bo7bo
51bobobo7bo51bobobo7bobobo48bo2bo7bo2bo42bo6bo2bo7bo2bo6bo42bo2bo7bo2b
o49bo2bo7bo2bo49bo2bo7bo2bo$6bo42b2o5bo25bo5b2o39b4ob4o45bo9b4ob4o55b
4ob4o55b4ob4o45bo9b4ob4o55b4ob4o55b4ob4o52b2ob4ob4o52b7ob4o55b4ob4o9bo
45b4ob4o55b4ob4o55b4ob4o9bo45b4ob4o52b2ob4ob4o52b2ob4ob4ob2o49b7ob7o
40bobo6b7ob7o6bobo40b7ob7o49b7ob7o49b7ob7o$6bobo39bobo6bo9bo3bo9bo6bob
o38bo2bobo2bo46bo8bo2bobo2bo58bobo61bobo49b2o10bobo61bobo61bobo61bobo
61bobo61bobo2bo8bo49bobo61bobo61bobo10b2o49bobo61bobo61bobo61bobo47b2o
12bobo12b2o47bobo61bobo41bo19bobo19bo$2bo3b2o42bo4b3o8bobobobo8b3o4bo
41bobobobo45b3o3bo5bobobobo56b2obobob2o55b2obobob2o45b2o2b3o3b2obobob
2o53b4obobob2o53b4obobob2o52b5obobob2o52b5obobob2o55b2obobobo5bo3b3o
42b4obobob2o53b4obobob2o53b4obobob2o3b3o2b2o43b4obobob4o50b5obobob4o
50b5obobob5o49b5obobob5o44b2o3b5obobob5o3b2o40b2o2b5obobob5o2b2o41b2o
2b5obobob5o2b2o31b2o8b2o2b5obobob5o2b2o8b2o$3b2o62b2ob2o59b2ob2o53bo5b
2ob2o57bob2ob2obo55bob2ob2obo51bo3bob2ob2obo52bo2bob2ob2obo52bo2bob2ob
2obo52bo2bob2ob2obo52bo2bob2ob2obo55bob2ob2o5bo48bo2bob2ob2obo52bo2bob
2ob2obo52bo2bob2ob2obo3bo48bo2bob2ob2obo2bo49bo2bob2ob2obo2bo49bo2bob
2ob2obo2bo49bo2bob2ob2obo2bo43bobo3bo2bob2ob2obo2bo3bobo39b2o2bo2bob2o
b2obo2bo2b2o41b2o2bo2bob2ob2obo2bo2b2o30bobo8b2o2bo2bob2ob2obo2bo2b2o
8bobo$2b2o183b3o182b3o5bo65b2o61bobo205b3o46b2o62b2o62b2o14bo5b3o38bob
o11b2o62bobo172bo21bo$54b3o25b3o289bo67bo67bo405bo41bo17bo59bo$56bo25b
o105bo184bo8b2o59b2o273bo188b2o8bo56b2o$55bo27bo103b2o65b2o121b2o2bo2b
o57b2o8b2o264b2o59b2o125bo2bo2b2o51b2o8b2o$187bobo59b3ob2o121bobo2bo2b
o63bo2b2o50b2o212bobo60b2ob3o120bo2bo2bobo51b2o2bo71b2o$194b2o55bo3bo
122bo3b2o64b2o3bo50b2o205b2o66bo3bo123b2o3bo52bo3b2o70b2o$194bobo53bo
196bobo53bo3b2o201bobo71bo184bobo66b2o3bo348b3o21b3o13b3o$194bo245b3o
56b2o5b2o204bo263b3o60b2o5b2o346bo6b2o13bo7b2o6bo$442bo57b2o6bo467bo
61bo6b2o346bo8b2o8b2o3bo5b2o8bo$441bo57bo477bo69bo353bo9bobo11bo$443b
3o527b3o437bo$443bo531bo$444bo529bo!""")
    g.putcells(pat)
Beispiel #21
0
def MakeForwardRecipe(helixSLdy, distance, dx, dy, recipe): 
	d = (distance - 98) / 2

	frontSL = g.parse("bo$obo$o2bo$b2o!", 132 + d + dx, 314 + d + dy)
	curd = helixSLdy + distance

	for r in recipe: 
	  if r != 'SKIP':	
		g.putcells(frontSL, 0, curd + r)

	  curd += distance
Beispiel #22
0
def MakeBackwardRecipe(distance, dx, dy, recipe): 
   d = (distance - 144) / 2
   backSL = g.parse("b2o$o2bo$obo$bo!", 6 - d + dx, 629 - d + dy)
   curd = distance + 2
   
   recipe.insert(0, -4)
   
   for r in recipe: 
   	  if r != 'SKIP':	
		g.putcells(backSL, 0, curd - r)

   	  curd += distance
Beispiel #23
0
def FinishMove(d, w, h, x0, y0, p, t):
	
   under = d[0]
   obj = d[1]
   x = d[2]
   y = d[3]
   
   if under != -1:
      g.putcells(under)
	  
   g.putcells(g.evolve(obj, p + GetEvolveDirection(t) * ((4 * (x - x0)) % p)), x, y)
   
   g.update()
def find_best_selection():
    r = g.getrect()
    all = g.getcells(r)
    sep = 1
    # - run the pattern for 4096 ticks, get the new settled pattern
    # - try XORing new pattern with original pattern for every possible offset up to 512
    # - one of the offsets should give the lowest total population
    #      (will probably decrease the population instead of increasing it,
    #       unless what is being built is a prolific puffer or gun or some such)
    bestscore, bestsep = len(all), -1  # = population * 2
    allplus4096 = g.evolve(all, 4096)
    g.addlayer()
    while sep <= 512:
        g.show("Finding stage spacing -- testing " + str(sep))
        g.new("sep=" + str(sep))
        g.putcells(all)
        g.putcells(allplus4096, sep, 0, 1, 0, 0, 1, "xor")
        score = int(g.getpop())
        if bestscore > score: bestscore, bestsep = score, sep
        sep += 1
    g.dellayer()

    sep = bestsep
    g.show("found separation: " + str(sep))
    bestblockscore, bestoffset = -999999, -1
    for offset in range(sep):
        g.select([r[0] - offset, r[1], sep, r[3]])
        g.update()
        blockscore = 0
        for blockx in range(r[0] - offset, r[0] + r[2], sep):
            g.select([blockx, r[1], sep, r[3]])
            blockrect = g.getselrect()
            block = g.getcells(blockrect)
            if len(
                    block
            ) == 0:  # ran into empty block, this must not be the right separation
                g.exit("Invalid pattern format found at separation = " +
                       str(sep) + ": selected block is empty.")
            g.shrink(1)
            shrunkblockrect = g.getselrect()
            leftdiff = shrunkblockrect[0] - blockrect[0]
            rightdiff = (blockrect[0] + blockrect[2]) - (shrunkblockrect[0] +
                                                         shrunkblockrect[2])
            blockscore += leftdiff + rightdiff
            if leftdiff < 10: blockscore -= (10 - leftdiff)**2
            if rightdiff < 10: blockscore -= (10 - rightdiff)**2
        if blockscore > bestblockscore:
            bestblockscore, bestoffset = blockscore, offset
    g.select([r[0] - bestoffset, r[1], r[2] + offset, r[3]])
    return sep
Beispiel #25
0
	def draw(self, addstr = ""):
		
		xy = [] 
		xz = [] 
		yz = [] 
		proj = []
		
		for (k, v) in self.cur_state.items():
			x, y, z = k
			
			xy.append(x)
			xy.append(y)
			
			xz.append(x + 128)
			xz.append(z)
			
			yz.append(y)
			yz.append(z + 128)
		
			proj.append(x + y + z + 128)
			proj.append(- x + y + z + 128)
			
		if len(g.getrect()) > 0:
			g.select(g.getrect())
			g.clear(0)
			g.select([])
		
		g.putcells(xy)
		g.putcells(xz)
		g.putcells(yz)
		g.putcells(proj)
		g.setpos("64", "64")
		g.setmag(1)
		g.show("Size: {0}, (w, d, h): {1}".format(self.get_pop(), str(self.get_wdh())) + addstr)
		g.update()
Beispiel #26
0
    def draw(self):

        xy = []
        xz = []
        yz = []
        proj = []

        for (k, v) in self.cur_state.items():
            x, y, z = k

            xy.append(x)
            xy.append(y)

            xz.append(x + 128)
            xz.append(z)

            yz.append(y)
            yz.append(z + 128)

            proj.append(x + y + z + 128)
            proj.append(-x + y + z + 128)

        if len(g.getrect()) > 0:
            g.select(g.getrect())
            g.clear(0)
            g.select([])

        g.putcells(xy)
        g.putcells(xz)
        g.putcells(yz)
        g.putcells(proj)
        g.setpos("64", "64")
        g.setmag(1)
        g.update()
Beispiel #27
0
def LeftMost(recipe):

	g.putcells(block_cells)
	
	idx = 1
	for r in recipe:
		#g.putcells(glider_cells, 80, 80 + r )
		g.putcells(glider_cells, 160 * idx, 160 * idx + int(r))
		idx += 1
		#g.step()
		
	rect = g.getrect()
	
	return rect[0]
Beispiel #28
0
def LeftMost(recipe):

    g.putcells(block_cells)

    idx = 1
    for r in recipe:
        #g.putcells(glider_cells, 80, 80 + r )
        g.putcells(glider_cells, 160 * idx, 160 * idx + int(r))
        idx += 1
        #g.step()

    rect = g.getrect()

    return rect[0]
Beispiel #29
0
def AdaptiveGoto(hwssRecipe, enablePrinting=True):

    #g.setrule("LifeHistory")
    fense50 = g.parse(
        "F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F!"
    )

    helixD = CalcHelix(hwssRecipe)

    curgen = -helixD * 2
    curgen += 2 * distForward

    goto(curgen)
    g.setbase(8)
    g.setstep(3)

    delta = 10
    lastmaxi = delta
    idx = 0

    for i in hwssRecipe:

        if enablePrinting and (100 * (idx + 1)) / len(hwssRecipe) != (
                100 * idx) / len(hwssRecipe):
            percent = (100 * (idx + 1)) / len(hwssRecipe)
            g.update()

            g.show("Iterating forward progress " + str(percent) + "%")

        curgen += 2 * distForward
        idx += 1

        while int(g.getgen()) < curgen:
            g.step()

        if i == 'SKIP':
            continue

        if i > lastmaxi:

            g.select([fenseX, helixD + fenseY + lastmaxi - delta, 1, delta])
            g.clear(0)
            lastmaxi += delta
            #g.update()

        if i < lastmaxi - delta:
            g.putcells(fense50, fenseX, helixD + fenseY + lastmaxi - 2 * delta)
            lastmaxi -= delta
Beispiel #30
0
def Validate(recipe):

    g.new("")
    g.setstep(3)

    g.putcells(block_cells)

    for r in recipe:
        g.putcells(glider_cells, 120, 120 + r)
        #g.putcells(glider_cells, 80, 80 + 2 - r )
        g.step()
        g.step()

    rect = g.getrect()

    return rect
Beispiel #31
0
def LeftMost(recipe):

	g.new("")
	g.setstep(3)
	
	g.putcells(block_cells)
	
	for r in recipe:
		#g.putcells(glider_cells, 80, 80 + r )
		g.putcells(glider_cells, 80, 80 + 2 - r )
		g.step()
		g.step()
		
	rect = g.getrect()
	
	return rect[0]
def AddText(val, x, y):
	t = make_text(val, "mono")
	newt = []
	cnt = 0 

	for i in t:
	   cnt += 1
	   newt.append(i)
	   
	   if cnt % 2 == 0:
		  newt.append(4)
		  
	if len(newt) % 2 == 0:
	   newt.append(0)
	   
	g.putcells(newt, x, y)
Beispiel #33
0
def AddText(val, x, y):
    t = make_text(val, "mono")
    newt = []
    cnt = 0

    for i in t:
        cnt += 1
        newt.append(i)

        if cnt % 2 == 0:
            newt.append(4)

    if len(newt) % 2 == 0:
        newt.append(0)

    g.putcells(newt, x, y)
def Validate(recipe):

	g.new("")
	g.setstep(3)
	
	g.putcells(block_cells)
	
	for r in recipe:
		g.putcells(glider_cells, 120, 120 + r)
		#g.putcells(glider_cells, 80, 80 + 2 - r )
		g.step()
		g.step()
		
	rect = g.getrect()
	
	return rect
Beispiel #35
0
def LeftMost(recipe):

    g.new("")
    g.setstep(3)

    g.putcells(block_cells)

    for r in recipe:
        #g.putcells(glider_cells, 80, 80 + r )
        g.putcells(glider_cells, 80, 80 + 2 - r)
        g.step()
        g.step()

    rect = g.getrect()

    return rect[0]
def PlaceNumber(number, x = 0, y = 0):
	if number < 0: 
		g.putcells(figure8[3], x, y)
		PlaceNumber(-number, x, y)
		return
	  
	curNum = number
	d = 20 * NumDigit(number)
	
	while True:
		PlaceDigit(curNum%10, x + d, y)
		curNum = (curNum - curNum%10) / 10 
		
		if curNum == 0:
			return 
		
		d -= 20
Beispiel #37
0
def show_it(recipe, lane, move, elbow_type, start_elbow):

    global offset

    start_cells, start_type, start_lane = start_elbow

    res = ""
    phase = 0
    if lane is not None:
        direction = lane[1]
        phase = lane[2]
        if direction == 0:
            res = "Rev%d" % lane[0]
        elif direction == 1:
            res = "R%d" % (lane[0] - start_lane)
        elif direction == 2:
            res = "L%d" % (lane[0] - start_lane)
#        elif direction == 3:
#            res = "LWSS_W"
#        elif direction == 4:
#            res = "LWSS_S"

    if move is None:
        res += "k"
    else:
        res += "m%d%s%s" % (move - start_lane, str(start_type), elbow_type)

    g.putcells(make_text(res, "mono"), offset, -80)

    g.putcells(start_cells, offset, 0)

    for i, t in enumerate(recipe[::2]):
        if t is not None:
            d = 80*i + MAX_DIFF / 4 + 20
            g.putcells(g.evolve(G1, t + MAX_DIFF), offset-d, d)

    for i, t in enumerate(recipe[1::2]):
        if t is not None:
            d = 80*i + MAX_DIFF / 4 + 20
            g.putcells(g.evolve(G2, t + MAX_DIFF), offset-d, d)

    res += ": "

    for i in range(0, len(recipe), 2):
        if recipe[i] is None:
            res += "eo"[(recipe[i+1]+phase)%2] + "-9999 "
        elif recipe[i+1] is None:
            res += "eo"[(recipe[i]+phase)%2] + "9999 "
        else:
            res += "eo"[(recipe[i]+phase)%2] + str(recipe[i]-recipe[i+1]) + " "
           
    f.write(res + "\n")
    f.flush()

    offset += 100
    g.update()
Beispiel #38
0
def EvolveRecipe(recipe):
	g.new("")
	g.setstep(3)
	
	g.putcells(blck)
	
	minx = g.getrect()[0]
	
	for r in recipe:
		g.putcells(gld, 40, 40 + r)
		g.step()
		g.step()
		
		if minx > g.getrect()[0]:
			minx > g.getrect()[0]
	
	return minx
Beispiel #39
0
def AdaptiveGoto(hwssRecipe, enablePrinting = True):

	#g.setrule("LifeHistory")
	fense50 = g.parse("F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F!")

	helixD = CalcHelix(hwssRecipe)
		
	curgen = -helixD * 2
	curgen += 2 * distForward
	
	goto(curgen)
	g.setbase(8)
	g.setstep(3)
	
	delta = 10
	lastmaxi = delta
	idx = 0
	
	for i in hwssRecipe:
		
		if enablePrinting and (100 * (idx + 1)) / len(hwssRecipe) != (100 * idx) / len(hwssRecipe):
			percent = (100 * (idx + 1)) / len(hwssRecipe)
			g.update()
			
			g.show("Iterating forward progress " + str(percent) + "%")
			
		curgen += 2 * distForward
		idx += 1
		
		while int(g.getgen()) < curgen:
			g.step()
			
		if i == 'SKIP':
			continue 
			
		if i > lastmaxi:
			
			g.select([fenseX, helixD + fenseY + lastmaxi - delta, 1, delta])
			g.clear(0)
			lastmaxi += delta
			#g.update()
			
		if i < lastmaxi - delta:
			g.putcells(fense50, fenseX, helixD + fenseY + lastmaxi - 2 * delta)
			lastmaxi -= delta
Beispiel #40
0
def CalculateLane(cells):
    g.new("")
    g.putcells(cells)
    cells = g.getcells(g.getrect())
    g.new("")
    g.putcells(cells, -cells[0], -cells[1])

    minx = 1000
    maxx = -1000

    for i in xrange(0, 4):
        rect = g.getrect()

        minx = min(minx, rect[0])
        maxx = max(maxx, rect[0] + rect[2])
        g.run(1)

    return (minx, maxx)
Beispiel #41
0
def CalculateLane(cells):
	g.new("")
	g.putcells(cells)
	cells = g.getcells(g.getrect())
	g.new("")
	g.putcells(cells, -cells[0], -cells[1])
	
	minx = 1000
	maxx = -1000
	
	for i in xrange(0, 4):
		rect = g.getrect()
		
		minx = min(minx, rect[0])
		maxx = max(maxx, rect[0] + rect[2])
		g.run(1)
		
	return (minx, maxx)
def run_patt(known_cells):
    global patt_count, meth_count
    g.new("PlutoniumSearch")
    g.reset()
    g.update()
    patt_count += 1
    #patt = g.parse(known_cells + "!")
    patt = g.parse(known_cells[1:] + "!")
    #g.note(known_cells[1:] + "!")
    g.putcells(patt)
    g.update()
    hashlist = {}
    for gene in range(999):
        if g.empty():
            break
        if g.hash(g.getrect()) in hashlist:
            p = int(g.getgen()) - hashlist[g.hash(g.getrect())]
            if not p in boring_periods:
                g.reset()
                g.save("p" + str(p) + "_" + str(cnt[p]) + ".rle", "rle")
                cnt[p] += 1
            break
        else:
            hashlist[g.hash(g.getrect())] = int(g.getgen())
            g.run(1)
        """
		except:
			# Pattern dies
			if int(g.getgen()) > min_lifespan:
				meth_count += 1
				newlifespan = int(g.getgen())
				g.new("Saving methuselah")
				g.putcells(patt)
				try:
					g.save("diehard-" + str(newlifespan) + ".rle", "rle")
				except:
					pass
				g.update()
				#max_final_pop = newpop
			break"""
    #g.warn(str(hashlist))
    g.show(str(patt_count) + "/" + str(2**(bx * by)))
Beispiel #43
0
def canon5Sship(ship, maxgen=2000):
    minpop, rulestr, dx, dy, period, shiprle = ship
    shipPatt = g.parse(shiprle)
    # Transform ship to canonical direction
    if abs(dx) >= abs(dy):
        a, b, c, d = sign(dx), 0, 0, sign(dy)
    else:
        a, b, c, d = 0, sign(dy), sign(dx), 0
    dy, dx = minmaxofabs((dx, dy))
    shipPatt = g.transform(shipPatt, 0, 0, a, b, c, d)
    # Clear the layer and place the ship
    r = g.getrect()
    if r:
        g.select(r)
        g.clear(0)
    g.putcells(shipPatt)
    shiprle = giveRLE(g.getcells(g.getrect()))
    g.setrule(rulestr)
    # Determine the minimal isotropic rule
    setminisorule(period)
    return minpop, g.getrule(), dx, dy, period, shiprle
def PerformDelete(glider, gunPeriod):

	initCells = g.getcells(g.getrect())
	
	for j in xrange(0, len(glider), 2):
		if g.getcell(glider[j], glider[j + 1]) != 1:
			return False
	
	Erase(glider)
	rect = g.getrect()
	cells = g.getcells(rect)
	g.run(gunPeriod)
	
	if str(g.getcells(rect)) == str(cells):
		g.new("")
		g.putcells(cells)
		return True
	else:
		g.new("")
		g.putcells(initCells)
		return False
Beispiel #45
0
def setupT(dhead, binaryStr, dx, dy):
    setupR(dhead, dx, dy)
    setupR(len(binaryStr) - 1 - dhead, dx + 310, dy - 506)
    setupR(dhead * 16, dx + 130, dy - 3286)
    setupR(dhead * 16, dx - 1113, dy - 2062)

    if len(binaryStr) == 0:
        return

    x = dx + 142
    y = dy - 3305
    g.select([x, y, 3, 3])
    g.clear(0)

    for i in range(len(binaryStr)):
        if binaryStr[i] == '0':
            g.putcells(boat, x, y)
        else:
            g.putcells(boat, x - 3, y - 3)

        x -= 16
        y -= 16
Beispiel #46
0
def AdaptiveGoto(hwssRecipe):

	#g.setrule("LifeHistory")
	fense50 = g.parse("F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F!")

	helixD = -step * len(hwssRecipe) - 1000
		
	while helixD % 7500 != 0:
		helixD -= 1
	
	curgen = -helixD * 2
	curgen += 2 * distForward
	goto(curgen)
	g.setstep(3)
	
	delta = 10
	lastmaxi = delta
	
	for i in hwssRecipe:
		curgen += 2 * distForward
		
		while int(g.getgen()) < curgen:
			g.step()
		
	
		if i == 'SKIP':
			continue 
			
		if i > lastmaxi:
			
			g.select([240, helixD + fenseY + lastmaxi - delta, 1, delta])
			g.clear(0)
			lastmaxi += delta
			#g.update()
			
		if i < lastmaxi - delta:
			g.putcells(fense50, 240, helixD + fenseY + lastmaxi - 2 * delta)
			lastmaxi -= delta
def AdaptiveGoto(hwssRecipe):

	#g.setrule("LifeHistory")
	fense50 = g.parse("F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F$F!")

	helixD = -step * len(hwssRecipe) - 1000
		
	while helixD % 7500 != 0:
		helixD -= 1
	
	curgen = -helixD * 2
	curgen += 2 * distForward
	goto(curgen)
	g.setstep(3)
	
	delta = 10
	lastmaxi = delta
	
	for i in hwssRecipe:
		curgen += 2 * distForward
		
		while int(g.getgen()) < curgen:
			g.step()
		
	
		if i == 'SKIP':
			continue 
			
		if i > lastmaxi:
			
			g.select([240, helixD + fenseY + lastmaxi - delta, 1, delta])
			g.clear(0)
			lastmaxi += delta
			#g.update()
			
		if i < lastmaxi - delta:
			g.putcells(fense50, 240, helixD + fenseY + lastmaxi - 2 * delta)
			lastmaxi -= delta
def getobject(x, y):
    object = []
    ncells.append( (x, y, g.getcell(x,y)) )
    g.setcell(x, y, 0)
    while len(ncells) > 0:
        # remove cell from end of ncells and append to object
        x, y, s = ncells.pop()
        object.append(x)
        object.append(y)
        object.append(s)
        # add any live neighbors to ncells
        checkneighbor(x  , y+1)
        checkneighbor(x  , y-1)
        checkneighbor(x+1, y  )
        checkneighbor(x-1, y  )
        checkneighbor(x+1, y+1)
        checkneighbor(x+1, y-1)
        checkneighbor(x-1, y+1)
        checkneighbor(x-1, y-1)
    # append padding int if necessary
    if len(object) > 0 and (len(object) & 1) == 0: object.append(0)
    g.putcells(object)
    return object
def getobject(x, y):
   object = []
   ncells.append( (x, y, g.getcell(x,y)) )
   g.setcell(x, y, 0)
   while len(ncells) > 0:
      # remove cell from end of ncells and append to object
      x, y, s = ncells.pop()
      object.append(x)
      object.append(y)
      object.append(s)
      # add any live neighbors to ncells
      checkneighbor(x  , y+1)
      checkneighbor(x  , y-1)
      checkneighbor(x+1, y  )
      checkneighbor(x-1, y  )
      checkneighbor(x+1, y+1)
      checkneighbor(x+1, y-1)
      checkneighbor(x-1, y+1)
      checkneighbor(x-1, y-1)
   # append padding int if necessary
   if len(object) > 0 and (len(object) & 1) == 0: object.append(0)
   g.putcells(object)
   return object
Beispiel #50
0
def main():

    g.setstep(0)
    g.setalgo('QuickLife')

    velocity = g.getstring('Please specify velocity', '(2,1)c/6')
    a, b, p = parse_velocity(velocity)
    params = partial_derivatives(a, b, p)

    dvdy = params['dvdy']
    dudy = params['dudy']
    dvdt = params['dvdt']

    cells = g.getcells(g.getrect())
    cells = zip(cells[::2], cells[1::2])
    gcells = []

    for (u, v) in cells:
        for t in xrange(p):
            xp = dvdy * u - dudy * v - a * t
            yq = v - t * dvdt
            if (xp % p != 0):
                continue
            if (yq % dvdy != 0):
                continue
            x = xp // p
            y = yq // dvdy
            gcells.append((t, x, y))

    spacing = max([x for (_, x, _) in gcells]) - min([x for (_, x, _) in gcells])
    spacing += 10

    gcells = [(x + spacing * t, y) for (t, x, y) in gcells]

    g.setlayer(g.addlayer())
    g.putcells([x for y in gcells for x in y])
    g.fit()
	def CanApplyRecipe(self, recipe, expected):
		g.new("")
		g.setstep(3)
		
		g.putcells(blck)
		g.putcells(self.init)
		
		for r in self.recipe:
			g.putcells(gld, 80, 80 + r)
			g.step()
		
		g.select([self.block0[0], self.block0[1], 2, 2])
		g.clear(0)
		cells = g.getcells(g.getrect())
		g.putcells(blck, self.block0[0], self.block0[1])
		delta = self.block0[1] - self.block0[0]
		
		for r in recipe:
			g.putcells(gld, 80, 80 + r + delta)
			g.step()
		
		for i in xrange(0, len(cells), 2):
			x = cells[i]
			y = cells[i + 1]
			
			if g.getcell(x, y) == 0:
				return False
				
		for i in xrange(0, len(expected), 2):
		
			x = expected[i] + self.block0[0]
			y = expected[i + 1] + self.block0[1]
			
			if g.getcell(x, y) == 0:
				return False
				
		return True
Beispiel #52
0
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)
Beispiel #53
0
def PlaceReadingHeads(hwssRecipe):
	global fenseX
	
	g.new("")
	g.setrule("LifeHistoryNoMark")
	
	if directionType == "B":
		dist = int(1.5 * len(hwssRecipe) / speed)
		for y in xrange(-dist, 1):
		
			MakeBackwardSalvo(step, 0, distBack * y, step * len(hwssRecipe) + 100, y == 0, y == 0)
		
		MakeBackwardRecipe(step, 0, 0, hwssRecipe)
		
		rect = g.getrect()
		
		cells = []

		for i in xrange(1200, step * len(hwssRecipe) + 1501):
			
			cells.append(rect[0]-50)
			cells.append(i)
			cells.append(6)
		
		g.putcells(cells)
		g.putcells(cells, rect[0]-1000, 0)
		
	else:
	
		helixD = CalcHelix(hwssRecipe)
		dist = int(1.5 * len(hwssRecipe) / speed)
		for y in xrange(0, dist + 1):
		   MakeForwardSalvo(step, 0, distForward * y, helixD, y == 0, y == 0)
		
		MakeForwardRecipe(helixD, step, 0, 0, hwssRecipe)
		rect = g.getrect()
		
		cells = []
		
		fenseX = rect[0] + rect[2] + 50
		
		for i in xrange(fenseY, -helixD + 201):
			
			cells.append(rect[0] + rect[2] + 50)
			cells.append(i + helixD)
			cells.append(6)
		
		g.putcells(cells)
def lookforkeys(event, deltax, deltay):
   global oldcells, selrect, selpatt
   
   # look for keys used to flip/rotate selection
   if event == "key x none" or event == "key y none":
      # flip floating selection left-right or top-bottom
      if len(oldcells) > 0:
         g.clear(0)
         g.putcells(selpatt, deltax, deltay)
      if " x " in event:
         g.flip(0)
      else:
         g.flip(1)
      selpatt = g.transform(g.getcells(selrect), -deltax, -deltay)
      if len(oldcells) > 0:
         g.clear(0)
         g.putcells(oldcells)
         g.putcells(selpatt, deltax, deltay)
      g.update()
      return
   
   if event == "key > none" or event == "key < none":
      # rotate floating selection clockwise or anticlockwise;
      # because we use g.rotate below we have to use the exact same
      # calculation (see Selection::Rotate in wxselect.cpp) for rotrect:
      midx = selrect[0] + int((selrect[2]-1)/2)
      midy = selrect[1] + int((selrect[3]-1)/2)
      newleft = midx + selrect[1] - midy
      newtop = midy + selrect[0] - midx
      rotrect = [ newleft, newtop, selrect[3], selrect[2] ]
      if not rectingrid(rotrect):
         g.warn("Rotation is not allowed if selection would be outside grid.")
         return
      g.clear(0)
      if len(oldcells) > 0: g.putcells(oldcells)
      oldcells = g.join(oldcells, g.getcells(rotrect))
      g.clear(0)
      g.select(rotrect)
      g.clear(0)
      g.select(selrect)
      g.putcells(selpatt, deltax, deltay)
      if " > " in event:
         g.rotate(0)
      else:
         g.rotate(1)
      selrect = g.getselrect()
      if selrect != rotrect: g.warn("Bug: selrect != rotrect")
      selpatt = g.transform(g.getcells(selrect), -deltax, -deltay)
      if len(oldcells) > 0:
         g.clear(0)
         g.putcells(oldcells)
         g.putcells(selpatt, deltax, deltay)
      g.update()
      return

   if event == "key h none":
      showhelp2()
      return
   
   g.doevent(event)
def moveselection():
   global oldcells, selrect, selpatt
   
   # wait for 1st click in selection
   while True:
      event = g.getevent()
      if event.startswith("click"):
         # event is a string like "click 10 20 left none"
         evt, xstr, ystr, butt, mods = event.split()
         x = int(xstr)
         y = int(ystr)
         if cellinrect(x, y, selrect):
            oldmouse = xstr + ' ' + ystr
            firstx = x
            firsty = y
            xoffset = firstx - selrect[0]
            yoffset = firsty - selrect[1]
            if mods == "alt":
               # don't delete pattern in selection
               oldcells = g.getcells(selrect)
            break
      elif event == "key h none":
         showhelp1()
      else:
         g.doevent(event)
   
   # wait for 2nd click while moving selection
   g.show("Move mouse and click again..." + helpmsg)
   gotclick = False
   while not gotclick:
      event = g.getevent()
      if event.startswith("click"):
         evt, x, y, butt, mods = event.split()
         mousepos = x+' '+y
         gotclick = True
      else:
         if len(event) > 0:
            lookforkeys(event, x - firstx, y - firsty)
            # update xoffset,yoffset in case selection was rotated
            xoffset = x - selrect[0]
            yoffset = y - selrect[1]
         mousepos = g.getxy()
      if len(mousepos) > 0 and mousepos != oldmouse:
         # mouse has moved, so move selection rect and pattern
         g.clear(0)
         if len(oldcells) > 0: g.putcells(oldcells)
         xstr, ystr = mousepos.split()
         x = int(xstr)
         y = int(ystr)
         selrect[0] = x - xoffset
         selrect[1] = y - yoffset
         
         if g.getwidth() > 0:
            # ensure selrect doesn't move beyond left/right edge of grid
            if selrect[0] < gridl:
               selrect[0] = gridl
               x = selrect[0] + xoffset
            elif selrect[0] + selrect[2] - 1 > gridr:
               selrect[0] = gridr + 1 - selrect[2]
               x = selrect[0] + xoffset
         if g.getheight() > 0:
            # ensure selrect doesn't move beyond top/bottom edge of grid
            if selrect[1] < gridt:
               selrect[1] = gridt
               y = selrect[1] + yoffset
            elif selrect[1] + selrect[3] - 1 > gridb:
               selrect[1] = gridb + 1 - selrect[3]
               y = selrect[1] + yoffset
         
         g.select(selrect)
         oldcells = g.getcells(selrect)
         g.putcells(selpatt, x - firstx, y - firsty)
         oldmouse = mousepos
         g.update()
         g.update()

# ------------------------------------------------------------------------------

selrect = g.getselrect()
if len(selrect) == 0: g.exit("There is no selection.")
selpatt = g.getcells(selrect)

# remember initial selection in case user aborts script
firstrect = g.getselrect()
firstpatt = g.getcells(selrect)

g.show("Click anywhere in selection, move mouse and click again..." + helpmsg)
oldcursor = g.getcursor()
g.setcursor("Move")
oldcells = []

try:
   aborted = True
   moveselection()
   aborted = False
finally:
   g.setcursor(oldcursor)
   if aborted:
      g.clear(0)
      if len(oldcells) > 0: g.putcells(oldcells)
      g.putcells(firstpatt)
      g.select(firstrect)
   else:
      g.show(" ")