Exemple #1
0
def ReplaceTreeSection(rulepath, newtree):
    # replace @TREE section in existing .rule file with new tree data
    try:
        rulefile = open(rulepath,'r')
    except:
        golly.exit('Failed to open existing .rule file: '+rulepath)
    
    # create a temporary file for writing new rule info
    temphdl, temppath = mkstemp()
    tempfile = open(temppath,'w')
    
    skiplines = False
    for line in rulefile:
        if line.startswith('@TREE'):
            tempfile.write('@TREE\n\n')
            tempfile.write(newtree)
            skiplines = True
        elif skiplines and line.startswith('@'):
            tempfile.write('\n')
            skiplines = False
        if not skiplines:
            tempfile.write(line)
    
    # close files
    rulefile.close()
    tempfile.flush()
    tempfile.close()
    os.close(temphdl)
    
    # remove original .rule file and rename temporary file
    os.remove(rulepath)
    move(temppath, rulepath)
Exemple #2
0
def draw_icons(iconinfo, transparent):
    global colorstate
    if len(iconinfo) == 0: return
    width = iconinfo[0]
    height = iconinfo[1]
    num_colors = iconinfo[2]
    chars_per_pixel = iconinfo[3]
    colordict = iconinfo[4]
    pos = 5
    numicons = height // width
    for i in range(numicons):
        x = i * 32
        y = 0
        if width == 15: y = 32
        if width == 7: y = 48
        for row in range(width):
            pxls = iconinfo[pos]
            pos += 1
            for col in range(width):
                offset = col * chars_per_pixel
                key = pxls[offset:offset + chars_per_pixel]
                if not key in colordict:
                    g.exit("Unexpected key in icon data: " + key)
                rgb = colordict[key]
                if rgb != transparent:
                    g.setcell(x + col, y + row, colorstate[rgb])
def ReplaceTreeSection(rulepath, newtree):
    # replace @TREE section in existing .rule file with new tree data
    try:
        rulefile = open(rulepath, 'r')
    except:
        golly.exit('Failed to open existing .rule file: ' + rulepath)

    # create a temporary file for writing new rule info
    temphdl, temppath = mkstemp()
    tempfile = open(temppath, 'w')

    skiplines = False
    for line in rulefile:
        if line.startswith('@TREE'):
            tempfile.write('@TREE\n\n')
            tempfile.write(newtree)
            skiplines = True
        elif skiplines and line.startswith('@'):
            tempfile.write('\n')
            skiplines = False
        if not skiplines:
            tempfile.write(line)

    # close files
    rulefile.close()
    tempfile.flush()
    tempfile.close()
    os.close(temphdl)

    # remove original .rule file and rename temporary file
    os.remove(rulepath)
    move(temppath, rulepath)
Exemple #4
0
def draw_icons(iconinfo, transparent):
    global colorstate
    if len(iconinfo) == 0: return
    width = iconinfo[0]
    height = iconinfo[1]
    num_colors = iconinfo[2]
    chars_per_pixel = iconinfo[3]
    colordict = iconinfo[4]
    pos = 5
    numicons = height/width
    for i in xrange(numicons):
        x = i*32
        y = 0
        if width == 15: y = 32
        if width == 7: y = 48
        for row in xrange(width):
            pxls = iconinfo[pos]
            pos += 1
            for col in xrange(width):
                offset = col*chars_per_pixel
                key = pxls[offset : offset + chars_per_pixel]
                if not key in colordict:
                    g.exit("Unexpected key in icon data: " + key)
                rgb = colordict[key]
                if rgb != transparent:
                    g.setcell(x+col, y+row, colorstate[rgb])
Exemple #5
0
def retrieveparam(article, param, s):
    if s.find(param) < 0:
        g.note("Setting clipboard to current html -- can't find '" + param +
               "'.")
        g.setclipstr(s)
        g.exit()
    regexstr = param + r'\s*=\s*(.*)$'  #######################
    match = re.search(regexstr, s, re.MULTILINE)
    if match:
        # pval = match.group(1)
        # if pval[-1:]=="\n": pval = pval[:-1]
        # # handle the case where newlines are not added before each pipe character
        # pval += "|"
        # g.note(pval + " :: " + pval[:pval.index("|")])
        # return pval[:pval.index("|")]

        # try to fix problem with multiple EmbedViewers on one line and pname as last parameter, as in Density article
        grp = match.group(1)
        if grp.find("}") > -1:
            pval = grp[:grp.find("}")] + "|"
        else:
            pval = grp + "|"

        return pval[:pval.index("|")].strip()
    else:
        g.note("Could not find definition of parameter '" + param +
               "' in article '" + article + "'.")
        g.setclipstr(s)
        g.exit()
Exemple #6
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 #7
0
def firstdiffs(values):
    if len(values) < 1:
        g.warn("No polynomial entered, apparently.")
        g.exit()
        return  # Just for good measure.
    if len(values) == 1:
        return [values[0]]
    if len(values) > 1:
        diffs = []
        for n in xrange(len(values) - 1):
            diffs.append(values[n + 1] - values[n])
        return firstdiffs(diffs) + [values[0]]
Exemple #8
0
def firstvalues(terms):
    vals = []
    for x in xrange(len(terms)):
        sum = 0
        for exp, coef in enumerate(terms):
            sum += coef * x**exp
        if sum != int(sum):
            g.warn(
                "Polynomial must produce integer values when x is an integer.")
            g.exit()
            return
        vals.append(int(sum))
    return vals
def retrieveparam(article, param, s):
  if s.find(param)<0:
    g.note("Setting clipboard to current html -- can't find '"+param+"'.")
    g.setclipstr(s)
    g.exit()
  regexstr = param+r'\s*=\s*(.*)$' #######################
  match = re.search(regexstr, s, re.MULTILINE)
  if match:
    pval = match.group(1)+"|"
    return pval[:pval.index("|")] # handle the case where newlines are not added before each pipe character
  else:
    g.note("Could not find definition of parameter '"+param+"' in article '"+article+"'.")
    g.setclipstr(s)
    g.exit()
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 TriangularTransitionsToRuleTree_CheckerboardMethod(neighborhood, n_states,
                                                       transitions, rule_name):

    # Background state 0 has no checkerboard, we infer it from its neighboring cells.
    def encode_lower(s):
        return s

    def encode_upper(s):
        ### AKT: this code causes syntax error in Python 2.3:
        ### return [0 if se==0 else n_states+se-1 for se in s]
        temp = []
        for se in s:
            if se == 0:
                temp.append(0)
            else:
                temp.append(n_states + se - 1)
        return temp

    total_states = n_states * 2 - 1
    if total_states > 256:
        golly.warn("Number of states exceeds Golly's limit of 256!")
        golly.exit()

    tree = RuleTree(total_states, 4)
    for t in transitions:
        # as lower
        tree.add_rule(
            [
                encode_lower(t[0]),  # C
                encode_upper(t[2]),  # S
                encode_upper(t[1]),  # E
                encode_upper(t[3]),  # W
                range(total_states)
            ],  # N
            encode_lower(t[4])[0])  # C'
        # as upper
        tree.add_rule(
            [
                encode_upper(t[0]),  # C
                range(total_states),  # S
                encode_lower(t[3]),  # E
                encode_lower(t[1]),  # W
                encode_lower(t[2])
            ],  # N
            encode_upper(t[4])[0])  # C'

    # output the rule tree
    golly.show("Compressing rule tree and saving to file...")
    tree.write(golly.getdir('rules') + rule_name + '.tree')
