Gustavo Ramos Rehermann's patterns

A forum where anything goes. Introduce yourselves to other members of the forums, discuss how your name evolves when written out in the Game of Life, or just tell us how you found it. This is the forum for "non-academic" content.
User avatar
praosylen
Posts: 2443
Joined: September 13th, 2014, 5:36 pm
Location: Pembina University, Home of the Gliders
Contact:

Re: Gustavo Ramos Rehermann's patterns

Post by praosylen » January 19th, 2016, 10:35 pm

dvgrn wrote:Other workable workarounds include creating a new layer, pasting in the pattern, and then

1) selecting and copying the pattern out to the clipboard and using g.getclipstr(). But it's not really a good idea to use the clipboard for a low-level task like this, at least without giving users clear warning. People might like what they have in their clipboard, and not want it to be suddenly clobbered by random junk.
There's an ugly but useful workaround for this: Use g.getclipstr() to save the original clipboard string at the beginning , and reinstate it using g.setclipstr() at the end. The only problem is when the original clipboard string is extremely long; it wastes a lot of computation, especially if the workaround is done multiple times.
former username: A for Awesome
praosylen#5847 (Discord)

The only decision I made was made
of flowers, to jump universes to one of springtime in
a land of former winter, where no invisible walls stood,
or could stand for more than a few hours at most...

User avatar
dvgrn
Moderator
Posts: 10612
Joined: May 17th, 2009, 11:00 pm
Location: Madison, WI
Contact:

Re: Gustavo Ramos Rehermann's patterns

Post by dvgrn » January 19th, 2016, 11:11 pm

A for awesome wrote:There's an ugly but useful workaround for this: Use g.getclipstr() to save the original clipboard string at the beginning , and reinstate it using g.setclipstr() at the end. The only problem is when the original clipboard string is extremely long; it wastes a lot of computation, especially if the workaround is done multiple times.
Another odd case is when something has been copied that isn't a string. Let's say you copy some formatted Rich Text Format text and pictures out of WordPad. After you run your script-with-workaround, you've mysteriously lost all your italics and font sizes and pictures and so forth.

The clipboard is a strange and uncanny thing, a miracle of rare device. I guess that's why I try to leave it alone, except when I would just be copying something out of some text file as the result of a script anyway.

User avatar
Gustavo6046
Posts: 647
Joined: December 7th, 2013, 6:26 pm
Location: Brazil.

Re: Gustavo Ramos Rehermann's patterns

Post by Gustavo6046 » January 20th, 2016, 8:00 am

dvgrn wrote:
A for awesome wrote:There's an ugly but useful workaround for this: Use g.getclipstr() to save the original clipboard string at the beginning , and reinstate it using g.setclipstr() at the end. The only problem is when the original clipboard string is extremely long; it wastes a lot of computation, especially if the workaround is done multiple times.
Another odd case is when something has been copied that isn't a string. Let's say you copy some formatted Rich Text Format text and pictures out of WordPad. After you run your script-with-workaround, you've mysteriously lost all your italics and font sizes and pictures and so forth.

The clipboard is a strange and uncanny thing, a miracle of rare device. I guess that's why I try to leave it alone, except when I would just be copying something out of some text file as the result of a script anyway.
I wonder who uses Wordpad instead of Libreoffice... :P

Anyway the script I done is behaving too weird and unfunctionally in a way that can't be described. (plz-hlp)
*yawn* What a nothing-to-do day! Let's be the only person in the world to do CGOL during boring times. :)

User avatar
Scorbie
Posts: 1692
Joined: December 7th, 2013, 1:05 am

Re: Gustavo Ramos Rehermann's patterns

Post by Scorbie » January 20th, 2016, 8:52 am

Gustavo6046 wrote:I wonder who uses Wordpad instead of Libreoffice... :P
Just to clarify, that was not his point.
dvgrn wrote:Let's say you copy some formatted Rich Text Format text and pictures out of WordPad. After you run your script-with-workaround, you've mysteriously lost all your italics and font sizes and pictures and so forth.
Copying text from WordPad and pasting it directly again doesn't damage anything, but manipulating and restoring the same string damages the format?! Hmm, that's a pretty strange aspect of the clipboard.
Gustavo6046 wrote:Anyway the script I done is behaving too weird and unfunctionally in a way that can't be described. (plz-hlp)
I'm not sure if anyone would willingly spend their time to do your work, especially debugging. For a feeble script-writer like me, that is the most annoying step through writing programs.

User avatar
Gustavo6046
Posts: 647
Joined: December 7th, 2013, 6:26 pm
Location: Brazil.

Re: Gustavo Ramos Rehermann's patterns

Post by Gustavo6046 » January 20th, 2016, 9:36 am

Can there be a console output as well? I didn't tested print but since there is no console I don't think it would work either.

g.show() don't let you scroll, which is a pity.
*yawn* What a nothing-to-do day! Let's be the only person in the world to do CGOL during boring times. :)

User avatar
Scorbie
Posts: 1692
Joined: December 7th, 2013, 1:05 am

Re: Gustavo Ramos Rehermann's patterns

Post by Scorbie » January 20th, 2016, 10:07 am

I pointed out a similar thing recently: viewtopic.php?f=9&t=1965#p25957
Summary: launch Golly from the terminal and you'll see the print statements.
(e.g. by launching /your/path/to/Golly/golly in the terminal)

User avatar
Gustavo6046
Posts: 647
Joined: December 7th, 2013, 6:26 pm
Location: Brazil.

Re: Gustavo Ramos Rehermann's patterns

Post by Gustavo6046 » January 20th, 2016, 12:54 pm

