Exemple #1
0
def bijoscar(maxsteps):

    initpop = int(g.getpop())
    initrect = g.getrect()
    if (len(initrect) == 0):
        return 0
    inithash = g.hash(initrect)

    for i in xrange(maxsteps):

        g.run(1)

        if (int(g.getpop()) == initpop): 

            prect = g.getrect()
            phash = g.hash(prect)

            if (phash == inithash):

                period = i + 1

                if (prect == initrect):
                    return period
                else:
                    return -period 
    return -1
Exemple #2
0
def bijoscar(maxsteps):
    initpop = int(g.getpop())
    initrect = g.getrect()
    if (len(initrect) == 0):
        return 0, None
    inithash = g.hash(initrect)

    for i in range(maxsteps):
        g.run(1)

        if (int(g.getpop()) == initpop):
            prect = g.getrect()
            phash = g.hash(prect)

            if (phash == inithash):
                period = i + 1

                if (prect == initrect):
                    return period, (0, 0)
                else:
                    dx = prect[0] - initrect[0]
                    dy = prect[1] - initrect[1]
                    return period, (dx, dy)

    return -1, None
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]
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 ()
Exemple #5
0
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
Exemple #6
0
def shrink():
	global d
	if g.empty():
		return
	g.select(g.getrect())
	d=int(10000*float(g.getpop())/(int(g.getselrect()[2])*int(g.getselrect()[3])))
	while d<100:
		bbox=g.getselrect()
		bbox[0]=bbox[0]+1
		bbox[1]=bbox[1]+1
		bbox[2]=bbox[2]-2
		bbox[3]=bbox[3]-2
		g.select(bbox)
		g.shrink()
		d=int(10000*float(g.getpop())/(int(g.getselrect()[2])*int(g.getselrect()[3])))
Exemple #7
0
def getwhp():
    bbox = g.getrect()

    if len(bbox) == 0:
        return 0, 0, 0

    return bbox[2], bbox[3], int(g.getpop())
Exemple #8
0
def rule_boring():
    explode = 0
    die = 0
    num_trial = 8

    for i in range(num_trial):
        g.new("")
        g.select([0, 0, 32, 32])
        g.randfill(50)

        g.run(16)

        if int(g.getpop()) == 0:
            die += 1
            continue

        r = g.getrect()

        if r[2] > 60 and r[3] > 60:
            explode += 1
            continue

        return -1

    if explode == num_trial:
        return 0

    if die == num_trial:
        return 1

    return -1
Exemple #9
0
def canonise():
    
    p = bijoscar(4)
    
    representation = "#"
    for i in range(abs(p)):
        rect = g.getrect()
        representation = compare_representations(representation, canonise_orientation(rect[2], rect[3], rect[0], rect[1], 1, 0, 0, 1))
        representation = compare_representations(representation, canonise_orientation(rect[2], rect[3], rect[0]+rect[2]-1, rect[1], -1, 0, 0, 1))
        representation = compare_representations(representation, canonise_orientation(rect[2], rect[3], rect[0], rect[1]+rect[3]-1, 1, 0, 0, -1))
        representation = compare_representations(representation, canonise_orientation(rect[2], rect[3], rect[0]+rect[2]-1, rect[1]+rect[3]-1, -1, 0, 0, -1))
        representation = compare_representations(representation, canonise_orientation(rect[3], rect[2], rect[0], rect[1], 0, 1, 1, 0))
        representation = compare_representations(representation, canonise_orientation(rect[3], rect[2], rect[0]+rect[2]-1, rect[1], 0, -1, 1, 0))
        representation = compare_representations(representation, canonise_orientation(rect[3], rect[2], rect[0], rect[1]+rect[3]-1, 0, 1, -1, 0))
        representation = compare_representations(representation, canonise_orientation(rect[3], rect[2], rect[0]+rect[2]-1, rect[1]+rect[3]-1, 0, -1, -1, 0))
        g.run(1)
    
    if (p<0):
        prefix = "q"+str(abs(p))
    elif (p==1):
        prefix = "s"+str(g.getpop())
    else:
        prefix = "p"+str(p)

    return "x"+prefix+"_"+representation
def calculate_density():
    bbox = gl.rect(g.getrect())
    if bbox.empty:
        d = 0
    else:
        d = float(g.getpop()) / float(bbox.wd*bbox.ht)
    return d
Exemple #11
0
def canonise():
    p = bijoscar(MAXPERIOD)
    if p == -1:
        # In rules with photons the pattern may be periodic, but not in CGoL
        return ""
    
    representation = "#"
    for i in range(abs(p)):
        rect = g.getrect()
        representation = compare_representations(representation, canonise_orientation(rect[2], rect[3], rect[0], rect[1], 1, 0, 0, 1))
        representation = compare_representations(representation, canonise_orientation(rect[2], rect[3], rect[0]+rect[2]-1, rect[1], -1, 0, 0, 1))
        representation = compare_representations(representation, canonise_orientation(rect[2], rect[3], rect[0], rect[1]+rect[3]-1, 1, 0, 0, -1))
        representation = compare_representations(representation, canonise_orientation(rect[2], rect[3], rect[0]+rect[2]-1, rect[1]+rect[3]-1, -1, 0, 0, -1))
        representation = compare_representations(representation, canonise_orientation(rect[3], rect[2], rect[0], rect[1], 0, 1, 1, 0))
        representation = compare_representations(representation, canonise_orientation(rect[3], rect[2], rect[0]+rect[2]-1, rect[1], 0, -1, 1, 0))
        representation = compare_representations(representation, canonise_orientation(rect[3], rect[2], rect[0], rect[1]+rect[3]-1, 0, 1, -1, 0))
        representation = compare_representations(representation, canonise_orientation(rect[3], rect[2], rect[0]+rect[2]-1, rect[1]+rect[3]-1, 0, -1, -1, 0))
        g.run(1)
    
    if (p<0):
        prefix = "xq" + str(abs(p))
    elif (p==1):
        prefix = "xs" + str(g.getpop())
    else:
        prefix = "xp" + str(p)
    
    return prefix + "_" + representation