Exemple #12
0
def add_data(PATTERN_FN):

    g.select([-2753, 891, 1092, 1397])
    g.clear(0)
    g.select([])

    input_str = open(PATTERN_FN, "r").read()

    firstbreak = input_str.find("\n")
    if firstbreak == -1:
        g.show("Error, no newlines found, invalid format")
        g.exit()

    info_line = input_str[0:firstbreak]
    input_str = input_str[firstbreak:]

    #x = 1581, y = 1396, rule = Varlife
    dataptrn = re.compile(
        br'x = (?P<xval>[0-9]{1,4}), y = (?P<yval>[0-9]{1,4}), rule = .*')

    match = dataptrn.match(info_line)
    xval = 0
    yval = 0

    if (match):
        xval = int(match.group("xval"), 10)
        yval = int(match.group("yval"), 10)

    else:
        g.show("ERROR invalid format {}".format(info_line))
        g.exit()

    ipat = pattern(input_str)
    minbox = getminbox(ipat)

    if max(xval, minbox.x) > 1200:
        g.show("ERROR inserted cell area too wide, max width is 1090")
        g.exit()

    if max(yval, minbox.y) > 1397:
        g.show("ERROR inserted cell area too tall, max height is 1397")
        g.exit()

    startx = -1661 - xval
    starty = 891

    #blankptrn.put(startx, starty)

    g.show(
        "width={}, height={} startx={}, starty={}, xval={}, yval={}, bytes={}".
        format(minbox.wd, minbox.height, startx, starty, xval, yval,
               len(input_str)))
    ipat.put(startx, starty)
    g.save("/tmp/output.mc", "rle", False)

    return "Pattern load data: width={}, height={} startx={}, starty={}, xval={}, yval={}, bytes={}".format(
        minbox.wd, minbox.height, startx, starty, xval, yval, len(input_str))
Exemple #13
0
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
Exemple #14
0
def init_colors():
    global iconcolors, colorstate
    if len(iconcolors) > 240: g.exit("The imported icons use too many colors!")

    # start with gradient from white to black (this makes it easier to
    # copy grayscale icons from one rule to another rule)
    s = 1
    g.setcolors([s, 255, 255, 255])
    colorstate[(255, 255, 255)] = s
    s += 1
    graylevel = 256
    while graylevel > 0:
        graylevel -= 32
        g.setcolors([s, graylevel, graylevel, graylevel])
        colorstate[(graylevel, graylevel, graylevel)] = s
        s += 1

    # now add all the colors used in the imported icons (unless added above)
    for rgb in iconcolors:
        if not rgb in colorstate:
            R, G, B = rgb
            g.setcolors([s, R, G, B])
            colorstate[rgb] = s
            s += 1

    # finally add rainbow colors in various shades (bright, pale, dark)
    for hue in range(12):
        if s > 255: break
        R, G, B = hsv_to_rgb(hue / 12.0, 1.0, 1.0)
        g.setcolors([s, int(255 * R), int(255 * G), int(255 * B)])
        s += 1
    for hue in range(12):
        if s > 255: break
        R, G, B = hsv_to_rgb(hue / 12.0, 0.5, 1.0)
        g.setcolors([s, int(255 * R), int(255 * G), int(255 * B)])
        s += 1
    for hue in range(12):
        if s > 255: break
        R, G, B = hsv_to_rgb(hue / 12.0, 1.0, 0.5)
        g.setcolors([s, int(255 * R), int(255 * G), int(255 * B)])
        s += 1

    # return the 50% gray state (used for drawing boxes and text)
    return colorstate[(128, 128, 128)]
Exemple #15
0
def init_colors():
    global iconcolors, colorstate
    if len(iconcolors) > 240: g.exit("The imported icons use too many colors!")
    
    # start with gradient from white to black (this makes it easier to
    # copy grayscale icons from one rule to another rule)
    s = 1
    g.setcolors([s,255,255,255])
    colorstate[(255,255,255)] = s
    s += 1
    graylevel = 256
    while graylevel > 0:
        graylevel -= 32
        g.setcolors([s, graylevel, graylevel, graylevel])
        colorstate[(graylevel, graylevel, graylevel)] = s
        s += 1

    # now add all the colors used in the imported icons (unless added above)
    for rgb in iconcolors:
        if not rgb in colorstate:
            R,G,B = rgb
            g.setcolors([s,R,G,B])
            colorstate[rgb] = s
            s += 1
    
    # finally add rainbow colors in various shades (bright, pale, dark)
    for hue in xrange(12):
        if s > 255: break
        R,G,B = hsv_to_rgb(hue/12.0, 1.0, 1.0)
        g.setcolors([s, int(255*R), int(255*G), int(255*B)])
        s += 1
    for hue in xrange(12):
        if s > 255: break
        R,G,B = hsv_to_rgb(hue/12.0, 0.5, 1.0)
        g.setcolors([s, int(255*R), int(255*G), int(255*B)])
        s += 1
    for hue in xrange(12):
        if s > 255: break
        R,G,B = hsv_to_rgb(hue/12.0, 1.0, 0.5)
        g.setcolors([s, int(255*R), int(255*G), int(255*B)])
        s += 1
    
    # return the 50% gray state (used for drawing boxes and text)
    return colorstate[(128,128,128)]
Exemple #16
0
def getenvelope(pat):
    env = []
    if len(pat) % 2:
        g.exit("Must be a 2-state list.")
    for i in range(0, len(pat) - 1, 2):
        for x in range(-1, 2):
            for y in range(-1, 2):
                if abs(x) != 0 or abs(
                        y
                ) != 0:  # add eight neighbors of each ON cell to the mask
                    if [pat[i] + x, pat[i + 1] + y] not in env:
                        env.append([pat[i] + x, pat[i + 1] + y])
    for i in range(0, len(pat), 2):
        if [pat[i], pat[i + 1]] in env:
            env.remove([pat[i],
                        pat[i + 1]])  # take original pattern back out of mask
        # else: # with the reduced envelope, this will now happen, e.g. with *WSS singleton sparks
        #  g.note("Technical error: " + str([pat[i],pat[i+1]])+ " not in envelope:" + str(env) + " \n\n" + str(pat))
    return list(itertools.chain.from_iterable(env))
Exemple #17
0
def main():

	# get selection and set to boundary
	bound = g.getselrect()
	if len( bound ) == 0:
		g.note( "No selection." )
		g.exit()

	# get current Golly states
	left   = bound[ 0 ]
	top    = bound[ 1 ]
	width  = bound[ 2 ]
	height = bound[ 3 ]

	for y in xrange( 0, height ):
		for x in xrange( 0, width ):

			state = g.getcell( left + x, top + y )
			g.setcell( height - y - 600, x - 600, state )