Scorbie wrote:I pointed out a similar thing recently: viewtopic.php?f=9&t=1965#p25957
Summary: launch Golly from the terminal and you'll see the print statements.
(e.g. by launching /your/path/to/Golly/golly in the terminal)
Golly should have a bShowConsole option... I wonder if they are still working in it.
*yawn* What a nothing-to-do day! Let's be the only person in the world to do CGOL during boring times. :)

User avatar
Gustavo6046
Posts: 647
Joined: December 7th, 2013, 6:26 pm
Location: Brazil.

Re: Gustavo Ramos Rehermann's patterns

Post by Gustavo6046 » January 21st, 2016, 7:55 pm

This is the VERY FIRST edgy long-boat reaction I've ever found:

Code: Select all

x = 9, y = 13, rule = LifeHistory
6.E$5.E$5.3E7$6.E$5.E.E$2E3.E2.E$2E4.2E!
Unfortunately no use... to a extent...
*yawn* What a nothing-to-do day! Let's be the only person in the world to do CGOL during boring times. :)

User avatar
Gustavo6046
Posts: 647
Joined: December 7th, 2013, 6:26 pm
Location: Brazil.

Re: Gustavo Ramos Rehermann's patterns

Post by Gustavo6046 » January 22nd, 2016, 11:17 am

How do I automatically archive the piles of crumbs resultable from that Toaster I? (number of conduits + lots o Snarks) The one I posted earlier, where the snarks are adjustable.
Edit: --
gmc_nxtman wrote:Incremental synthesis (haven't made one with kickbacks yet):

Code: Select all

<rle>
What is a kickback?
*yawn* What a nothing-to-do day! Let's be the only person in the world to do CGOL during boring times. :)

mniemiec
Posts: 1590
Joined: June 1st, 2013, 12:00 am

Re: Gustavo Ramos Rehermann's patterns

Post by mniemiec » January 22nd, 2016, 12:49 pm

Gustavo6046 wrote:What is a kickback?
Before asking simple questions like this, you should first try looking on the LifeWiki. You would get your answer in only 3 mouse clicks.

User avatar
dvgrn
Moderator
Posts: 10612
Joined: May 17th, 2009, 11:00 pm
Location: Madison, WI
Contact:

Re: Gustavo Ramos Rehermann's patterns

Post by dvgrn » January 22nd, 2016, 12:51 pm

Gustavo6046 wrote:How do I automatically archive the piles of crumbs resultable from that Toaster I? (number of conduits + lots o Snarks) The one I posted earlier, where the snarks are adjustable.
Rather than just a vague reference to things like "the one I posted earlier", it would be nice if you'd get in the habit of including a link. I'm a lot more likely to click on a link than to go paging back through this thread to find what you're talking about.

I can't help remembering Toaster I, though! Please consider simplifying your toaster to make a Toaster II before you start collecting crumbs. Whatever crumbs might spew out of Toaster I won't likely be useful for anything, because of the surplus of Snarks surrounding the output location... as mniemiec has explained.

To make an automatic archive: write a script to run through all possible combinations of reflector adjustments -- nested for loops, let's say. For each combination, the script should
  • place Snarks at the correct offsets,
  • run the pattern,
  • check that the Snarks and other catalysts all survive
  • remove the Snarks and other catalysts from the pattern
  • dump the remaining crumbs to a text file.
One line of text per constellation of crumbs would be good -- maybe use ptbsearch format, or plain headerless RLE.
Gustavo6046 wrote:What is a kickback?
The Life Lexicon (Golly > Help > Life Lexicon) would also be happy to answer this kind of question for you. Kickback reaction. These are used to tighten up continuous syntheses sometimes, at the cost of one more glider per kickback, or to sneak a glider in to a tight recipe where it would otherwise conflict with other incoming gliders.

Kickbacks don't really seem to be necessary in this case. It's a perfectly nice continuous synthesis already, though it's labeled as "incremental".

User avatar
Gustavo6046
Posts: 647
Joined: December 7th, 2013, 6:26 pm
Location: Brazil.

Re: Gustavo Ramos Rehermann's patterns

Post by Gustavo6046 » January 22nd, 2016, 1:26 pm

Oh thanks :) I forgot about LifeWiki & the Lexicon.

I am fixing HRF and making a Cell list to RLE function:

Code: Select all

import golly as g
import time as t

def cell_list_to_rle(debug = False, *cells):
	
	if debug == True:
		g.show(str(cells))
		t.sleep(1)
	
	top = None
	left = None
	bottom = None
	right = None
	tmpn = 0
	tmpl = []
	clst = []
	rle = ""
	
	for x in cells:
		tmpn += 1
		tmpl.append(x)
		if tmpn == 2:
			clst.append(tmpl)
			tmpl = []
			tmpn = 0
			
	if debug == True:
		g.show(str(clst))
		t.sleep(1)
			
	for x in clst:
		if x[0] < left or left == None:
			left = x[0]
			g.show(str(x[0]))
		if x[1] < top or top == None:
			top = x[1]
			g.show(str(x[1]))
		if x[0] > right or right == None:
			right = x[0]
			g.show(str(x[0]))
		if x[1] > bottom or bottom == None:
			bottom = x[1]
			g.show(str(x[1]))
	
	for x in range(left, right):
		for y in range(top, bottom):
			bFound = False
			for z in clst:
				if z == [x, y]:
					rle += "o"
					bFound = True
				if z[0] == right and z[1] == y:
					rle += "$"
					bFound = True
				if z[0] == right and z[1] == bottom:
					rle += "!"
					return rle
			if not bFound:
				rle += "b"