Exemple #12
0
def canonise():

    p = bijoscar(1000)

    representation = "#"
    for i in range(abs(p)):
        rect = g.getrect()
        representation = compare_representations(representation, canonise_orientation(rect[2], rect[3], rect[0], rect[1], 1, 0, 0, 1))
        representation = compare_representations(representation, canonise_orientation(rect[2], rect[3], rect[0]+rect[2]-1, rect[1], -1, 0, 0, 1))
        representation = compare_representations(representation, canonise_orientation(rect[2], rect[3], rect[0], rect[1]+rect[3]-1, 1, 0, 0, -1))
        representation = compare_representations(representation, canonise_orientation(rect[2], rect[3], rect[0]+rect[2]-1, rect[1]+rect[3]-1, -1, 0, 0, -1))
        representation = compare_representations(representation, canonise_orientation(rect[3], rect[2], rect[0], rect[1], 0, 1, 1, 0))
        representation = compare_representations(representation, canonise_orientation(rect[3], rect[2], rect[0]+rect[2]-1, rect[1], 0, -1, 1, 0))
        representation = compare_representations(representation, canonise_orientation(rect[3], rect[2], rect[0], rect[1]+rect[3]-1, 0, 1, -1, 0))
        representation = compare_representations(representation, canonise_orientation(rect[3], rect[2], rect[0]+rect[2]-1, rect[1]+rect[3]-1, 0, -1, -1, 0))
        g.run(1)
    
    if (p<0):
        prefix = "q"+str(abs(p))
    elif (p==1):
        prefix = "s"+str(g.getpop())
    else:
        prefix = "p"+str(p)

    rule = str.replace(g.getrule(),"/","").lower()
    
    webbrowser.open_new("http://catagolue.appspot.com/object?apgcode=x"+prefix+"_"+representation+"&rule="+rule)
Exemple #13
0
def get_pop(numsteps=44100, x=256, y=256):
    if numsteps < 1:
        g.exit("numsteps must be greater than 0.")

    randfill(x, y)

    poplist = [int(g.getpop())]
    extinction = sys.maxint

    rule = g.getrule()
    oldsecs = time.time()
    for i in xrange(numsteps - 1):
        if g.empty():
            extinction = int(g.getgen())
            break
        g.step()
        poplist.append(int(g.getpop()))
        newsecs = time.time()
        if newsecs - oldsecs >= 1.0:
            oldsecs = newsecs
            g.show("Rule {}, Step {} of {}".format(rule, i + 1, numsteps))

    return (poplist, extinction)
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
def analyse (gogen, glcnt, minpop, maxpop, mingl):
  if glcnt < mingl:
    return (False, 0)
  
  g.run (gogen)
  inrect = g.getrect ()
  clean (inrect)

  endpop = int (g.getpop ())
  if endpop < minpop or endpop > maxpop:
    return (False, 0)

  rect = g.getrect ()
  if rect == []:
    return (True, 0)
  else:
    addmarkers (inrect)
    return (True, g.hash (inrect))
Exemple #16
0
def find_all_glider_idx(mask):
   
   idxs = extract_indexes(mask)
   idxs.sort(key=lambda idx: (1.01 * gliders_in[idx][0] + gliders_in[idx][1]))
   copy_idxs = idxs[:]

   for edge_i in enum_shooters(mask):
      reaction_cells = shoot_defs[edge_i][4]
      stable_cells = shoot_defs[edge_i][5]

      for g_i in list(copy_idxs):
      
         g.new("")
 
         for g_j in idxs:
            x, y, idx = gliders_in[g_j]
            if g_j == g_i:
               g.putcells(g.evolve(reaction_cells, idx), x, y)
            else:
               g.putcells(g.evolve(gld, idx), x - 128, y + 128)

         g.setbase(8)
         g.setstep(3)
         g.step()
         
         x, y, _ = gliders_in[g_i]

         # test if the pattern consists of the stable cells plus the
         # necessary gliders and nothing else

         g.putcells(stable_cells, x, y, 1, 0, 0, 1, "xor")

         if int(g.getpop()) != 5 * len(idxs):
            continue

         for g_j in idxs:
               x, y, idx = gliders_in[g_j]
               g.putcells(g.evolve(gld, idx), x, y, 1, 0, 0, 1, "xor")

         if g.empty():
            copy_idxs.remove(g_i)
            yield g_i,edge_i