Exemple #18
0
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
Exemple #19
0
def golly_main():

    bounding_box = g.getrect()

    g.show('Installing rule file...')
    src_rule = os.path.join(scriptdir, 'grills-examples', 'Grills.rule')
    dst_rule = os.path.join(g.getdir('rules'), 'Grills.rule')
    shutil.copyfile(src_rule, dst_rule)
    g.show('...installed.')

    if (len(bounding_box) == 0):
        g.setrule("Grills")
        g.exit("Please draw or load an input pattern.")
    elif (g.getrule() == "Grills"):
        golly_grills()
    elif (g.getrule() == "LifeHistory"):
        golly_lhistory()
    else:
        g.exit("Pattern has the incorrect rule: '%s' != '%s'" %
               (g.getrule(), 'Grills'))
def TriangularTransitionsToRuleTree_CheckerboardMethod(neighborhood,n_states,transitions,rule_name):

    # Background state 0 has no checkerboard, we infer it from its neighboring cells.
    def encode_lower(s):
        return s
    def encode_upper(s):
        ### AKT: this code causes syntax error in Python 2.3:
        ### return [0 if se==0 else n_states+se-1 for se in s]
        temp = []
        for se in s:
            if se==0:
                temp.append(0)
            else:
                temp.append(n_states+se-1)
        return temp

    total_states = n_states*2 - 1
    if total_states>256:
        golly.warn("Number of states exceeds Golly's limit of 256!")
        golly.exit()
    
    tree = RuleTree(total_states,4)
    for t in transitions:
        # as lower
        tree.add_rule([encode_lower(t[0]),   # C
                       encode_upper(t[2]),   # S
                       encode_upper(t[1]),   # E
                       encode_upper(t[3]),   # W
                       range(total_states)],   # N
                      encode_lower(t[4])[0]) # C'
        # as upper
        tree.add_rule([encode_upper(t[0]),   # C
                       range(total_states),    # S
                       encode_lower(t[3]),   # E
                       encode_lower(t[1]),   # W
                       encode_lower(t[2])],  # N
                      encode_upper(t[4])[0]) # C'
        
    # output the rule tree
    golly.show("Compressing rule tree and saving to file...")
    tree.write(golly.getdir('rules') + rule_name + '.tree')
Exemple #21
0
def calc_p_boring(p_rule):
    boring_explode = 0
    boring_die = 0

    for i in range(1000):

        g.show(str(i))

        rand_rule(p_rule)
        bor = rule_boring()

        if bor == 0:
            boring_explode += 1

        if bor == 1:
            boring_die += 1

        if bor == -1:
            g.exit()

    return (boring_explode, boring_die)
Exemple #22
0
def open_file2(file):
    if not os.path.exists(file):
        oldfile = file
        file = g.opendialog("Please locate " + file + ":", "Text files (*.txt)|*.txt", "", file)     
        if not os.path.exists(file):
            g.exit("Could not find '" + oldfile + "' or '" + file + "'.")
    f = open(file, 'r')
    f1 = f.read()
    f1 = f1.replace('b3/s23', 'B3/S23')
    while '\n\n\n' in f1:
        f1 = f1.replace('\n\n\n', '\n\n')
    f1 = f1.split('\n\n')
    #f1 = f1[:-2] #last two are larger than column width and will cause infinite loop
    for i in f1:
        #try:
        #    i = i[i.index('x ='):]
        #except ValueError:
        #    print('No "x =": ' + i)
        patterns.append(i)
        show_message("Pass 1 of 3: processing pattern #" + str(len(patterns)),0.001)
    show_message('Total number of patterns: %s' % len(patterns),0.5)
Exemple #23
0
    def setrule(self, rulestring):
    
        # neighbours_flat = [n for x in neighbours for n in x]
        b = {}
        s = {}
        sep = ''
        birth = ''
        survive = ''
        
        rulestring = rulestring.lower()
        
        if '/' in rulestring:
            sep = '/'
        elif '_' in rulestring:
            sep = '_'
        elif (rulestring[0] == 'b'):
            sep = 's'
        else:
            sep = 'b'
        
        survive, birth = rulestring.split(sep)
        if (survive[0] == 'b'):
            survive, birth = birth, survive
        survive = survive.replace('s', '')
        birth = birth.replace('b', '')
        
        b = self.ruleparts(birth)
        s = self.ruleparts(survive)

        if b and s:
            self.alphanumeric = 'B' + birth + 'S' + survive
            self.rulename = 'B' + birth + '_S' + survive + "History"
            self.bee = b
            self.ess = s
        else:
            # Error
            g.note("Unable to process rule definition.\n" +
                    "b = " + str(b) + "\ns = " + str(s))
            g.exit()
Exemple #24
0
def get_bitmap():
    ''' Get current selection & turn it into a bitmap. '''
    selrect = golly.getselrect()
    if len(selrect) == 0: golly.exit("There is no selection, aborting.")

    #Get bitmap size
    w, h = selrect[2:]
    #Adjust width, so it's in the form of 4m, m>1
    w = (w + 3) // 4 * 4
    w = max(8, w)

    #Initialize empty bitmap
    row = w * [0]
    bm = [row[:] for i in xrange(h)]

    #Populate bitmap with cell data
    u, v = selrect[:2]
    cells = golly.getcells(selrect)
    cellsxy = [(cells[i] - u, cells[i + 1] - v)
               for i in xrange(0, len(cells), 2)]
    for x, y in cellsxy:
        bm[y][x] = 1
    return bm
Exemple #25
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)
Exemple #26
0
def get_bitmap():
    selrect = golly.getselrect()
    if len(selrect) == 0: golly.exit("There is no selection, aborting.")

    #Get bitmap size
    w, h = selrect[2:]
    #Adjust width, so it's in the form of 4m, m>1
    w = (w + 3) // 4 * 4
    w = max(8, w)

    #Initialize empty bitmap
    row = w * ['0']
    bm = [row[:] for i in xrange(h)]

    #Populate bitmap with cell data
    u, v = selrect[:2]
    cells = golly.getcells(selrect)
    cellsxy = [(cells[i] - u, cells[i+1] - v) for i in xrange(0, len(cells), 2)]
    for x, y in cellsxy:
        bm[y][x] = '1'
       
    #Convert to CSV string
    return ','.join([''.join(row) for row in bm])