However it only returns "none" or "!", probably the last FOR isn't working...
*yawn* What a nothing-to-do day! Let's be the only person in the world to do CGOL during boring times. :)

User avatar
dvgrn
Moderator
Posts: 10612
Joined: May 17th, 2009, 11:00 pm
Location: Madison, WI
Contact:

Re: Gustavo Ramos Rehermann's patterns

Post by dvgrn » January 22nd, 2016, 2:28 pm

Gustavo6046 wrote:I am fixing HRF and making a Cell list to RLE function...
However it only returns "none" or "!", probably the last FOR isn't working.
Is there a reason why you're worrying about writing your own function, when there's a perfectly good working one available? If you looked at the link I gave you in this message, what did you think was wrong with that code?

Here's a slightly altered version of Nathaniel's code. It seems to me that this should solve your problem just fine:

selection-to-clipboard-as-RLE.py:

Code: Select all

# RLE computation script for use with Golly.
# Author: Nathaniel Johnston (nathaniel@nathanieljohnston.com), June 2009.
#          DMG: Refactored slightly so that the function input is a simple cell list.
#               This script the current selection as a test.  No error checking added.
#               TBD:  check for multistate rule, show appropriate warning.

# Copies the RLE encoding of the current pattern to the clipboard


import golly as g

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

def chunks(l, n):
    for i in range(0, len(l), n):
        yield l[i:i+n]

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

def giveRLE(clist):
   clist_chunks = list (chunks (clist, 2))
   mcc = min(clist_chunks)
   rl_list = [[x[0]-mcc[0],x[1]-mcc[1]] for x in clist_chunks]
   rle_res = ""
   rle_len = 1
   rl_y = rl_list[0][1] - 1
   rl_x = 0
   for rl_i in rl_list:
      if rl_i[1] == rl_y:
         if rl_i[0] == rl_x + 1:
            rle_len += 1
         else:
            if rle_len == 1: rle_strA = ""
            else: rle_strA = str (rle_len)
            if rl_i[0] - rl_x - 1 == 1: rle_strB = ""
            else: rle_strB = str (rl_i[0] - rl_x - 1)

            rle_res = rle_res + rle_strA + "o" + rle_strB + "b"
            rle_len = 1
      else:
         if rle_len == 1: rle_strA = ""
         else: rle_strA = str (rle_len)
         if rl_i[1] - rl_y == 1: rle_strB = ""
         else: rle_strB = str (rl_i[1] - rl_y)
         if rl_i[0] == 1: rle_strC = "b"
         elif rl_i[0] == 0: rle_strC = ""
         else: rle_strC = str (rl_i[0]) + "b"
         
         rle_res = rle_res + rle_strA + "o" + rle_strB + "$" + rle_strC
         rle_len = 1

      rl_x = rl_i[0]
      rl_y = rl_i[1]
   
   if rle_len == 1: rle_strA = ""
   else: rle_strA = str (rle_len)
   rle_res = rle_res[2:] + rle_strA + "o"
   
   return rle_res+"!"
      
# --------------------------------------------------------------------

test_cell_list = g.getcells (g.getselrect())

RLE = giveRLE(test_cell_list)
g.setclipstr(RLE)
g.show(RLE)

User avatar
Gustavo6046
Posts: 647
Joined: December 7th, 2013, 6:26 pm
Location: Brazil.

Re: Gustavo Ramos Rehermann's patterns

Post by Gustavo6046 » January 22nd, 2016, 2:36 pm

It isn't good enough because it don't support multistate rules. I want HRF to work in multistate rules as well.

Code: Select all

# ...
def celleq(self, other):
    return g.evolve(self, 0) == g.evolve(other, 0)  # Both hand sides are lists, not glife.patterns! No super() needed.

# ...

def testReaction(xpos, ypos, sli):
	global found
	global debug
	orig = g.getcells(g.getrect())
	g.putcells(stillLifes[sli], xpos, ypos)
	this = g.getcells(g.getrect())
	oldgeneration = g.getgen()
	for i in range(maxgen):
		oldpat = g.getcells(g.getrect())
		g.step()
		if g.getcells(g.getrect()) == oldpat or g.getcells(g.getrect()) == []:
			break
		if celleq(g.getcells(g.getrect()), herschels[sli]):
			Found = True
			break
# ...
didn't seem to work. The right hand was just a very long list when I printed it out, even though they should be the very same...

But wait! I found out LifeHistory is the culprit! I can't remove the blue cells... :(

EDIT: Oooh wait, I also found out this assertion gives a error:

Code: Select all

def celleq(self, other):
    return g.evolve(self, 0) == g.evolve(other, 0)  # Both hand sides are lists, not glife.patterns! No super() needed.

assert celleq([0, 1, 0, 2], [0, 2, 0, 3])
celleq doesn't work! :x :x :x
*yawn* What a nothing-to-do day! Let's be the only person in the world to do CGOL during boring times. :)

User avatar
dvgrn
Moderator
Posts: 10612
Joined: May 17th, 2009, 11:00 pm
Location: Madison, WI
Contact:

Re: Gustavo Ramos Rehermann's patterns

Post by dvgrn » January 22nd, 2016, 3:31 pm

Gustavo6046 wrote:The right hand was just a very long list when I printed it out, even though they should be the very same...

But wait! I found out LifeHistory is the culprit! I can't remove the blue cells... :(
Sure you can -- you just have to write specific code to ignore them. It's certainly true that they won't just magically go away.
Gustavo6046 wrote:EDIT: Oooh wait, I also found out this assertion gives a error:

Code: Select all

def celleq(self, other):
    return g.evolve(self, 0) == g.evolve(other, 0)  # Both hand sides are lists, not glife.patterns! No super() needed.