Exemple #17
0
def CountSL():
	
	result = []
	while int(g.getpop()) > 0: 
	   xy = [FindActive()]
	   
	   while True: 
		  newXY = FindConnected(xy)
		  
		  #g.getstring(str(xy) + " : " + str(newXY) )
		  
		  if len(newXY) == len(xy):
			 break
			 
		  xy = newXY
	   
	   result.append(xy)
	   RemoveList(xy)
	  
	return result
def CountSL():
	
	result = []
	while int(g.getpop()) > 0: 
	   xy = [FindActive()]
	   
	   while True: 
		  newXY = FindConnected(xy)
		  
		  #g.getstring(str(xy) + " : " + str(newXY) )
		  
		  if len(newXY) == len(xy):
			 break
			 
		  xy = newXY
	   
	   result.append(xy)
	   RemoveList(xy)
	  
	   
	  
	return result
Exemple #19
0
def PlaySound():
    # the next (non-empty) generation has just been created
    # so get the current population and update minpop and maxpop
    global minpop, maxpop, prevsound, samecount
    currpop = int(g.getpop())
    if currpop < minpop: minpop = currpop
    if currpop > maxpop: maxpop = currpop
    poprange = maxpop - minpop
    if poprange == 0:
        g.sound("play", sounds[numsounds // 2], volume)
    else:
        p = (currpop - minpop) / poprange
        # p is from 0.0 to 1.0
        i = int(p * (numsounds - 1))
        g.sound("play", sounds[i], volume)

        # occasionally play a chord
        if random() < 0.1:
            # two notes up will be a major or minor third
            # since only white notes are used
            j = i + 2
            if j >= numsounds: j = 0
            g.sound("play", sounds[j], volume)

        # note that we can end up repeating the same sound
        # (eg. if the initial pattern is a dense Life soup),
        # so if that happens we reset minpop and maxpop
        if i == prevsound:
            samecount = samecount + 1
            if samecount == numsounds:
                minpop = currpop
                maxpop = currpop
                prevsound, samecount = 0, 0
        else:
            prevsound = i
            samecount = 0
Exemple #20
0
    status = ""

    g.new("")
    g.reset()
    g.putcells(test_list,0,0,1,0,0,1,"xor")

    g.show("Checking for oscillation... (hit escape to abort)")

    oldsecs = time()

    # --------------------------------------------------------------------
    bbox = rect( g.getrect() )
    if bbox.empty:
        initial_d = 0
    else:
        initial_d = float( g.getpop() ) / ( float(bbox.wd) * float(bbox.ht) )
    initial_pop = g.getpop()

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

    while not oscillating() and iterations < max_iter:
        g.run(1)
        iterations += 1

        newsecs = time()
        if newsecs - oldsecs >= 1.0:     # show pattern every second
            oldsecs = newsecs
            fit_if_not_visible()
            g.update()

    if iterations >= max_iter:
Exemple #21
0
if not os.path.isfile("colseqs.txt"):
    g.show("Decompressing colseqs.txt.bz2...")
    temp = bz2.BZ2File('colseqs.txt.bz2', 'rb')
    data = temp.read().decode()
    with open("colseqs.txt", "w") as f:
        f.write(data)

patts = open("rles.txt", "r", newline="\r\n")
cols = open("colseqs.txt", "r", newline="\r\n")

sols = 0
count = 0
popseq = ""
for i in range(0, GEN_CHECK):
    popseq += str(chr(33 + (int(g.getpop()) % 64)))
    g.run(1)
g.new("Solutions")
curr_patt = patts.readline()
while curr_patt != "":
    curr_col = cols.readline()
    g.show(
        str(sols) + " solutions found, " + str(count) +
        " collisions tried. Press <x> to copy current results to clipboard. Press <esc> to quit."
    )
    if popseq in curr_col:
        g.putcells(g.parse(curr_patt), offset, 0)
        offset += 75
        sols += 1
    event = g.getevent()
    if event.startswith("key x"):
Exemple #22
0
                str(21 - cycles))
         cycles -= 1
         g.run(p)
         newgunpat = str(g.getcells(r))
         if gunpat == newgunpat:  # this checks LifeHistory cells also
             break
     g.clear(1)
     g.setgen("0")
     g.save(os.path.join(LHoutfolder, item), "rle")
     if g.getrule() != "LifeHistory":
         g.exit("Uh-oh 2.")  # should already be for this layer
     g.setrule("LifeHistoryToLife")
     g.run(1)
     g.setrule("B3/S23")
     g.putcells(originalONcells, 0, 0, 1, 0, 0, 1, "xor")
     if cycles == 0 or g.getpop() != "0":
         mismatchreport += "Fixed-gun LifeHistory mismatch found at period " + str(
             p) + "-- Cycles: " + str(
                 cycles) + ", pop = " + g.getpop() + "\n"
         # if cycles==0 and g.getpop()=="0":
         # #  This is most often due to a single missing state-2 cell just in front of the output glider
         # #  TODO:  catch this case and dispose of it without unnecessary warning messages
         #   g.setclipstr(str([gunpat, newgunpat]))
         #   g.exit() #################################3
 else:  # not a fixed gun, therefore a gun built from a template
     g.open(os.path.join(outfolder, item))
     r = g.getrect()
     g.select(r)
     g.run(p)  # get rid of bounding-box marker sparks first
     g.setrule("LifeHistory")
     # there are no pseudo-period template guns, so one cycle should be enough
Exemple #23
0
def oscillating():
   # return True if the pattern is empty, stable or oscillating
   
   # first get current pattern's bounding box
   prect = g.getrect()
   pbox = rect(prect)
   if pbox.empty:
      g.show("The pattern is empty.")
      return True
   
   # get current pattern and create hash of "normalized" version -- ie. shift
   # its top left corner to 0,0 -- so we can detect spaceships and knightships
   ## currpatt = pattern( g.getcells(prect) )
   ## h = hash( tuple( currpatt(-pbox.left, -pbox.top) ) )

   # use Golly's hash command (3 times faster than above code)
   h = g.hash(prect)

   # check if outer-totalistic rule has B0 but not S8
   rule = g.getrule().split(":")[0]
   hasB0notS8 = rule.startswith("B0") and (rule.find("/") > 1) and not rule.endswith("8")
   
   # determine where to insert h into hashlist
   pos = 0
   listlen = len(hashlist)
   while pos < listlen:
      if h > hashlist[pos]:
         pos += 1
      elif h < hashlist[pos]:
         # shorten lists and append info below
         del hashlist[pos : listlen]
         del genlist[pos : listlen]
         del poplist[pos : listlen]
         del boxlist[pos : listlen]
         break
      else:
         # h == hashlist[pos] so pattern is probably oscillating, but just in
         # case this is a hash collision we also compare pop count and box size
         if (int(g.getpop()) == poplist[pos]) and \
            (pbox.wd == boxlist[pos].wd) and \
            (pbox.ht == boxlist[pos].ht):
            period = int(g.getgen()) - genlist[pos]
            
            if hasB0notS8 and (period % 2 > 0) and (pbox == boxlist[pos]):
               # ignore this hash value because B0-and-not-S8 rules are
               # emulated by using different rules for odd and even gens,
               # so it's possible to have identical patterns at gen G and
               # gen G+p if p is odd
               return False
            
            if period == 1:
               if pbox == boxlist[pos]:
                  g.show("The pattern is stable.")
               else:
                  show_spaceship_speed(1, 0, 0)
            elif pbox == boxlist[pos]:
               g.show("Oscillator detected (period = " + str(period) + ")")
            else:
               deltax = abs(boxlist[pos].x - pbox.x)
               deltay = abs(boxlist[pos].y - pbox.y)
               show_spaceship_speed(period, deltax, deltay)
            return True
         else:
            # look at next matching hash value or insert if no more
            pos += 1
   
   # store hash/gen/pop/box info at same position in various lists
   hashlist.insert(pos, h)
   genlist.insert(pos, int(g.getgen()))
   poplist.insert(pos, int(g.getpop()))
   boxlist.insert(pos, pbox)

   return False
Exemple #24
0
    if not sel:
        clist = g.getcells(g.getrect())
    else:
        clist = g.getcells(g.getselrect())
    return sum(clist[2::3].count(x) for x in live_cells)


dict_lc = {'BDRainbow': [2, 4], 'BGRainbowR2': [2, 4]}

input = (g.getstring('How many steps?/similarity distance?', '2000/1'))
numsteps = int(input.split('/')[0])
dmax = int(input.split('/')[1])

poplist = []
hashlist = [int(g.hash(g.getrect()))]
popold = int(g.getpop())
dead = 0

if g.getrule().split(':')[0] in dict_lc:
    popfunc = lambda: popcount()

else:
    popfunc = lambda: g.getpop()

for i in range(numsteps):
    g.run(1)
    if g.empty():
        break
    poplist.append(int(popfunc()))
    h = int(g.hash(g.getrect()))
    if h in hashlist:
Exemple #25
0
def sof_canonise(duration, dxdy):
    sof = ''
    moving = 's'  # Stationary

    # For spaceships the pattern needs to be oriented in the standard direction
    # N, NW, or in between.
    if not dxdy == (0, 0):
        dx, dy = dxdy
        if abs(dx) > abs(dy):
            a, b, c, d = 0, -sign(dy), -sign(dx), 0
        else:
            a, b, c, d = -sign(dx), 0, 0, -sign(dy)
        rect = g.getrect()
        ship = g.getcells(rect)
        g.select(rect)
        g.clear(0)
        g.putcells(ship, 0, 0, a, b, c, d)

        dx, dy = (dx * a + dy * b, dx * c + dy * d)
        if dx == 0:
            moving = 'o'  # Orthogonal
        elif dx == -dy:
            moving = 'd'  # Diagonal
        else:
            moving = 'k'  # Oblique

    # We need to compare each phase to find the one used to determine the
    # pattern's standard form. The standard form is selected from a phase
    # with the minimum population
    minpop = int(g.getpop())
    if (duration > 1):
        for t in range(duration):
            minpop = min(minpop, int(g.getpop()))
            g.run(1)

    if minpop == 0:
        return '0'

    for t in range(duration):
        if int(g.getpop()) == minpop:
            rect = g.getrect()
            ox = rect[0]
            oy = rect[1]
            x_length = rect[2]
            y_breadth = rect[3]

            # Choose the orientation which comes first according to sof comparison rules:
            sof = sof_compare(sof,
                              sof_representation(x_length, y_breadth, ox, oy,
                                                 1, 0, 0, 1))  # Identity
            if moving in ('s', 'o'):
                sof = sof_compare(sof,
                                  sof_representation(x_length, y_breadth,
                                                     ox + x_length - 1, oy, -1,
                                                     0, 0, 1))  # flip_x
            if moving in ('s', 'd'):
                sof = sof_compare(sof,
                                  sof_representation(y_breadth, x_length,
                                                     ox + x_length - 1,
                                                     oy + y_breadth - 1, 0, -1,
                                                     -1, 0))  # swap_xy_flip
            if moving == 's':
                sof = sof_compare(sof,
                                  sof_representation(x_length, y_breadth, ox,
                                                     oy + y_breadth - 1, 1, 0,
                                                     0, -1))  # flip_y
                sof = sof_compare(sof,
                                  sof_representation(x_length, y_breadth,
                                                     ox + x_length - 1,
                                                     oy + y_breadth - 1, -1, 0,
                                                     0, -1))  # 180
                sof = sof_compare(sof,
                                  sof_representation(y_breadth, x_length, ox,
                                                     oy, 0, 1, 1,
                                                     0))  # swap_xy
                sof = sof_compare(sof,
                                  sof_representation(y_breadth, x_length,
                                                     ox + x_length - 1, oy, 0,
                                                     -1, 1, 0))  # cw 90
                sof = sof_compare(sof,
                                  sof_representation(y_breadth, x_length, ox,
                                                     oy + y_breadth - 1, 0, 1,
                                                     -1, 0))  # ccw 90

        if (duration > 1):
            g.run(1)

    return sof
Exemple #26
0
def chunks(l,w):
   for i in xrange(0, len(l), 2):
      yield l[i]+(w*l[i+1])

if g.empty(): g.exit("The pattern is empty.")
s = g.getstring("Enter the period:","", "Heat calculator")

if not validint(s): 
  g.exit('Bad number: %s' % s)
numsteps = int(s)
if numsteps < 2:
  g.exit('Period must be at least 2.')

g.show('Processing...')

heat = 0;
maxheat = 0;
minheat = 9*g.getpop();

for i in range(0, numsteps):
  bb = g.getrect()
  clist = list(chunks(g.getcells(bb), bb[2]+2))
  g.run(1)
  dlist = list(chunks(g.getcells(g.getrect()), bb[2]+2))
  theat = (len(clist)+len(dlist)-2*len([x for x in set(clist).intersection( set(dlist) )]))
  heat += theat
  maxheat = max(theat, maxheat)
  minheat = min(theat, minheat)

g.show('Heat: %.4f, Max change: %d, Min change: %d' % ((float(heat)/numsteps), maxheat, minheat))
Exemple #27
0
    status = ""

    g.new("")
    g.reset()
    g.putcells(test_list, 0, 0, 1, 0, 0, 1, "xor")

    g.show("Checking for oscillation... (hit escape to abort)")

    oldsecs = time()

    # --------------------------------------------------------------------
    bbox = rect(g.getrect())
    if bbox.empty:
        initial_d = 0
    else:
        initial_d = float(g.getpop()) / (float(bbox.wd) * float(bbox.ht))
    initial_pop = g.getpop()

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

    while not oscillating() and iterations < max_iter:
        g.run(1)
        iterations += 1

        newsecs = time()
        if newsecs - oldsecs >= 1.0:  # show pattern every second
            oldsecs = newsecs
            fit_if_not_visible()
            g.update()

    if iterations >= max_iter:
Exemple #28
0
for i in xrange(g.numlayers()):
    if g.getname(i) == layername:
        poplayer = i
        break
if poplayer == -1 and g.numlayers() == g.maxlayers():
    g.exit("You need to delete a layer.")

# prompt user for number of steps
numsteps = xlen
s = g.getstring("Enter the number of steps:",
                str(numsteps), "Population plotter")
if len(s) > 0: numsteps = int(s)
if numsteps <= 0: g.exit()

# generate pattern for given number of steps
poplist = [ int(g.getpop()) ]
genlist = [ int(g.getgen()) ]
oldsecs = time()
for i in xrange(numsteps):
    g.step()
    poplist.append( int(g.getpop()) )
    genlist.append( int(g.getgen()) )
    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" % (i+1, numsteps))

fit_if_not_visible()
# extract-single-channel-recipe.py
# glider stream should be pointed northwest.  First glider should be in 3o$o$bo! phase, point at (0,0).
# no selection needed -- script works on entire pattern in current universe
#
# For very large single-channel streams, a variant of recognizer.py would be enormously more efficient

import golly as g
count = 0
recipe = []
while int(g.getpop())>0:
  if g.getcell(0,0)==1 and g.getcell(1,0)==1 and g.getcell(2,0)==1 and g.getcell(0,1)==1 and g.getcell(1,2)==1:
    g.setcell(0,0,0)
    g.setcell(1,0,0)
    g.setcell(2,0,0)
    g.setcell(0,1,0)
    g.setcell(1,2,0)
    recipe+=[count]
    count=0
    if len(recipe)%10 == 0:
      g.show(str(len(recipe)))
      g.fit()
      g.update()
  else:
    count+=1
    g.run(1)
g.note("Done.  Click OK to copy results to clipboard.")
g.setclipstr(str(recipe))
g.show(str(len(recipe)))
Exemple #30
0
	return sum(clist[2::3].count(x) for x in live_cells)
	

dict_lc={'BDRainbow':[2,4],'BGRainbowR2':[2,4]}

input=(g.getstring('How many steps?/similarity distance?','2000/1'))
numsteps=int(input.split('/')[0])
dmax=int(input.split('/')[1])
sel=(g.getselrect()!=[])

rule=g.getrule().split(':')[0]
if rule in dict_lc:
	popfunc=lambda:popcount(sel)
else:
	popfunc=lambda:int(g.getpop())



poplist=[]
dpoplist=[]
hashlist=[int(g.hash(g.getrect()))]
popold=int(popfunc())

poplist.append(popold)
dpoplist.append(0)
for i in range(numsteps):
	g.step()	
	if g.empty():
		break	
	pop=int(popfunc())
Exemple #31
0
def FindAllHs(cells):
	g.new("")
	g.putcells(cells)
	rect = g.getrect()
	
	
	min = 10000
	max = -10000
	
	for i in xrange(1, len(cells), 2):
		cx = cells[i - 1]
		cy = cells[i]
		
		dx = 40 - cx
		cy += dx
		
		if cy < min:
			min = cy
		
		if cy > max:
			max = cy
		
	answer = [[],[]] 
	
	if (min - 9) % 2 != 0:
		min += 1
		
	for i in xrange(min - 9 - 40, max + 6 - 40, 2):
		g.new("")
		g.putcells(cells)
		g.putcells(gld, 40, 40 + i)
		g.setstep(3)
		g.step()
		g.step()
		
		if int(g.getpop()) > 80 or int(g.getpop()) == 0:
			continue 
		
		if g.getrect()[0] < -120:
			continue 
		
		rect = g.getrect()
		
		if rect[2] > 25 or rect[3] > 25:
			continue
		
		s = str(g.getcells(g.getrect()))
		g.run(1)
		
		if s == str(g.getcells(g.getrect())):
			
			key = str(rect) + ":" + str(g.getpop())
			
			SLs = []
			
			if rect[2] < 8 and rect[3] < 8:
				SLs = CountSL()
			
			if len(SLs) == 1: 
				SLs[0].sort(key=lambda r: 100000 * r[1] + r[0])
				
				x1 = SLs[0][0][0]
				y1 = SLs[0][0][1]
				
				for o in xrange(0, len(SLs[0])):
					SLs[0][o][0] -= x1
					SLs[0][o][1] -= y1

				answer[0].append([i, x1, y1, SLs[0]])
			
			if not (key in existingKeys):
				existingDic[key] = []
				existingKeys.append(key)
				
			if s in existingDic[key]:
				continue 
			else:
				existingDic[key].append(s)
		
			answer[1].append(i)
			
	return answer 
Exemple #32
0
soupnum = int(input.split('/')[1])
soupwd = int(input.split('/')[2])
density = int(input.split('/')[3])
gen_thres = int(input.split('/')[4])

if g.getrule().split(':')[0] in dict_lc:
    yfunc = 'popc'
else:
    yfunc = 'pop'
vars = g.getstring(
    "yVar/yxVar, \n pop=population,\n gen=generation,\n boxy=width of bounding box,\n boxx=height of bounding box,\n density=population/area of bindingbox ,\n area=area of bounding box",
    "%s/gen" % yfunc)
dict_lc = {'BDRainbow': [2, 4], 'BGRainbowR2': [2, 4]}
live_cells = dict_lc[g.getrule().split(':')[0]]
dict_f = {'popc':popcount,'pop': g.getpop, 'gen': g.getgen,'boxx':lambda:boxdm(2) ,'boxy': lambda: boxdm(3),'area':area,'density':density, \
  'logpop':lambda:int(int(g.getpop())*math.log(float(g.getpop()))/math.log(2)),'popi':lambda:int(1000000000/float(g.getpop())), 'areai':lambda:int(1000000000/float(int(boxdm(2))*int(boxdm(3))))}
dict_t={'popc':'Population','pop':'Population','gen':'Generation','boxx':'Box width','boxy':'Box height','area':'Box area','density':'Cell density (0.001)',\
  'logpop':'log(pop)','popi':'inverse of pop','areai':'inverse of area'}
yfunc = dict_f[vars.split("/")[0]]
xfunc = dict_f[vars.split("/")[1]]
ytitle = dict_t[vars.split("/")[0]]
xtitle = dict_t[vars.split("/")[1]]
htlist = []
plotlist = []

tile = loadtopo(maxnum, step)
# g.note(str(tile[0]))

if not tile == []:
    # add a layer
    layername = "Topology_Search"
g.autoupdate(False)
f = open(out_filename, 'w')
f.write("id,number_of_iterations,initial_pop,final_pop,initial_density,final_density,end_status,elapsed_time\n")
#f2 = open(patterns_filename, 'w')
#f2.write("id, initial_cell_list\n")

trial_number = 1
for test_list in create_cell_list(grid_size):
    iterations = 0
    status = ''
    o.clear()
    g.new(name)
    g.reset()
    g.putcells(test_list)

    initial_pop = g.getpop()
    initial_d = calculate_density()

    start_time = time()
    while not o.oscillating() and iterations<max_iter:
        g.step()
        iterations += 1
    end_time = time()

    status = o.status

    if iterations >= max_iter:
        status = "timeout"
        #f2.write("%d, %s\n" % (trial_number, str(test_list)))
        #g.store(test_list, rlepatterns_filename%(trial_number))
Exemple #34
0
 g.setmag(screen_mag)  # screen magnification
 g.setrule(rule)  # set the rule that Golly will use
 offset = int(initial_size /
              2)  # this centers the matrix in the display
 #
 # write initial matrix into the Golly universe
 #
 density = rand.uniform(density_range[0], density_range[1])
 for x in range(initial_size):
     for y in range(initial_size):
         if (rand.uniform(0, 1) <= density):
             g.setcell(x - offset, y - offset, 1)  # set cell to 1
 #
 # initial population count
 #
 initial_pop_count = float(g.getpop())
 initial_bounding_box = g.getrect()
 initial_area = float(initial_size * initial_size)
 #
 # run Golly for num_steps
 #
 g.run(num_steps)
 g.update()  # update the Golly display
 #
 # final population count
 #
 final_pop_count = float(g.getpop())
 final_bounding_box = g.getrect()
 #
 # final area
 #
Exemple #35
0
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:
    soupfile.write("\n".join(soups))
    g.show("Soups successfully saved in {}.".format(soupfilepath))
# getminpopandminbb.py
import golly as g

maxticks = g.getstring ("Enter maximum number of ticks to search: ", "1024")
r = g.getrect()
count, minT, minpop, minbbx, minbby, minbbt = 0, 0, int(g.getpop()), r[2], r[3], 0
newpop = minpop
while count<int(maxticks):
  if count%100==0:
    g.show("T: " + str(count) + "    Current pop: "+str(newpop)+"    Current minimum pop: " + str(minpop) + " at T = " + str(minT) + ". Min box = "+str([minbbx, minbby]) + " at T = " + str(minbbt) + ".  'q' to quit.")
    g.update()
    cancel=0
    for i in range(100): # clear buffer if, e.g., mouse events have been piling up
      evt = g.getevent()
      if evt == "key q none":
        cancel = 1
    if cancel==1: break 
  g.run(1)
  count+=1
  newpop = int(g.getpop())
  if newpop<minpop:
    minpop = newpop
    minT = count
  r = g.getrect()
  if r[2]*r[3]<minbbx*minbby:
    minbbx, minbby, minbbt = r[2], r[3], count
g.note("Finished scan of " + str(count) + " ticks.  Minimum population: " +str(minpop) + " at T = " + str(minT) + ". Min box = "+str([minbbx, minbby]) + " at T = " + str(minbbt))
Exemple #37
0
def FindAllHs(cells, minx):
	g.new("")
	g.putcells(cells)
	rect = g.getrect()
	
	min = 10000
	max = -10000
	
	for i in xrange(1, len(cells), 2):
		cx = cells[i - 1]
		cy = cells[i]
		
		dx = 40 - cx
		cy += dx
		
		if cy < min:
			min = cy
		
		if cy > max:
			max = cy
		
	answer = [[],[]] 
	
	if (min - 9) % 2 != 0:
		min += 1
		
	for i in xrange(min - 9 - 40, max + 6 - 40, 2):
		g.new("")
		g.putcells(cells)
		g.putcells(gld, 40, 40 + i)
		g.setstep(3)
		g.step()
		g.step()
		
		if int(g.getpop()) > 60:
			continue 
			
		if int(g.getpop()) == 0:
			continue 
		
		if g.getrect()[0] < -120:
			continue 
		
		edgeType = HasEdgeShooter(minx)
		
		if edgeType != False:
			answer[0].append([i, 0, 0, [edgeType]])
			
		rect = g.getrect()
		
		if rect[2] > 12 or rect[3] > 12:
			continue
		
		s = str(g.getcells(g.getrect()))
		g.run(2)
		
		if s == str(g.getcells(g.getrect())):
			
			key = str(rect) + ":" + str(g.getpop())
			
			if not (key in existingKeys):
				existingDic[key] = []
				existingKeys.append(key)
				
			if s in existingDic[key]:
				continue 
			else:
				existingDic[key].append(s)
		
			answer[1].append(i)
			
	return answer 
Exemple #38
0
# Calculates the density of live cells in the current pattern.
# Author: Andrew Trevorrow ([email protected]), March 2006.
# Updated to use exit command, Nov 2006.

from glife import rect
import golly as g

bbox = rect( g.getrect() )
if bbox.empty: g.exit("The pattern is empty.")

d = float( g.getpop() ) / ( float(bbox.wd) * float(bbox.ht) )
if d < 0.000001:
   g.show("Density = %.1e" % d)
else:
   g.show("Density = %.6f" % d)
periodlist = map(int, rawentry1.split(','))
maxgens = int(rawentry2)
soups = int(rawentry3)

totalperiod = 1
for period in periodlist:
    totalperiod = lcm(period, totalperiod)

longest = [], 0
for soupnum in range(soups):
    g.new('')
    g.select([0, 0, 5, 5])
    g.randfill(50)
    currsoup = g.getcells([0, 0, 5, 5])
    currpop = g.getpop()
    sameaslast = 0
    totalgens = 0
    success = False
    while totalgens < maxgens:
        g.run(totalperiod)
        totalgens += totalperiod
        if g.getpop() == currpop:
            sameaslast += 1
        else:
            sameaslast == 0
        currpop = g.getpop()
        if sameaslast == 5:
            # We assume it's stabilized
            success = True
            totalgens -= totalperiod * 5
   while cycles>0:
     g.show("LifeHistorifizing period " + str(p) + ", trial #" + str(21-cycles))
     cycles-=1
     g.run(p)
     newgunpat = str(g.getcells(r))
     if gunpat == newgunpat: # this checks LifeHistory cells also
       break
   g.clear(1)
   g.setgen("0")    
   g.save(os.path.join(LHoutfolder,item),"rle")
   if g.getrule()!="LifeHistory": g.exit("Uh-oh 2.") # should already be for this layer
   g.setrule("LifeHistoryToLife")
   g.run(1)
   g.setrule("B3/S23")
   g.putcells(originalONcells, 0, 0, 1, 0, 0, 1, "xor")
   if cycles==0 or g.getpop()!="0":
     mismatchreport+="Fixed-gun LifeHistory mismatch found at period " + str(p) + "-- Cycles: "+str(cycles)+", pop = "+g.getpop()+"\n"
     # if cycles==0 and g.getpop()=="0":
     # #  This is most often due to a single missing state-2 cell just in front of the output glider
     # #  TODO:  catch this case and dispose of it without unnecessary warning messages
     #   g.setclipstr(str([gunpat, newgunpat]))
     #   g.exit() #################################3
 else: # not a fixed gun, therefore a gun built from a template
   g.open(os.path.join(outfolder,item))
   r = g.getrect()
   g.select(r)
   g.run(p)  # get rid of bounding-box marker sparks first
   g.setrule("LifeHistory")
   # there are no pseudo-period template guns, so one cycle should be enough
   g.run(p)
   originalONcells = g.getcells(r)
Exemple #41
0
def oscillating():
    # return True if the pattern is empty, stable or oscillating

    # first get current pattern's bounding box
    csel = g.getselrect()
    g.shrink()
    prect = g.getselrect()
    g.select(csel)
    pbox = rect(prect)
    if pbox.empty:
        g.show("The pattern is empty.")
        return True

    # get current pattern and create hash of "normalized" version -- ie. shift
    # its top left corner to 0,0 -- so we can detect spaceships and knightships
    ## currpatt = pattern( g.getcells(prect) )
    ## h = hash( tuple( currpatt(-pbox.left, -pbox.top) ) )

    # use Golly's hash command (3 times faster than above code)
    h = g.hash(prect)

    # check if outer-totalistic rule has B0 but not S8
    rule = g.getrule().split(":")[0]
    hasB0notS8 = rule.startswith("B0") and (rule.find("/") >
                                            1) and not rule.endswith("8")

    # determine where to insert h into hashlist
    pos = 0
    listlen = len(hashlist)
    while pos < listlen:
        if h > hashlist[pos]:
            pos += 1
        elif h < hashlist[pos]:
            # shorten lists and append info below
            del hashlist[pos:listlen]
            del genlist[pos:listlen]
            del poplist[pos:listlen]
            del boxlist[pos:listlen]
            break
        else:
            # h == hashlist[pos] so pattern is probably oscillating, but just in
            # case this is a hash collision we also compare pop count and box size
            if (pbox.wd == boxlist[pos].wd) and \
               (pbox.ht == boxlist[pos].ht):
                # (int(g.getpop()) == poplist[pos])

                period = int(g.getgen()) - genlist[pos]

                if hasB0notS8 and (period % 2 > 0) and (pbox == boxlist[pos]):
                    # ignore this hash value because B0-and-not-S8 rules are
                    # emulated by using different rules for odd and even gens,
                    # so it's possible to have identical patterns at gen G and
                    # gen G+p if p is odd
                    return False

                if period == 1:
                    if pbox == boxlist[pos]:
                        g.show("The pattern is stable.")
                    else:
                        show_spaceship_speed(1, 0, 0)
                elif pbox == boxlist[pos]:
                    g.show("Oscillator detected (period = " + str(period) +
                           ")")
                else:
                    deltax = abs(boxlist[pos].x - pbox.x)
                    deltay = abs(boxlist[pos].y - pbox.y)
                    show_spaceship_speed(period, deltax, deltay)
                return True
            else:
                # look at next matching hash value or insert if no more
                pos += 1

    # store hash/gen/pop/box info at same position in various lists
    hashlist.insert(pos, h)
    genlist.insert(pos, int(g.getgen()))
    poplist.insert(pos, int(g.getpop()))
    boxlist.insert(pos, pbox)

    return False
Exemple #42
0
#!/usr/bin/env python2.6

# Q: http://www.hacker.org/challenge/chal.php?id=117
# A: http://www.hacker.org/challenge/chal.php?answer=821%2C319&id=117&go=Submit

# Use Golly, a Game of Life simulator. It can be shown that after 1500 generations, the populations are always 116. So only need to search the first 1500 generations to find the max population.

import golly as g

GENERATION_NUM = 1500

max_population = -1
best_generation = -1

for generation in range(GENERATION_NUM):
    population = int(g.getpop())
    if population > max_population:
        max_population = population
        best_generation = generation
    
    g.step()

g.note('%d,%d' % (best_generation, max_population))