Exemple #27
0
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
Exemple #28
0
def encode_row(row):
    result = ''

    # find te rightmost 1 bit in this row
    far_right = x + width - 1
    while g.getcell(far_right, row) == 0:
        far_right -= 1
        if far_right < x:
            g.exit('Empty rows forbidden: ' + str(row))

    col = x
    while col <= far_right:
        cell_value = g.getcell(col, row)
        num_consecutive = count_bits(row, col, cell_value)

        if cell_value == 1:  # next cell 1?
            col += num_consecutive
            result += encode_consecutive_ones(num_consecutive)
        else:
            col += num_consecutive + 1
            result += encode_consecutive_zeros(num_consecutive)

    result += '0' * (chunk_size // 2 + 3)  # end of row
    return result
Exemple #29
0
from glife import validint, inside
from string import lower
import golly as g
import math

rules = ("JvN29", "Nobili32", "Hutton32")

rule = g.getrule ()
if rule not in rules:
    g.exit ("Invalid rule: " + rule + " (must be " + rules + ")")

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

answer = g.getstring("Enter axis to mirror on\n" +
                     "(valid axes are x and y, default is y):",
                     "y",
                     "Mirror selection")

if answer != "x" and answer != "y":
    g.exit ("Unknown mode: " + answer + " (must be x/y)")

cells = g.getcells (rect)

jvn_flip_x = ((10, 12), (14, 16), (18, 20), (22, 24))
jvn_flip_y = ((9, 11), (13, 15), (17, 19), (21, 23))

if answer == "x":
    flips = jvn_flip_x
else:
# this script allows for testing of lifegenes functionality from the python command line rather than the golly environment. Currently this is accomplished by using a mock-golly module called folly (short for fake-golly). The folly module does not actually perform all functions as golly would, it just looks like it for testing.

try:    # print a nice message if someone tries to open this script from w/in golly
    import golly as g
    g.exit('this script is for dev test only and cannot be run from within golly, check out the scripts in the "LifeGenes" folder instead')
except:
    from LifeGenes.lifegenes_core.tests.folly import folly as g

from LifeGenes.lifegenes_core.setupLog import setupLog
from LifeGenes.lifegenes_core.tests.optimization_tools import timedRuns
from os import system

import logging
setupLog('__test_LifeGenes.log')

def wait():
    try:
        system('pause')  #windows, doesn't require enter
    except:
        system('read -p "Press any key to continue"') #linux


# MAIN
logging.info('script started')
nruns = 10

print 'testing environment...'
from LifeGenes.lifegenes_core.environment import environment as lifegenes_environment
lg_envmt = lifegenes_environment()
testNames = list()
testTimes = list()
Exemple #31
0
(Larger values of N can take a long time.)
""",
    "N3",
    "Enter specification:",
)

# work out what the string meant
nhood = ""
nhoods = {"N": "vonNeumann", "TM": "triangularMoore", "M": "Moore", "T": "triangularVonNeumann", "H": "hexagonal"}
for nh in nhoods.keys():
    if nh in spec:
        nhood = nhoods[nh]
        n = int(spec.replace(nh, ""))
        break
if nhood == "":
    golly.exit("Unsupported string: " + spec)
if n < 2 or n > 255:
    golly.exit("Value of N must lie between 2 and 255.")

# assemble the transitions
nbors = {"vonNeumann": 4, "Moore": 8, "hexagonal": 6, "triangularVonNeumann": 3, "triangularMoore": 12}
transitions = []
for sl in product(range(n), repeat=nbors[nhood]):
    transitions += [[range(n)] + [[s] for s in sl] + [[sum(sl) % n]]]
rule_name = "Fredkin_mod" + str(n) + "_" + nhood

Converters = {
    "vonNeumann": ConvertRuleTableTransitionsToRuleTree,
    "Moore": ConvertRuleTableTransitionsToRuleTree,
    "triangularVonNeumann": EmulateTriangular,
    "triangularMoore": EmulateTriangular,
Exemple #32
0
# Use multiple layers to create a history of the current pattern.
# The "envelope" layer remembers all live cells.
# Author: Andrew Trevorrow ([email protected]), December 2006.
# Updated for better compatibility with envelope.pl, June 2007.
# Updated to use new setcolors command, September 2008.

import golly as g

if g.empty(): g.exit("There is no pattern.")

currindex = g.getlayer()
startindex = 0
envindex = 0
startname = "starting pattern"
envname = "envelope"

if currindex > 1 and g.getname(currindex - 1) == startname \
                 and g.getname(currindex - 2) == envname :
    # continue from where we left off
    startindex = currindex - 1
    envindex = currindex - 2

elif currindex + 2 < g.numlayers() \
                 and g.getname(currindex + 1) == startname \
                 and g.getname(currindex)     == envname :
    # switch from envelope layer to current layer and continue
    currindex += 2
    g.setlayer(currindex)
    startindex = currindex - 1
    envindex = currindex - 2
Exemple #33
0
import golly as g
import quiescentauton as q

soupfilepath = "/home/scorbie/Apps/ptbtest/random"
nsoups = int(g.getstring("How many soups?", "1000"))
soupsize = 10  # int(g.getstring('Soup size?', '10'))

if g.getrule() == "LifeHistory":
    g.setrule("B3/S23")
if g.numstates() > 2:
    g.exit("This script only works with two-state rules.")

soups = []
x, y, w, h = r = [0, 0, soupsize, soupsize]
cellchar = [".", "a"]
while len(soups) < nsoups:
    g.new("Generating Soups")
    g.select(r)
    g.randfill(40)
    g.run(250)
    # To avoid 'Empty Pattern!' messages in status bar.
    if int(g.getpop()) == 0:
        continue
    if not q.testquiescence(60):
        g.reset()
        soupstr = "!".join(
            "".join(cellchar[g.getcell(i, j)] for j in xrange(0, soupsize + 1)) for i in xrange(0, soupsize + 1)
        )
        soups.append(soupstr)
        g.show("Soup {}/{}".format(len(soups), nsoups))
with open(soupfilepath, "w") as soupfile:
H = hexagonal, TM = triangular Moore) and the value of N (2-255). e.g. H2, N7

(Larger values of N can take a long time.)
''', 'N3', 'Enter specification:')

# work out what the string meant
nhood = ''
nhoods = {'N':'vonNeumann','TM':'triangularMoore','M':'Moore',
          'T':'triangularVonNeumann','H':'hexagonal'}
for nh in nhoods.keys():
    if nh in spec:
        nhood = nhoods[nh]
        n = int(spec.replace(nh,''))
        break
if nhood=='':
    golly.exit('Unsupported string: '+spec)
if n<2 or n>255:
    golly.exit('Value of N must lie between 2 and 255.')

# assemble the transitions
nbors = {'vonNeumann':4,'Moore':8,'hexagonal':6,'triangularVonNeumann':3,
         'triangularMoore':12}
transitions = []
for sl in product(range(n),repeat=nbors[nhood]):
    transitions += [ [range(n)] + [[s] for s in sl] + [[sum(sl)%n]] ]
rule_name = 'Fredkin_mod'+str(n)+'_'+nhood

Converters = {
    "vonNeumann":ConvertRuleTableTransitionsToRuleTree,
    "Moore":ConvertRuleTableTransitionsToRuleTree,
    "triangularVonNeumann":EmulateTriangular,
Exemple #35
0
# Make a pattern from states 1 and 0, select it and then
# run this script to make a Codd CA pattern that will then
# construct the pattern. The constructor will then attempt
# to inject sheathing and triggering signals to a point one
# up from the pattern's bottom-left corner.
#
# See example: Patterns/Codd/golly-constructor.rle
#
# Tim Hutton <*****@*****.**>

from glife import rect
from time import time
import golly as g

r = rect( g.getselrect() )
if r.empty: g.exit("There is no selection.")

oldsecs = time()
maxstate = g.numstates() - 1

# these are the commands:
extend = '70116011'
extend_left = '4011401150116011'
extend_right = '5011501140116011'
retract = '4011501160116011'
retract_left = '5011601160116011'
retract_right = '4011601160116011'
mark = '701160114011501170116011'
erase = '601170114011501160116011'
sense = '70117011'
cap = '40116011'
               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()

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

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
Exemple #37
0
def iscomment(line):
    return line.strip() == "" or line.lstrip().startswith("#")


g.setrule("LifeHistory")

try:
    currcats = []

    with open(catfilename) as catfile:
        for line in catfile:
            if iscomment(line):
                # Organize all the previous cats.
                if currcats:
                    currcat = reduce(operator.add, (cat.translate(0, idx * size) for idx, cat in enumerate(currcats)))
                    cats.append(currcat)
                # Prepare new cat container
                currcats = []
            else:
                currcats.append(glife.pattern(line))
        currcat = reduce(operator.add, (cat.translate(0, idx * size) for idx, cat in enumerate(currcats)))
        cats.append(currcat)
except:
    if catfilename == "":
        g.exit()
    else:
        raise

totalpat = reduce(operator.add, (currcat.translate(idx * size, 0) for idx, currcat in enumerate(cats)))
totalpat.put()
# (program length is mostly unrelated to machine size, so it all works)
write_program(program)

# write the data tape
data_tape = ''
rect = g.getrect()   # copy everything within the bounding rectangle
width = rect[2]
height = rect[3]
x = rect[0]
y = rect[1]
for row in inclusive_range(y+height-1,y):
    far_right = x+width-1
    while g.getcell(far_right,row)==0:
        far_right -= 1
        if far_right<x:
            g.exit('Empty rows forbidden: '+str(row))
    col = x
    while col <= far_right:
        if g.getcell(col,row)==1:
            data_tape+='11' # write 1
            col += 1
        else:
            if not g.getcells([col,row,n,1]): # next N cells zero?
                data_tape+='01'
                col += n
            else:
                data_tape+='10' # write 0
                col += 1
    data_tape+='001' # end of row
#data_tape+='000' # end of construction (actually we skip this command)
write_data_string(data_tape[::-1])
Exemple #39
0
# Shift current selection by given x y amounts using optional mode.
# Author: Andrew Trevorrow ([email protected]), June 2006.
# Updated to use exit command, Nov 2006.
# Updated to check for bounded grid, Oct 2010.

from glife import validint, inside
from string import lower
import golly as g

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

answer = g.getstring("Enter x y shift amounts and an optional mode\n" +
                     "(valid modes are copy/or/xor, default is or):",
                     "0 0 or",
                     "Shift selection")
xym = answer.split()

# extract x and y amounts
if len(xym) == 0: g.exit()
if len(xym) == 1: g.exit("Supply x and y amounts separated by a space.")
if not validint(xym[0]): g.exit("Bad x value: " + xym[0])
if not validint(xym[1]): g.exit("Bad y value: " + xym[1])
x = int(xym[0])
y = int(xym[1])

# extract optional mode
if len(xym) > 2:
    mode = lower(xym[2])
    if mode=="c": mode="copy"
    if mode=="o": mode="or"
            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()

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

if len(g.getrect()) == 0: g.exit("There are no objects.")

g.show("Click on or near live cell in object, move mouse and click again..." + helpmsg)
oldcursor = g.getcursor()
g.setcursor("Move")
oldcells = []        # cells under moved object
object = []          # cells in moving object
object1 = []         # cells in initial object

try:
   aborted = True
   moveobject()
   aborted = False
finally:
   g.setcursor(oldcursor)
   if aborted:
		
		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]
	

cells = g.getcells(g.getrect())
curGunPeriod = PeriodCalculator()

if curGunPeriod == -1:
	note("Failed to find gun period")
	g.exit("No gun found")

edgeGlider = EdgeGlider()

if edgeGlider == -1:
	g.note("Please orient the gun properly")
	g.exit("No glider found in bottom right corner")

valueGun = GunArea(cells, curGunPeriod)
g.show("The value = " + str(valueGun[0]) + ", The box = " + str(valueGun[2]) )
Exemple #42
0
# use same file name as in goto.lua
GotoINIFileName = g.getdir("data") + "goto.ini"
previousgen = ""
try:
    f = open(GotoINIFileName, 'r')
    previousgen = f.readline()
    f.close()
    if not validint(previousgen):
        previousgen = ""
except:
    # should only happen 1st time (GotoINIFileName doesn't exist)
    pass

gen = g.getstring("Enter the desired generation number,\n" +
                  "or -n/+n to go back/forwards by n:",
                  previousgen, "Go to generation")
if len(gen) == 0:
    g.exit()
elif gen == "+" or gen == "-":
    # clear the default
    savegen(GotoINIFileName, "")
elif not validint(gen):
    g.exit('Sorry, but "' + gen + '" is not a valid integer.')
else:
    # best to save given gen now in case user aborts script
    savegen(GotoINIFileName, gen)
    oldstep = g.getstep()
    goto(gen.replace(",",""))
    g.setstep(oldstep)
Exemple #43
0
def ConvertTreeToRule(rule_name, total_states, icon_pixels):
    '''
    Convert rule_name.tree to rule_name.rule and delete the .tree file.
    
    If rule_name.colors exists then use it to create an @COLORS section
    and delete the .colors file.
    
    If icon_pixels is supplied then add an @ICONS section.
    Format of icon_pixels (in this example there are 4 icons at each size):
    
    ---------------------------------------------------------
    |             |             |             |             |
    |             |             |             |             |
    |    31x31    |    31x31    |    31x31    |    31x31    |
    |             |             |             |             |
    |             |             |             |             |
    ---------------------------------------------------------
    |       |.....|       |.....|       |.....|       |.....|
    | 15x15 |.....| 15x15 |.....| 15x15 |.....| 15x15 |.....|
    |       |.....|       |.....|       |.....|       |.....|
    ---------------------------------------------------------
    |7x7|.........|7x7|.........|7x7|.........|7x7|.........|
    ---------------------------------------------------------
    
    The top layer of 31x31 icons is optional -- if not supplied (ie. the
    height is 22) then there are no gaps between the 15x15 icons.
    '''
    rulepath = golly.getdir('rules')+rule_name+'.rule'
    treepath = golly.getdir('rules')+rule_name+'.tree'
    colorspath = golly.getdir('rules')+rule_name+'.colors'

    # get contents of .tree file
    try:
        treefile = open(treepath,'r')
        treedata = treefile.read()
        treefile.close()
    except:
        golly.exit('Failed to open .tree file: '+treepath)
    
    # if the .rule file already exists then only replace the @TREE section
    # so we don't clobber any other info added by the user
    if os.path.isfile(rulepath):
        ReplaceTreeSection(rulepath, treedata)
        os.remove(treepath)
        if os.path.isfile(colorspath): os.remove(colorspath)
        return
    
    # create a new .rule file
    rulefile = open(rulepath,'w')
    rulefile.write('@RULE '+rule_name+'\n\n')
    rulefile.write('@TREE\n\n')
    
    # append contents of .tree file, then delete that file
    rulefile.write(treedata)
    os.remove(treepath)
    
    # if .colors file exists then append @COLORS section and delete file
    if os.path.isfile(colorspath):
        colorsfile = open(colorspath,'r')
        rulefile.write('\n@COLORS\n\n')
        for line in colorsfile:
            if line.startswith('color') or line.startswith('gradient'):
                # strip off everything before 1st digit
                line = line.lstrip('colorgadient= \t')
            rulefile.write(line)
        colorsfile.close()
        os.remove(colorspath)
    
    # if icon pixels are supplied then append @ICONS section
    if len(icon_pixels) > 0:
        wd = len(icon_pixels[0])
        ht = len(icon_pixels)
        iconsize = 15                   # size of icons in top row
        if ht > 22: iconsize = 31       # 31x31 icons are present
        numicons = wd / iconsize
        
        # get colors used in all icons (we assume each icon size uses the same set of colors)
        colors, multi_colored = GetColors(icon_pixels, wd, ht)
        if len(colors) > 256:
            golly.warn('Icons use more than 256 colors!')
            rulefile.flush()
            rulefile.close()
            return
        if multi_colored:
            # create @COLORS section using color info in icon_pixels (not grayscale)
            rulefile.write('\n@COLORS\n\n')
            if numicons >= total_states:
                # extra icon is present so use top right pixel to set the color of state 0
                R,G,B = icon_pixels[0][wd-1]
                rulefile.write('0 ' + str(R) + ' ' + str(G) + ' ' + str(B) + '\n')
                numicons -= 1
            # set colors for each live state to the average of the non-black pixels
            # in each icon on top row (note we've skipped the extra icon detected above)
            for i in xrange(numicons):
                nbcount = 0
                totalR = 0
                totalG = 0
                totalB = 0
                for row in xrange(iconsize):
                    for col in xrange(iconsize):
                        R,G,B = icon_pixels[row][col + i*iconsize]
                        if R > 0 or G > 0 or B > 0:
                            nbcount += 1
                            totalR += R
                            totalG += G
                            totalB += B
                if nbcount > 0:
                    rulefile.write(str(i+1) + ' ' + str(totalR / nbcount) + ' ' \
                                                  + str(totalG / nbcount) + ' ' \
                                                  + str(totalB / nbcount) + '\n')
                else:
                    # avoid div by zero
                    rulefile.write(str(i+1) + ' 0 0 0\n')
        
        # create @ICONS section using (r,g,b) triples in icon_pixels[row][col]
        rulefile.write('\n@ICONS\n')
        if ht > 22:
            # top row of icons is 31x31
            CreateXPMIcons(colors, icon_pixels, 31,  0, 31, numicons, rulefile)
            CreateXPMIcons(colors, icon_pixels, 15, 31, 31, numicons, rulefile)
            CreateXPMIcons(colors, icon_pixels,  7, 46, 31, numicons, rulefile)
        else:
            # top row of icons is 15x15
            CreateXPMIcons(colors, icon_pixels, 15,  0, 15, numicons, rulefile)
            CreateXPMIcons(colors, icon_pixels,  7, 15, 15, numicons, rulefile)
    
    rulefile.flush()
    rulefile.close()
Exemple #44
0
# Change the entire pattern from emulated-Margolus states to N-state:

from glife import rect
import golly as g

r = rect( g.getrect() )
if r.empty: g.exit("There is no pattern.")

for row in xrange(r.top, r.top + r.height):
    for col in xrange(r.left, r.left + r.width):
        s = g.getcell(col,row)
        g.setcell(col, row, (s+s%2)/2-1)
#
# 3 July 2007:  added code to avoid errors in rules like Seeds,
#  where the Golly canonical form of the rule doesn't include a '/'
#
# Modified by Andrew Trevorrow, 20 July 2006 (faster, simpler and
# doesn't change the current clipboard).
#
# Modified by Andrew Trevorrow, 5 October 2007 (metafied pattern is
# created in a separate layer so we don't clobber the selection).

import os
import golly as g
from glife import *

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

# check that a layer is available for the metafied pattern;
# if metafied layer already exists then we'll use that
layername = "metafied"
metalayer = -1
for i in xrange(g.numlayers()):
   if g.getname(i) == layername:
      metalayer = i
      break
if metalayer < 0 and g.numlayers() == g.maxlayers():
   g.exit("You need to delete a layer.")

# note that getrule returns canonical rule string
rulestr = g.getrule().split(":")[0]
if (not rulestr.startswith("B")) or (rulestr.find("/S") == -1):
Exemple #46
0
import golly
import os
from glife.ReadRuleTable import *
from glife.RuleTree import *
from glife.EmulateTriangular import *
from glife.EmulateMargolus import *
from glife.EmulateOneDimensional import *
from glife.EmulateHexagonal import *

# ask user to select .table file
filename = golly.opendialog('Open a rule table to convert:',
                      'Rule tables (*.table)|*.table',
                      golly.getdir('rules'))

if len(filename) == 0: golly.exit()    # user hit Cancel

# add new converters here as they become available:
Converters = {
    "vonNeumann":ConvertRuleTableTransitionsToRuleTree,
    "Moore":ConvertRuleTableTransitionsToRuleTree,
    "triangularVonNeumann":EmulateTriangular,
    "triangularMoore":EmulateTriangular,
    "Margolus":EmulateMargolus,
    "square4_figure8v":EmulateMargolus,
    "square4_figure8h":EmulateMargolus,
    "square4_cyclic":EmulateMargolus,
    "oneDimensional":EmulateOneDimensional,
    "hexagonal":EmulateHexagonal,
}

golly.show("Reading from rule table file...")
Exemple #47
0
                     important[3], important[4]))

pointer = [0, 0]
instruction_pointer = "start"

while True:
    command = commands[[i[0] for i in commands].index(instruction_pointer)]
    pointer = [pointer[0] + command[1], pointer[1] + command[2]]
    x = pointer[0]
    y = pointer[1]

    print(command, pointer)
    if golly.getcell(x, y):
        golly.fit()

        golly.exit()

    else:
        golly.setcell(x, y, 1)

    neighbours = [
        golly.getcell(x - 1, y),
        golly.getcell(x + 1, y),
        golly.getcell(x, y - 1),
        golly.getcell(x, y + 1),
    ]

    if any(neighbours):
        instruction_pointer = command[3]

    else:
Exemple #48
0
                ) != 0:  # add eight neighbors of each ON cell to the mask
                    if [pat[i] + x, pat[i + 1] + y] not in env:
                        env.append([pat[i] + x, pat[i + 1] + y])
    for i in range(0, len(pat), 2):
        if [pat[i], pat[i + 1]] in env:
            env.remove([pat[i],
                        pat[i + 1]])  # take original pattern back out of mask
        # else: # with the reduced envelope, this will now happen, e.g. with *WSS singleton sparks
        #  g.note("Technical error: " + str([pat[i],pat[i+1]])+ " not in envelope:" + str(env) + " \n\n" + str(pat))
    return list(itertools.chain.from_iterable(env))


r = g.getselrect()
if len(r) == 0:
    r = g.getrect()
    if len(r) == 0: g.exit("No pattern, nothing to do.")
sel = g.getcells(r)
if len(sel) == 0: g.exit("Nothing in selection.")
if len(sel) % 2: g.exit("Can't do the rewinding trick on multistate rules.")
all = g.getcells(g.getrect())
allcoords = []
for i in range(0, len(all), 2):
    allcoords.append([all[i], all[i + 1]])

# g.show("Processing object library...")
odict = dict()
for i in range(len(lib)):
    # g.show("Processing object " + lib[i][0])
    # run and normalize each library object until a duplicate of the original pattern appears
    # The number of ticks to duplication, and the offset, give all the information needed to rewind...
    obj = g.parse(lib[i][1])
Exemple #49
0
# Fill clicked region with current drawing state.
# Author: Andrew Trevorrow ([email protected]), Jan 2011.

import golly as g
from time import time

# avoid an unbounded fill
if g.empty():
    if g.getwidth() == 0 or g.getheight() == 0:
        g.exit("You cannot fill an empty universe that is unbounded!")
else:
    # set fill limits to the pattern's bounding box
    # (these will be extended below if the grid is bounded)
    r = g.getrect()
    minx = r[0]
    miny = r[1]
    maxx = minx + r[2] - 1
    maxy = miny + r[3] - 1

# allow filling to extend to the edges of bounded grid
if g.getwidth() > 0:
    minx = -int(g.getwidth()/2)
    maxx = minx + g.getwidth() - 1
if g.getheight() > 0:
    miny = -int(g.getheight()/2)
    maxy = miny + g.getheight() - 1

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

def checkneighbor(x, y, oldstate):
    # first check if x,y is outside fill limits
Exemple #50
0
import golly as g
from bitstring import BitArray

try:
	from PIL import Image
	from PIL import ImageSequence
except:
	g.exit("You need to install PIL (Python Imaging Library).")
	 
fname = g.opendialog("Open File", "*.gif", "", "")
if not len(fname):
  g.exit("")
  
outfile = g.savedialog("Save RAW Data File", "*.*", "", "ROM.dat")
if not len(outfile):
	g.exit("")
	
image = Image.open(fname)
buff = BitArray()

for frame in ImageSequence.Iterator(image):
	frame = list(frame.convert("1").getdata())
	for i in range(len(frame)):
		buff.append('0b0' if frame[i] & 0x1 else '0b1')

# normalize to 256k
if buff.length < 1 << 18:
	for i in range ((1 << 18 - 3) - (buff.length >> 3)):
		buff.append('0x00')
elif buff.length > 1 << 18:
	del buff[(1 << 18) + 1 : buff.length]
	return result

userSpeed = g.getstring("Please enter step/period", "1/8")

if userSpeed.split("/")[0] == 'c':
	userSpeed = userSpeed.replace("c", "1")
else:
	userSpeed = userSpeed.replace("c", "")
	
iniStep = int(userSpeed.split("/")[0]) 
iniPeriod = int(userSpeed.split("/")[1])

speed = float(iniStep) / iniPeriod

if speed >= 0.25:
	g.exit("This speed should be strictly less than c/4")

if (iniPeriod + 2 * iniStep) % 8 == 0:
	g.exit("This period and step are not supported: period + 2 * step, should not be 0 mod 8")

if (iniPeriod - 2 * iniStep) % 8 == 0:
	g.exit("This period and step are not supported: period - 2 * step, should not be 0 mod 8")

fenseY = 220
fenseX = 0 

for k in xrange(1, 1000000):

	step = iniStep * k
	period = iniPeriod * k
	distBack = period / 2 + step
Exemple #52
0
#        so to get .cells file for new articles, first .rle files are created
#        and (manually) uploaded, then those same .rle files are downloaded again
#        the next time the script is run, and are used to make .cells files)

import golly as g
import urllib.request
import re
import os

samplepath = g.getstring("Enter path to generate .rle and .cells files",
                         "C:/users/{username}/Desktop/LW/")
if samplepath == "C:/users/{username}/Desktop/LW/":
    g.note("Please run this script again and change the sample path to something that works on your system.\n\n" \
         + "If the path you supply does not point to folders that you have permission to write to, " \
         + "or if synthfile is not present, the data collection process will eventually fail with an error.")
    g.exit()

outfolder = samplepath + "rle/"
cellsfolder = samplepath + "cells/"
rlefolder = samplepath + "rledata/"
synthfolder = samplepath + "synthesis-costs/"
synthfile = synthfolder + "synthesis-costs.txt"

if not os.path.exists(samplepath):
    resp = g.getstring(
        "No folder exists at '" + samplepath + "'.  Create it and subfolders?",
        "Yes")
    if resp.lower()[:1] == "y":
        os.makedirs(
            outfolder
        )  # this has no effect if folder(s) already present and/or contain files
Exemple #53
0
# Invert all cell states in the current selection.
# Author: Andrew Trevorrow ([email protected]), Jun 2006.
# Updated to use exit command, Nov 2006.
# Updated to use numstates command, Jun 2008.

from glife import rect
from time import time
import golly as g

r = rect( g.getselrect() )
if r.empty: g.exit("There is no selection.")

oldsecs = time()
maxstate = g.numstates() - 1

for row in xrange(r.top, r.top + r.height):
   # if large selection then give some indication of progress
   newsecs = time()
   if newsecs - oldsecs >= 1.0:
      oldsecs = newsecs
      g.update()

   # also allow keyboard interaction
   g.dokey( g.getkey() )

   for col in xrange(r.left, r.left + r.width):
      g.setcell(col, row, maxstate - g.getcell(col, row))

if not r.visible(): g.fitsel()
Exemple #54
0
    # use name.tree to create name.rule (with no icons);
    # note that if name.rule already exists then we only replace the info in
    # the @TREE section to avoid clobbering any other info added by the user
    ConvertTreeToRule(name, n_states, [])
    
    golly.setalgo("RuleLoader")
    golly.setrule(name)
    golly.show("Created "+golly.getdir("rules")+name+".rule and switched to that rule.")

except:
    import sys
    import traceback
    exception, msg, tb = sys.exc_info()
    golly.warn(\
 '''To use this script, copy a Python format rule definition into the clipboard, e.g.:

 name = "ParityNWE"
 n_states = 5
 n_neighbors = 4
 # order for 4 neighbors is N, W, E, S, C
 def transition_function ( s ) :
       return ( s[0] + s[1] + s[2] ) % 5

 For more examples, see the script file (right-click on it).
 ____________________________________________________

 A problem was encountered with the supplied rule:

 '''+ '\n'.join(traceback.format_exception(exception, msg, tb)))
    golly.exit()
# Randomly fill cells in the current selection.
# Author: Andrew Trevorrow ([email protected]), March 2011.

import golly as g
from glife import rect, validint
from time import time
from random import randint

r = rect(g.getselrect())
if r.empty:
    g.exit("There is no selection.")

maxlive = g.numstates() - 1

# use previous values if they exist
inifilename = g.getdir("data") + "random-fill.ini"
previousvals = "50 1 " + str(maxlive)
try:
    f = open(inifilename, "r")
    previousvals = f.readline()
    f.close()
except:
    # should only happen 1st time (inifilename doesn't exist)
    pass

result = g.getstring(
    "Enter percentage minstate maxstate values\n"
    + "where the percentage is an integer from 0 to 100\n"
    + "and the state values are integers from 1 to "
    + str(maxlive)
    + "\n"
Exemple #56
0
def ReadRuleTable(filename):
    '''
    Return n_states, neighborhood, transitions
    e.g. 2, "vonNeumann", [[0],[0,1],[0],[0],[1],[1]]
    Transitions are expanded for symmetries and bound variables.
    '''
    f = open(filename, 'r')
    vars = {}
    symmetry_string = ''
    symmetry = []
    n_states = 0
    neighborhood = ''
    transitions = []
    numParams = 0
    for line in f:
        if line[0] == '#' or line.strip() == '':
            pass
        elif line[0:9] == 'n_states:':
            n_states = int(line[9:])
            if n_states < 0 or n_states > 256:
                golly.warn('n_states out of range: ' + n_states)
                golly.exit()
        elif line[0:13] == 'neighborhood:':
            neighborhood = line[13:].strip()
            if not neighborhood in SupportedSymmetries:
                golly.warn('Unknown neighborhood: ' + neighborhood)
                golly.exit()
            numParams = len(SupportedSymmetries[neighborhood].items()[0][1][0])
        elif line[0:11] == 'symmetries:':
            symmetry_string = line[11:].strip()
            if not symmetry_string in SupportedSymmetries[neighborhood]:
                golly.warn('Unknown symmetry: ' + symmetry_string)
                golly.exit()
            symmetry = SupportedSymmetries[neighborhood][symmetry_string]
        elif line[0:4] == 'var ':
            line = line[4:]  # strip var keyword
            if '#' in line:
                line = line[:line.find('#')]  # strip any trailing comment
            # read each variable into a dictionary mapping string to list of ints
            entries = line.replace('=',' ').replace('{',' ').replace(',',' ').\
                replace(':',' ').replace('}',' ').replace('\n','').split()
            vars[entries[0]] = []
            for e in entries[1:]:
                if e in vars:
                    vars[entries[0]] += vars[e]  # vars allowed in later vars
                else:
                    vars[entries[0]].append(int(e))
        else:
            # assume line is a transition
            if '#' in line:
                line = line[:line.find('#')]  # strip any trailing comment
            if ',' in line:
                entries = line.replace('\n',
                                       '').replace(',',
                                                   ' ').replace(':',
                                                                ' ').split()
            else:
                entries = list(line.strip())  # special no-comma format
            if not len(entries) == numParams:
                golly.warn('Wrong number of entries on line: ' + line +
                           ' (expected ' + str(numParams) + ')')
                golly.exit()
            # retrieve the variables that repeat within the transition, these are 'bound'
            bound_vars = [
                e for e in set(entries) if entries.count(e) > 1 and e in vars
            ]
            # iterate through all the possible values of each bound variable
            var_val_indices = dict(zip(bound_vars, [0] * len(bound_vars)))
            while True:
                ### AKT: this code causes syntax error in Python 2.3:
                ### transition = [ [vars[e][var_val_indices[e]]] if e in bound_vars \
                ###                else vars[e] if e in vars \
                ###                else [int(e)] \
                ###                for e in entries ]
                transition = []
                for e in entries:
                    if e in bound_vars:
                        transition.append([vars[e][var_val_indices[e]]])
                    elif e in vars:
                        transition.append(vars[e])
                    else:
                        transition.append([int(e)])
                if symmetry_string == 'permute' and neighborhood in PermuteLater:
                    # permute all but C,C' (first and last entries)
                    for permuted_section in permu2(transition[1:-1]):
                        permuted_transition = [
                            transition[0]
                        ] + permuted_section + [transition[-1]]
                        if not permuted_transition in transitions:
                            transitions.append(permuted_transition)
                else:
                    # expand for symmetry using the explicit list
                    for s in symmetry:
                        tran = [transition[i] for i in s]
                        if not tran in transitions:
                            transitions.append(tran)
                # increment the variable values (or break out if done)
                var_val_to_change = 0
                while var_val_to_change < len(bound_vars):
                    var_label = bound_vars[var_val_to_change]
                    if var_val_indices[var_label] < len(vars[var_label]) - 1:
                        var_val_indices[var_label] += 1
                        break
                    else:
                        var_val_indices[var_label] = 0
                        var_val_to_change += 1
                if var_val_to_change >= len(bound_vars):
                    break
    f.close()
    return n_states, neighborhood, transitions
Exemple #57
0
from glife import validint, inside
from string import lower
import golly as g
import math

rules = ("JvN29", "Nobili32", "Hutton32")

rule = g.getrule ()
if rule not in rules:
    g.exit ("Invalid rule: " + rule + " (must be " + rules + ")")

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

answer = g.getstring("Enter direction to rotate in\n" +
                     "(valid rotations are cw and ccw, default is cw):",
                     "cw",
                     "Rotate selection")

if answer != "cw" and answer != "ccw":
    g.exit ("Unknown direction: " + answer + " (must be cw/ccw)")

cells = g.getcells (rect)

jvn_rotate = (( 9, 12, 11, 10),
              (13, 16, 15, 14),
              (17, 20, 19, 18),
              (21, 24, 23, 22))

def rotated (rotations, direction, state):
Exemple #58
0
    draw_line(x + barwd, 0, x + barwd, -barht, extrastate)
    if barht > 1:
        # fill bar with corresponding color
        x1 = x + 1
        x2 = x + barwd - 1
        for y in xrange(barht - 1):
            draw_line(x1, -(y + 1), x2, -(y + 1), state)
    if statecount[state] > 0:
        # show count on top of bar
        t, twd, tht = color_text(str(statecount[state]), extrastate)
        t.put(barwd * (state + 1) - barwd / 2 - twd / 2, -barht - tht - 3)


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

if g.empty(): g.exit("There is no pattern.")
if g.numstates() == 256: g.exit("No room for extra state.")

# check that a layer is available for the histogram
histname = "histogram"
histlayer = -1
for i in xrange(g.numlayers()):
    if g.getname(i) == histname:
        histlayer = i
        break
if histlayer == -1 and g.numlayers() == g.maxlayers():
    g.exit("You need to delete a layer.")

# use selection rect if it exists, otherwise use pattern bounds
label = "Selection"
r = rect(g.getselrect())
# 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)