assert celleq([0, 1, 0, 2], [0, 2, 0, 3])
celleq doesn't work!
The g.evolve() trick is for making sure that the self and other cell lists don't contain any duplicates, and that the cells are in sorted order. That way you don't get any false negatives from patterns that are really the same but have their cells listed in different orders -- e.g., a block rotated by g.transform(), compared with the original block.

The assertion is failing because your two patterns are not normalized -- the top left cell isn't the same, so of course the comparison fails. I'd suggest something like this:

Code: Select all

import golly as g

def celleq(self, other):
    ssort, osort = g.evolve(self, 0), g.evolve(other, 0)
    return g.transform(ssort,-ssort[0],-ssort[1]) == g.transform(osort,-osort[0],-osort[1])

assert celleq([0, 1, 0, 2], [0, 2, 0, 3])
That just means: "move all the cells in each list so that the first live cell in the upper left corner is (0,0)."

You could normalize the lists some other way -- make the upper left cell of the bounding box be (0,0) instead, for example. That might be better for some purposes.

This definition is a little simpler to code, though. I've used it in my last several projects, and usually it doesn't cause any trouble at all.

User avatar
Gustavo6046
Posts: 647
Joined: December 7th, 2013, 6:26 pm
Location: Brazil.

Re: Gustavo Ramos Rehermann's patterns

Post by Gustavo6046 » January 22nd, 2016, 3:54 pm

IT WOOORKS

Code: Select all

import golly as g
from sys import exit
from time import sleep

found = False

herschels = []

def celleq(self, other):
    ssort, osort = g.evolve(self, 0), g.evolve(other, 0)
    return g.transform(ssort,-ssort[0],-ssort[1]) == g.transform(osort,-osort[0],-osort[1])

assert celleq([0, 1, 0, 2], [0, 2, 0, 3])
	
testrect = g.getselrect();
if testrect == []:
	g.exit("Select the area where the still life is placeable!")

if g.empty():
	g.exit("There is no pattern to add bait!")
	
stillLifes = []

try:
	maxgen = int(g.getstring("Which is the max generation to test for?", "300", "HRF v0.1")) + 1
except ValueError:
	g.exit("Invalid number!")
if maxgen < 2:
	g.exit("Null number")
	
def addStillLife():
	while True:
		stillLife = g.getstring("What still life to test for? (RLE)", "2o$2o!", "HRF v0.1")
		stillLifes.append(g.parse(stillLife))
		addAnother = g.getstring("Add another still life? (y|n)", "n", "HRF v0.1")
		if addAnother.lower() == "n":
			break
		elif addAnother.lower() != "y":
			g.exit("Invalid letter!")
			
def removeFirstLine(str):
	result = str.rsplit('\n')
	result.pop(0)
	return ''.join(result)
			
def addResultDesired():
	while True:
		herschelDesired = g.getstring("What result to find? (RLE)", "3o$obo$obo!", "HRF v0.1")
		herschels.append(g.parse(herschelDesired))
		addAnother = g.getstring("Add another result desired? (y|n)", "n", "HRF v0.1")
		if addAnother.lower() == "n":
			break
		elif addAnother.lower() != "y":
			g.exit("Invalid letter!")

debug = False
addStillLife()
addResultDesired()
dmy = g.getstring("Debug mode? (y|n)", "n", "HRF v0.1")
if dmy.lower() == "y":
	debug = True
	g.autoupdate(True)
elif dmy.lower() != "n":
	g.exit("Invalid letter!")
	
def testReaction(xpos, ypos, sli):
	global found
	global debug
	global maxgen
	orig = g.getcells(g.getrect())
	g.putcells(stillLifes[sli], xpos, ypos)
	this = g.getcells(g.getrect())
	oldgeneration = g.getgen()
	for i in range(maxgen):
		oldpat = g.getcells(g.getrect())
		g.step()
		if g.getcells(g.getrect()) == oldpat or g.getcells(g.getrect()) == []:
			break
		if celleq(g.getcells(g.getrect()), herschels[sli]):
			found = True
			break
	g.clear(0)
	g.clear(1)
	g.setgen(oldgeneration)
	if found:
		g.putcells(this)
		g.exit("Found reaction!")
	else:
		g.putcells(orig)
		g.show("No result found at x:" + str(xpos) + ", y:" + str(ypos) + ", still life " + str(sli))
		

def tests():
	global found
	for n in range(testrect[2]):
		for m in range(testrect[3]):
			for o in range(len(stillLifes)):
				testReaction(n + testrect[0], m + testrect[1], o)
				if found:
					return
tests()
Now you can use it for general purpose searches!

EDIT:

I found out something strange. While in real life I have no friends, in virtual life I have these:
Z9SltsH.png
Z9SltsH.png (4.65 KiB) Viewed 202 times
*yawn* What a nothing-to-do day! Let's be the only person in the world to do CGOL during boring times. :)

User avatar
Gustavo6046
Posts: 647
Joined: December 7th, 2013, 6:26 pm
Location: Brazil.

Re: Gustavo Ramos Rehermann's patterns

Post by Gustavo6046 » January 22nd, 2016, 4:47 pm

HRF found this:

Code: Select all

x = 16, y = 11, rule = LifeHistory
2.3D$2.DBD$2.DBD2B6.CB$2.6B.B2.BCBC$2.11B2C$.13B$6B3C5B$.14B$2.12B$2.
4B2.2B3C$8.2B.B!
*yawn* What a nothing-to-do day! Let's be the only person in the world to do CGOL during boring times. :)

User avatar
Gustavo6046
Posts: 647
Joined: December 7th, 2013, 6:26 pm
Location: Brazil.

Re: Gustavo Ramos Rehermann's patterns

Post by Gustavo6046 » January 22nd, 2016, 5:47 pm

This is a experimental HRF version that inputs from a config file (.ini):

Code: Select all

import golly as g
from sys import exit
from time import sleep
from ConfigParser import RawConfigParser

found = False

herschels = []
stillLifes = []

def celleq(self, other):
    ssort, osort = g.evolve(self, 0), g.evolve(other, 0)
    return g.transform(ssort,-ssort[0],-ssort[1]) == g.transform(osort,-osort[0],-osort[1])

assert celleq([0, 1, 0, 2], [0, 2, 0, 3])
	
testrect = g.getselrect();
if testrect == []:
	g.exit("Select the area where the still life is placeable!")

if g.empty():
	g.exit("There is no pattern to add bait!")

inputconfig = g.getstring("Which file to get configuration from?")

input = RawConfigParser()
if input.read(InputConfig) == []:
	g.exit("Non-existent config file!")
try:
	debug = input.getboolean("General", "DebugMode")
	maxgens = input.getint("Input", "Generations")
	herschels = input.get("Input", "Results").split(",")
	stillLifes = input.get("Input", "Baits").split(",")
	logfile = open(input.get("General", "LogFilename"))
	
except ValueError:
	g.exit("Invalid value(s) in config!")
except NoSectionError:
	g.exit("Invalid sections in config!")
except NoOptionError:
	g.exit("Invalid options in config!")
except IOError:
	g.exit("Log can't be made!")
except:
	g.exit("Invalid config!")

def logToLogfile(logged = "\n"):
	try:
		logfile.write(logged + "\n")
	except IOError:
		g.exit("Log can't be written to!")
	else:
		print "Written " + raw(logged) + " to the log!"
	
def testReaction(xpos, ypos, sli):
	found = false
	global debug
	global maxgen
	orig = g.getcells(g.getrect())
	g.putcells(stillLifes[sli], xpos, ypos)
	this = g.getcells(g.getrect())
	oldgeneration = g.getgen()
	for i in range(maxgen):
		oldpat = g.getcells(g.getrect())
		g.step()
		if g.getcells(g.getrect()) == oldpat or g.getcells(g.getrect()) == []:
			break
		if celleq(g.getcells(g.getrect()), herschels[sli]):
			found = True
			break
	g.clear(0)
	g.clear(1)
	g.setgen(oldgeneration)
	if found:
		g.putcells(this)
		logToLogFile("Found reaction!")
	else:
		g.putcells(orig)
		logToLogFile("No result found at x:" + str(xpos) + ", y:" + str(ypos) + ", still life " + str(sli))
		

def tests():
	global found
	for n in range(testrect[2]):
		for m in range(testrect[3]):
			for o in range(len(stillLifes)):
				testReaction(n + testrect[0], m + testrect[1], o)
				if found:
					return
tests()
I just forgot to test it!!!

ME.AM.DUMB :evil: :evil: :evil: :evil: :evil: :evil: :evil: :evil: :evil:

Anyway here is a sample config file:

Code: Select all

[General]
DebugMode=true
LogFilename="hrf.log"

[Input]
Generations=500
Results=3o$2bo$3o!,3o$o$3o!,3o$obo$obo!,obo$obo$3o!,2o$2o!
Baits=2o$2o!,o$3o$3bo$2b2o!,bo$obo$obo$bo!,b2o$o2bo$b2o!,2b2o$bobo$bo$2o!
*yawn* What a nothing-to-do day! Let's be the only person in the world to do CGOL during boring times. :)

User avatar
Gustavo6046
Posts: 647
Joined: December 7th, 2013, 6:26 pm
Location: Brazil.

Re: Gustavo Ramos Rehermann's patterns

Post by Gustavo6046 » January 22nd, 2016, 6:44 pm

Working HRF v0.2:

Code: Select all

import golly as g
from sys import exit
from time import sleep
import ConfigParser as cp
import os

herschels = []
stillLifes = []

def celleq(self, other):
    ssort, osort = g.evolve(self, 0), g.evolve(other, 0)
    return g.transform(ssort,-ssort[0],-ssort[1]) == g.transform(osort,-osort[0],-osort[1])

assert celleq([0, 1, 0, 2], [0, 2, 0, 3])
	
testrect = g.getselrect();
if testrect == []:
	g.exit("Select the area where the still life is placeable!")

if g.empty():
	g.exit("There is no pattern to add bait!")

def parseRLEs(*args):
	tmp = []
	for x in args:
		tmp.append(g.parse(x))
	return tmp
	
inputconfig = g.getstring("Which file to get configuration from?", "hrf_test1.ini", "HRF v0.2")

input = cp.RawConfigParser()
if input.read(inputconfig) == []:
	g.exit("Non-existent config file!")
try:
	debug = input.getboolean("General", "DebugMode")
	maxgen = input.getint("Input", "Generations")
	herschels = parseRLEs(*input.get("Input", "Results").split(","))
	stillLifes = parseRLEs(*input.get("Input", "Baits").split(","))
	logfile = open(input.get("General", "LogFilename"), "w")
	outdir = input.get("General", "OutputDir")
	
except ValueError:
	g.exit("Invalid value(s) in config!")
except cp.NoSectionError:
	g.exit("Invalid sections in config!")
except cp.NoOptionError:
	g.exit("Invalid options in config!")

def logToLogfile(logged = "\n"):
	try:
		logfile.write(logged + "\n")
	except IOError:
		g.exit("Log can't be written to!")

results = 0
	
this = []

def ensure_dir(f):
    if not os.path.exists(f):
        os.makedirs(f)
	
ensure_dir(outdir)
	
def testReaction(xpos, ypos, sli):
	found = False
	global debug
	global maxgen
	global results
	global this
	orig = g.getcells(g.getrect())
	g.putcells(stillLifes[sli], xpos, ypos)
	this = g.getcells(g.getrect())
	oldgeneration = g.getgen()
	for i in range(maxgen):
		oldpat = g.getcells(g.getrect())
		g.step()
		if g.getcells(g.getrect()) == oldpat or g.getcells(g.getrect()) == []:
			break
		if celleq(g.getcells(g.getrect()), herschels[sli]):
			found = True
			break
	g.clear(0)
	g.clear(1)
	g.setgen(oldgeneration)
	if found:
		results += 1
		g.putcells(orig)
		logToLogfile("Found reaction!")
		output = open(outdir + "\\hrf_output" + str(results) + ".cells", "w")
		output.write(str(this))
		output.close()
	else:
		g.putcells(orig)
		logToLogfile("No result found at x:" + str(xpos) + ", y:" + str(ypos) + ", still life " + str(sli))
		

def tests():
	global found
	for n in range(testrect[2]):
		for m in range(testrect[3]):
			for o in range(len(stillLifes)):
				testReaction(n + testrect[0], m + testrect[1], o)
tests()
logfile.close()
g.clear(1)
g.clear(0)
g.putcells(this)
Also this is the new INI specification:

Code: Select all

[General]
DebugMode=<whether debug mode is on>
LogFilename=<filename of log>
OutputDir=<name of directory to save outputs to>

[Input]
Generations=<max number of generations in each test>
Results=<desired result RLEs separated by comma and no space>
Baits=<bait still life RLEs separated by comma and no space>
*yawn* What a nothing-to-do day! Let's be the only person in the world to do CGOL during boring times. :)

User avatar
Gustavo6046
Posts: 647
Joined: December 7th, 2013, 6:26 pm
Location: Brazil.

Re: Gustavo Ramos Rehermann's patterns

Post by Gustavo6046 » January 22nd, 2016, 7:09 pm

I tried inserting Nathaniel's RLE script but it gives me a "int object has no attribute '__getitem__'" error, which is omfg very freaking weird. Maybe it's for older Python versions?
*yawn* What a nothing-to-do day! Let's be the only person in the world to do CGOL during boring times. :)

User avatar
dvgrn
Moderator
Posts: 10612
Joined: May 17th, 2009, 11:00 pm
Location: Madison, WI
Contact:

Re: Gustavo Ramos Rehermann's patterns

Post by dvgrn » January 22nd, 2016, 7:42 pm

Gustavo6046 wrote:I tried inserting Nathaniel's RLE script but it gives me a "int object has no attribute '__getitem__'" error, which is omfg very freaking weird. Maybe it's for older Python versions?
No, it works fine with the latest Python. Do you mean you tried using the version of Nathaniel's script that I just re-posted? My version of the function had a few new lines of code at the beginning, which changed the function's expected input so it can handle a regular flat cell list.

Or did you go back and get Nathaniel's original script, and then try to pass it a regular flat cell list? I would imagine you might well get some mysterious error along those lines, in that case. The error is just saying:

Your code wants this data to be a list (or something with multiple pieces, anyway).
But this data that I actually have is not a list, it's just a plain old number.


I haven't tried it, but you might get something similar if you try to pass in a multistate cell list. If you want to handle that case, you need to test for it specifically, set the chunk size to 3 if necessary, throw out any state-2 blue cells, and so forth.

Or keep things simple and just do the conversion to a single-state rule before you start, using some code along the lines of ToLife.py.

User avatar
Gustavo6046
Posts: 647
Joined: December 7th, 2013, 6:26 pm
Location: Brazil.

Re: Gustavo Ramos Rehermann's patterns

Post by Gustavo6046 » January 22nd, 2016, 7:52 pm

OK, I'll use your variant them.

But I guess it's later, because I have YET ANOTHER error in my hands: (oh crap)

Code: Select all

import golly as g
from sys import exit
from time import sleep
import ConfigParser as cp
import os, shutil

herschels = []
stillLifes = []

def celleq(self, other):
    ssort, osort = g.evolve(self, 0), g.evolve(other, 0)
    return g.transform(ssort,-ssort[0],-ssort[1]) == g.transform(osort,-osort[0],-osort[1])

assert celleq([0, 1, 0, 2], [0, 2, 0, 3])
	
testrect = g.getselrect();
if testrect == []:
	g.exit("Select the area where the still life is placeable!")

if g.empty():
	g.exit("There is no pattern to add bait!")

def chunks(l, n):
    for i in range(0, len(l), n):
        yield l[i:i+n]

def giveRLE(rl_list):
   rle_res = ""
   rle_len = 1
   rl_y = rl_list[0][1] - 1
   rl_x = 0
   for rl_i in rl_list:
      if rl_i[1] == rl_y:
         if rl_i[0] == rl_x + 1:
            rle_len += 1
         else:
            if rle_len == 1: rle_strA = ""
            else: rle_strA = str (rle_len)
            if rl_i[0] - rl_x - 1 == 1: rle_strB = ""
            else: rle_strB = str (rl_i[0] - rl_x - 1)

            rle_res = rle_res + rle_strA + "o" + rle_strB + "b"
            rle_len = 1
      else:
         if rle_len == 1: rle_strA = ""
         else: rle_strA = str (rle_len)
         if rl_i[1] - rl_y == 1: rle_strB = ""
         else: rle_strB = str (rl_i[1] - rl_y)
         if rl_i[0] == 1: rle_strC = "b"
         elif rl_i[0] == 0: rle_strC = ""
         else: rle_strC = str (rl_i[0]) + "b"
         
         rle_res = rle_res + rle_strA + "o" + rle_strB + "$" + rle_strC
         rle_len = 1

      rl_x = rl_i[0]
      rl_y = rl_i[1]
   
   if rle_len == 1: rle_strA = ""
   else: rle_strA = str (rle_len)
   rle_res = rle_res[2:] + rle_strA + "o"
   
   return rle_res

	
def parseRLEs(*args):
	tmp = []
	for x in args:
		tmp.append(g.parse(x))
	return tmp
	
inputconfig = g.getstring("Which file to get configuration from?", "hrf_test1.ini", "HRF v0.2")

input = cp.RawConfigParser()
if input.read(inputconfig) == []:
	g.exit("Non-existent config file!")
try:
	debug = input.getboolean("General", "DebugMode")
	maxgen = input.getint("Input", "Generations")
	herschels = parseRLEs(*input.get("Input", "Results").split(","))
	stillLifes = parseRLEs(*input.get("Input", "Baits").split(","))
	logfile = open(input.get("General", "LogFilename"), "w")
	outdir = input.get("General", "OutputDir")
	
except ValueError:
	g.exit("Invalid value(s) in config!")
except cp.NoSectionError:
	g.exit("Invalid sections in config!")
except cp.NoOptionError:
	g.exit("Invalid options in config!")

def logToLogfile(logged = "\n"):
	try:
		logfile.write(logged + "\n")
	except IOError:
		g.exit("Log can't be written to!")

results = 0
	
this = []

def ensure_dir(f):
    if not os.path.exists(f):
        os.makedirs(f)
	
if os.path.isdir(outdir):
	shutil.rmtree(outdir)

ensure_dir(outdir)

def testReaction(xpos, ypos, sli):
	found = False
	global debug
	global maxgen
	global results
	global this
	orig = g.getcells(g.getrect())
	g.putcells(stillLifes[sli], xpos, ypos)
	this = g.getcells(g.getrect())
	oldgeneration = g.getgen()
	for i in range(maxgen):
		oldpat = g.getcells(g.getrect())
		g.step()
		if g.getcells(g.getrect()) == oldpat or g.getcells(g.getrect()) == []:
			break
		if celleq(g.getcells(g.getrect()), herschels[sli]):
			found = True
			break
	g.clear(0)
	g.clear(1)
	g.setgen(oldgeneration)
	if found:
		results += 1
		g.putcells(orig)
		logToLogfile("Found reaction!")
		output = open(outdir + "\\hrf_output" + str(results) + ".cells", "w")
		output.write(giveRLE(g.evolve(this, 0)))
		output.close()
	else:
		g.putcells(orig)
		logToLogfile("No result found at x:" + str(xpos) + ", y:" + str(ypos) + ", still life " + str(sli))
		

def tests():
	global found
	for n in range(testrect[2]):
		for m in range(testrect[3]):
			for o in range(len(stillLifes)):
				testReaction(n + testrect[0], m + testrect[1], o)
tests()
logfile.close()
g.clear(1)
g.clear(0)
g.putcells(this)
Yes, that's quite a bit of code. It will most probably be hard to debug. :|

The error is "list index out of range" at line 126.

Sometimes it will give some "Access Negated" errors but nothing that worries. I wonder how to ignore a exception...
*yawn* What a nothing-to-do day! Let's be the only person in the world to do CGOL during boring times. :)

User avatar
Scorbie
Posts: 1692
Joined: December 7th, 2013, 1:05 am

Re: Gustavo Ramos Rehermann's patterns

Post by Scorbie » January 22nd, 2016, 8:24 pm

I can see that your python is improving every version. This seems to be good practice for you.
Gustavo6046 wrote:The error is "list index out of range" at line 126.
Line 126 is a call to the function "celleq", and for that line to raise an error, the function body of celleq may be a problem?

I would recommend posting the whole error message (unless it's too long) so that people would have a better idea of the problem.

Anyway, as there are no more information available, I would have to assume that the error was raised inside the "celleq" function body. For that to raise an IndexError, line 12:

Code: Select all

    return g.transform(ssort,-ssort[0],-ssort[1]) == g.transform(osort,-osort[0],-osort[1])
should be a problem when osort or ssort has less than 2 items. (Which would be when osort or ssort is an empty cell list.)

@Gustavo You **did** fix that prior bug before you added functionality, right? Extending a not-working program seems to be a little nonsense, and would create a bigger not-working program instead of a small but working one.

@dvgrn By the way, does g.evolve(clist, 0) sort all the coordinates?
EDIT: Thanks for the explanation. (it's in page 38)
Last edited by Scorbie on January 23rd, 2016, 4:10 am, edited 1 time in total.

User avatar
Gustavo6046
Posts: 647
Joined: December 7th, 2013, 6:26 pm
Location: Brazil.

Re: Gustavo Ramos Rehermann's patterns

Post by Gustavo6046 » January 22nd, 2016, 9:13 pm

Thanks! Just fixed it.

It works fine for a few cycles, then crashes because of a line 141 IndexError:

Code: Select all

import golly as g
from sys import exit
from time import sleep
import ConfigParser as cp
import os, glob

herschels = []
stillLifes = []

def celleq(self, other):
	if self != [] or other != []:
		ssort, osort = g.evolve(self, 0), g.evolve(other, 0)
		return g.transform(ssort,-ssort[0],-ssort[1]) == g.transform(osort,-osort[0],-osort[1])
	elif self == other:
		return true
	else:
		return false

assert celleq([0, 1, 0, 2], [0, 2, 0, 3])
	
testrect = g.getselrect();
if testrect == []:
	g.exit("Select the area where the still life is placeable!")

if g.empty():
	g.exit("There is no pattern to add bait!")

def chunks(l, n):
    for i in range(0, len(l), n):
        yield l[i:i+n]
	
def parseRLEs(*args):
	tmp = []
	for x in args:
		tmp.append(g.parse(x))
	return tmp
	
def chunks(l, n):
    for i in range(0, len(l), n):
        yield l[i:i+n]

def giveRLE(clist):
   clist_chunks = list (chunks (clist, 2))
   mcc = min(clist_chunks)
   rl_list = [[x[0]-mcc[0],x[1]-mcc[1]] for x in clist_chunks]
   rle_res = ""
   rle_len = 1
   rl_y = rl_list[0][1] - 1
   rl_x = 0
   for rl_i in rl_list:
      if rl_i[1] == rl_y:
         if rl_i[0] == rl_x + 1:
            rle_len += 1
         else:
            if rle_len == 1: rle_strA = ""
            else: rle_strA = str (rle_len)
            if rl_i[0] - rl_x - 1 == 1: rle_strB = ""
            else: rle_strB = str (rl_i[0] - rl_x - 1)

            rle_res = rle_res + rle_strA + "o" + rle_strB + "b"
            rle_len = 1
      else:
         if rle_len == 1: rle_strA = ""
         else: rle_strA = str (rle_len)
         if rl_i[1] - rl_y == 1: rle_strB = ""
         else: rle_strB = str (rl_i[1] - rl_y)
         if rl_i[0] == 1: rle_strC = "b"
         elif rl_i[0] == 0: rle_strC = ""
         else: rle_strC = str (rl_i[0]) + "b"
         
         rle_res = rle_res + rle_strA + "o" + rle_strB + "$" + rle_strC
         rle_len = 1

      rl_x = rl_i[0]
      rl_y = rl_i[1]
   
   if rle_len == 1: rle_strA = ""
   else: rle_strA = str (rle_len)
   rle_res = rle_res[2:] + rle_strA + "o"
   
   return rle_res+"!"
	
inputconfig = g.getstring("Which file to get configuration from?", "hrf_test1.ini", "HRF v0.2")

input = cp.RawConfigParser()
if input.read(inputconfig) == []:
	g.exit("Non-existent config file!")
try:
	debug = input.getboolean("General", "DebugMode")
	maxgen = input.getint("Input", "Generations")
	herschels = parseRLEs(*input.get("Input", "Results").split(","))
	stillLifes = parseRLEs(*input.get("Input", "Baits").split(","))
	logfile = open(input.get("General", "LogFilename"), "w")
	outdir = input.get("General", "OutputDir")
	
except ValueError:
	g.exit("Invalid value(s) in config!")
except cp.NoSectionError:
	g.exit("Invalid sections in config!")
except cp.NoOptionError:
	g.exit("Invalid options in config!")

def logToLogfile(logged = "\n"):
	try:
		logfile.write(logged + "\n")
	except IOError:
		g.exit("Log can't be written to!")

results = 0
	
this = []

def ensure_dir(f):
    if not os.path.exists(f):
        os.makedirs(f)
	os.chmod(f)
	
def remove_folder_content(f):
	filelist = glob.glob(f + "\\*.*")
	for x in filelist:
		os.remove(x)
	
remove_folder_content(outdir)
ensure_dir(outdir)
	
def testReaction(xpos, ypos, sli):
	found = False
	global debug
	global maxgen
	global results
	global this
	orig = g.getcells(g.getrect())
	g.putcells(stillLifes[sli], xpos, ypos)
	this = g.getcells(g.getrect())
	oldgeneration = g.getgen()
	for i in range(maxgen):
		oldpat = g.getcells(g.getrect())
		g.step()
		if g.getcells(g.getrect()) == oldpat or g.getcells(g.getrect()) == []:
			break
		if celleq(g.getcells(g.getrect()), herschels[sli]):
			found = True
			break
	g.clear(0)
	g.clear(1)
	g.setgen(oldgeneration)
	if found:
		results += 1
		g.putcells(orig)
		logToLogfile("Found reaction!")
		output = open(outdir + "\\hrf_output" + str(results) + ".cells", "w")
		output.write(giveRLE(g.evolve(this, 0)))
		output.close()
	else:
		g.putcells(orig)
		logToLogfile("No result found at x:" + str(xpos) + ", y:" + str(ypos) + ", still life " + str(sli))
		

def tests():
	global found
	for n in range(testrect[2]):
		for m in range(testrect[3]):
			for o in range(len(stillLifes)):
				testReaction(n + testrect[0], m + testrect[1], o)
tests()
logfile.close()
g.clear(1)
g.clear(0)
g.putcells(this)
*yawn* What a nothing-to-do day! Let's be the only person in the world to do CGOL during boring times. :)

User avatar
Scorbie
Posts: 1692
Joined: December 7th, 2013, 1:05 am

Re: Gustavo Ramos Rehermann's patterns

Post by Scorbie » January 22nd, 2016, 10:10 pm

Gustavo6046 wrote:It works fine for a few cycles, then crashes because of a line 141 IndexError:
Hmm, it's the same function call again and I'm not sure what's the problem... Good luck. Crashes leave stack traces, so I guess that would be easier to fix than subtle bugs.
Anyway, as I said before,
I would recommend posting the whole error message (unless it's too long) so that people would have a better idea of the problem.
If a Golly python script crashes, I think it gives the um... call trace(?) with a popup window. Copy that message and paste it here next time.

Post Reply