Golly scripts

For scripts to aid with computation or simulation in cellular automata.
User avatar
12Glider
Posts: 79
Joined: December 17th, 2010, 4:56 pm

Re: Golly scripts

Post by 12Glider » March 8th, 2011, 6:34 pm

Would anyone modify the ssstream script to work in Golly 2.2? I would be very thankful.
Image

Why hasn't a glider exploded yet?

User avatar
Andrew
Moderator
Posts: 771
Joined: June 2nd, 2009, 2:08 am
Location: Melbourne, Australia
Contact:

Re: Golly scripts

Post by Andrew » March 8th, 2011, 7:02 pm

12Glider wrote:Would anyone modify the ssstream script to work in Golly 2.2? I would be very thankful.
This should work:

Code: Select all

# Golly python script. 
# Written by PM 2Ring, April 2009

''' Create a spaceship stream of any period.

The pattern is built from the current selection, which is assumed to be a spaceship. 
'''

from glife import * 
import golly
  
class ArgError(Exception): pass  

def getargs():
  ''' Get input data '''
  
  prompt = 'Enter period and number of spaceships'
  usage = 'Create a stream of the selected spaceship.\n' + prompt + ', separated by spaces.'
  
  #Loop until we get correct args, or are aborted by ESC    
  while True: 
    try: 
      args = golly.getstring(prompt + ':').split()
      if args == []:
        raise ArgError
      
      if len(args) < 2: 
        raise ArgError, 'Not enough data.'
      
      #Check that args are valid integers
      for s in args:  
        if not validint(s): 
          raise ArgError, '[%s] is not a valid integer.' % s      

      #Convert arguments to integer
      args = [int(s) for s in args]           
      for i in args:
        if i<=0:
          raise ArgError, 'Data must be > 0, not %d!' % i
        
    except ArgError, s:
      g.warn('%s\n\n%s' % (s, usage))  
    else:    
      break  
  return args  
    
def main():
  selrect = golly.getselrect()
  if len(selrect) == 0: golly.exit("No selection")
  ss = pattern(golly.getcells(selrect))

  #Get input data 
  period, num = getargs()  

  all = pattern()  
  for i in xrange(1, num):
    all += ss[i * period]
  all.put()
    
main()

137ben
Posts: 343
Joined: June 18th, 2010, 8:18 pm

Re: Golly scripts

Post by 137ben » March 8th, 2011, 8:58 pm

Andrew wrote:
12Glider wrote:Would anyone modify the ssstream script to work in Golly 2.2? I would be very thankful.
This should work:

Code: Select all

# Golly python script. 
# Written by PM 2Ring, April 2009

''' Create a spaceship stream of any period.

The pattern is built from the current selection, which is assumed to be a spaceship. 
'''

from glife import * 
import golly
  
class ArgError(Exception): pass  

def getargs():
  ''' Get input data '''
  
  prompt = 'Enter period and number of spaceships'
  usage = 'Create a stream of the selected spaceship.\n' + prompt + ', separated by spaces.'
  
  #Loop until we get correct args, or are aborted by ESC    
  while True: 
    try: 
      args = golly.getstring(prompt + ':').split()
      if args == []:
        raise ArgError
      
      if len(args) < 2: 
        raise ArgError, 'Not enough data.'
      
      #Check that args are valid integers
      for s in args:  
        if not validint(s): 
          raise ArgError, '[%s] is not a valid integer.' % s      

      #Convert arguments to integer
      args = [int(s) for s in args]           
      for i in args:
        if i<=0:
          raise ArgError, 'Data must be > 0, not %d!' % i
        
    except ArgError, s:
      g.warn('%s\n\n%s' % (s, usage))  
    else:    
      break  
  return args  
    
def main():
  selrect = golly.getselrect()
  if len(selrect) == 0: golly.exit("No selection")
  ss = pattern(golly.getcells(selrect))

  #Get input data 
  period, num = getargs()  

  all = pattern()  
  for i in xrange(1, num):
    all += ss[i * period]
  all.put()
    
main()
It doesn't work for me with python 2.5.4...which version of python should I use with the ssship script?

flipper77
Posts: 197
Joined: October 24th, 2010, 3:25 am
Location: Spokane, WA

Re: Golly scripts

Post by flipper77 » March 8th, 2011, 9:35 pm

When I use ssstream.py, it seems that python 2.7 works when using the script, but it's probably not the only version that can work for this script

User avatar
Andrew
Moderator
Posts: 771
Joined: June 2nd, 2009, 2:08 am
Location: Melbourne, Australia
Contact:

Re: Golly scripts

Post by Andrew » March 8th, 2011, 11:17 pm

137ben wrote:It doesn't work for me with python 2.5.4.
That doesn't tell me much -- what error message do you get? I've tested the script with 2.3 and 2.7 without any problems. I can't see anything in the script that would prevent it working with your python.

137ben
Posts: 343
Joined: June 18th, 2010, 8:18 pm

Re: Golly scripts

Post by 137ben » March 9th, 2011, 9:48 am

It is telling me "NameError: global name 'g' is not defined"

User avatar
Andrew
Moderator
Posts: 771
Joined: June 2nd, 2009, 2:08 am
Location: Melbourne, Australia
Contact:

Re: Golly scripts

Post by Andrew » March 9th, 2011, 6:10 pm

137ben wrote:It is telling me "NameError: global name 'g' is not defined"
Useful clue. There was a line calling "g.warn" rather than "golly.warn" so I've fixed that in the code below. (I guess it didn't cause any problems for me because I must have already run another script that did an "import golly as g".)

Code: Select all

# Golly python script. 
# Written by PM 2Ring, April 2009

# Create a spaceship stream of any period.
# The pattern is built from the current selection, which is assumed to be a spaceship. 

import golly
from glife import validint, pattern
  
class ArgError(Exception): pass

def getargs():
  ''' Get input data '''
  
  prompt = 'Enter period and number of spaceships'
  usage = 'Create a stream of the selected spaceship.\n' + prompt + ', separated by spaces.'
  
  #Loop until we get correct args, or are aborted by ESC    
  while True: 
    try: 
      args = golly.getstring(prompt + ':').split()
      if args == []:
        raise ArgError
      
      if len(args) < 2: 
        raise ArgError, 'Not enough data.'
      
      #Check that args are valid integers
      for s in args:  
        if not validint(s): 
          raise ArgError, '[%s] is not a valid integer.' % s      

      #Convert arguments to integer
      args = [int(s) for s in args]           
      for i in args:
        if i<=0:
          raise ArgError, 'Data must be > 0, not %d!' % i
        
    except ArgError, s:
      golly.warn('%s\n\n%s' % (s, usage))  
    else:    
      break  
  return args  
    
def main():
  selrect = golly.getselrect()
  if len(selrect) == 0: golly.exit("No selection")
  ss = pattern(golly.getcells(selrect))

  #Get input data 
  period, num = getargs()  

  all = pattern()  
  for i in xrange(1, num):
    all += ss[i * period]
  all.put()
    
main()

137ben
Posts: 343
Joined: June 18th, 2010, 8:18 pm

Re: Golly scripts

Post by 137ben » March 9th, 2011, 10:07 pm

Thanks, it's working now.

flipper77
Posts: 197
Joined: October 24th, 2010, 3:25 am
Location: Spokane, WA

Re: Golly scripts

Post by flipper77 » March 20th, 2011, 5:38 pm

Can somebody make a script that, like the move-object.py script, move an object on a torus because when I use it on a torus where an object is on an edge, it only grabs that portion of the object.

User avatar
Extrementhusiast
Posts: 1832
Joined: June 16th, 2009, 11:24 pm
Location: USA

Re: Golly scripts

Post by Extrementhusiast » March 21st, 2011, 10:12 am

Well, if the pattern is a small one without large gaps, you could always paste the left part by hand, and then paste the right part to the left of the left part in the corresponding position. (Just make sure that it works correctly. This method also works for objects spanning top and bottom, as well as objects straddling the corner, but that case takes longer.)

Or, if the torus is a small one, just copy the whole thing and then paste it several times next to another copy. (This would be in an infinite planar universe, a.k.a. the standard one.)
I Like My Heisenburps! (and others)

User avatar
12Glider
Posts: 79
Joined: December 17th, 2010, 4:56 pm

Re: Golly scripts

Post by 12Glider » March 21st, 2011, 4:30 pm

Can someone update and/or fix the LWSS & MWSS gun maker script for me? I would be very thankful. :D
Image

Why hasn't a glider exploded yet?

User avatar
Andrew
Moderator
Posts: 771
Joined: June 2nd, 2009, 2:08 am
Location: Melbourne, Australia
Contact:

Re: Golly scripts

Post by Andrew » October 23rd, 2011, 8:45 pm

I've added three new scripts to the Golly Scripts Database:

benchmark.py -- Does a simple timing test using the current algorithm + rule + pattern.

hexrot.py -- Rotates a hexagonal neighborhood pattern by 60 degrees clockwise. Here's a glider in a hexagonal rule for testing the script:

Code: Select all

x = 7, y = 6, rule = B245/S3H
obo$4bo$2bo$bo2bobo$3bo$5bo!
save-bmp.py -- Saves the current selection/pattern as a .bmp file. Unlike save-image.py this script does not require PIL (Python Imaging Library).

flipper77
Posts: 197
Joined: October 24th, 2010, 3:25 am
Location: Spokane, WA

Re: Golly scripts

Post by flipper77 » October 30th, 2011, 6:43 pm

Andrew wrote: hexrot.py -- Rotates a hexagonal neighborhood pattern by 60 degrees clockwise. Here's a glider in a hexagonal rule for testing the script:
Could someone change the script so it works for selections?

137ben
Posts: 343
Joined: June 18th, 2010, 8:18 pm

Re: Golly scripts

Post by 137ben » November 12th, 2011, 4:49 pm

Something I think would be useful is a script to count how many of each color cell there is, rather than just the total number of live cells.

User avatar
Andrew
Moderator
Posts: 771
Joined: June 2nd, 2009, 2:08 am
Location: Melbourne, Australia
Contact:

Re: Golly scripts

Post by Andrew » November 12th, 2011, 6:10 pm

Something I think would be useful is a script to count how many of each color cell there is, rather than just the total number of live cells.
See histogram.py in the Golly Scripts Database.

edwardfanboy
Posts: 80
Joined: September 16th, 2011, 10:29 pm

VonNeumann to Moore

Post by edwardfanboy » December 2nd, 2011, 7:31 pm

I have no experience writing scripts, but I have figured out a way to turn Von Neumann neighbourhood ruletables into Moore neighbourhood ruletables. I may need this script for a project I am working on. Namely "Arrows WW".
Last edited by edwardfanboy on December 9th, 2011, 7:35 am, edited 1 time in total.

User avatar
Wojowu
Posts: 210
Joined: October 1st, 2011, 1:24 pm

Re: VonNeumann to Moore

Post by Wojowu » December 4th, 2011, 8:13 am

edwardfanboy wrote:I have no experience writing scripts, but I have figured out a way to turn Von Neumann neighbourhood ruletables into Moore neighbourhood ruletables. I may need this script for a project I am working on.
It would be nice if it could also change 1-D and hexagonal neighbourhoods :D
First question ever. Often referred to as The Question. When this question is asked in right place in right time, no one can lie. No one can abstain. But when The Question is asked, silence will fall. Silence must fall. The Question is: Doctor Who?

edwardfanboy
Posts: 80
Joined: September 16th, 2011, 10:29 pm

LifeHistory to Life

Post by edwardfanboy » January 24th, 2012, 10:39 pm

I wrote this script to convert LifeHistory to Life. Those pesky state 2 cells almost always get in the way!

Code: Select all

# Change the selected area from N states to Life states:
# s -> 1+2s (if in the top-left of the partition)
# s -> 2+2s (if not)

from glife import rect
import golly as g

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

for row in xrange(r.top, r.top + r.height):
   for col in xrange(r.left, r.left + r.width):
         g.setcell(col, row, g.getcell(col,row)%2)
When I run it, it gives me this:

Traceback (most recent call last):
File "<string>", line 1, in <module>
File "C:\Users\a\Desktop\golly-2.2-win\Patterns\_Scripts\Python\lifehistory.py", line 5, in <module>
from glife import rect
ImportError: No module named glife
I moved my Scripts into my Patterns folder (along with the glife folder).

User avatar
simsim314
Posts: 1766
Joined: February 10th, 2014, 1:27 pm

Re: Golly scripts

Post by simsim314 » April 19th, 2014, 6:10 pm

A small script that counts the objects (object is connected pattern, like glider, block etc.). Made mainly for still life object count.

Code: Select all

import golly as g
from copy import copy

def FindActive():

	rect = g.getrect()
	
	for i in xrange(rect[0], rect[0] + rect[2] + 1): 
		if g.getcell(i, rect[1]) > 0:
			return (i, rect[1])
			
def FindConnected(listXY):
	result = copy(listXY)
	
	for xy in listXY:
		x = xy[0]
		y = xy[1]
		
		for i in xrange(-1, 2): 
			for j in xrange(-1, 2): 
				if g.getcell(x + i, y + j) > 0 and len([i for t in listXY if (t[0] == x + i and t[1] == y + j)]) == 0:
					result.append((x + i, y + j))
			
	return result
	
def RemoveList(listXY):

	for xy in listXY:
		x = xy[0]
		y = xy[1]
		g.setcell(x, y, 0)

total = 0 
g.run(1)

while int(g.getpop()) > 0: 
	xy = [FindActive()]
	
	while True: 
		newXY = FindConnected(xy)
		
		#g.getstring(str(xy) + " : " + str(newXY) )
		
		if len(newXY) == len(xy):
			break
			
		xy = newXY
	
	RemoveList(xy)
	
	g.show(str(total))
	g.update()
	total += 1

g.show("The total Objects cound is: " + str(total))
g.reset()

User avatar
simsim314
Posts: 1766
Joined: February 10th, 2014, 1:27 pm

Re: Golly scripts

Post by simsim314 » April 22nd, 2014, 6:23 am

While on it, here is a much faster LifeHistory->Life converter, that creates a new document and set it to Life rule.

Code: Select all

# Change the LifeHistory N states to Life states and set the rule to Life
# s -> 1+2s (if in the top-left of the partition)
# s -> 2+2s (if not)

import golly as g

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

g.new("")
g.setrule("B3/S23")

i = 0 

while i + 2 < len(cells):
	
	x = cells[i]
	y = cells[i + 1]
	val = cells[i + 2]
	
	if val % 2 == 1: 
		g.setcell(x, y, 1)
		
	i+=3
And here is one that does it in LifeHistory, so the undo operation is available.

Code: Select all

# Change the LifeHistory N states to Life states and stay in LifeHistory
# s -> 1+2s (if in the top-left of the partition)
# s -> 2+2s (if not)

import golly as g

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

g.select(g.getrect())
g.clear(0)

i = 0 

while i + 2 < len(cells):
	
	x = cells[i]
	y = cells[i + 1]
	val = cells[i + 2]
	
	if val % 2 == 1: 
		g.setcell(x, y, 1)
		
	i+=3

g.select([])

User avatar
simsim314
Posts: 1766
Joined: February 10th, 2014, 1:27 pm

Re: Golly scripts

Post by simsim314 » April 24th, 2014, 5:29 am

Here is a smart paste script. It creates a new document, and sets the rule to the rule in clipboard and places the pattern in (x,y) written in rle. Very useful for paste in threads with multiple CA rules.

Code: Select all

#Smart past -> sets the rule of golly to the one in clipboard and paste it in the location of the x,y in the rle format 
import golly as g 

g.new("")
s = g.getclipstr()

s = s.split()

while len(s) > 0 and not s[0].startswith("x"):
	s.pop(0)

if len(s) < 10:
	g.exit("wrong length" + ":" + str(len(s))+ ":" + str((s)))

if s[0] == 'x' and s[1] == "=": 
	x = int(s[2].split(",")[0])
else: 
	g.exit("no pattern selected there is no x")
	
if s[3] == 'y' and s[4] == "=": 
	y = int(s[5].split(",")[0])
else: 
	g.exit("no pattern selected there is no y")

if s[6] == 'rule' and s[7] == "=": 
	rule = s[8]
	
	pat = ""
	for i in xrange(9,len(s)):
		pat += s[i]
else: 
	g.exit("no pattern selected there is no rule or pattern")

cells = g.parse(pat)
g.setrule(rule)
g.putcells(cells, x, y)
g.fit()

c0b0p0
Posts: 645
Joined: February 26th, 2014, 4:48 pm

Re: Golly scripts

Post by c0b0p0 » April 26th, 2014, 7:22 pm

For pattern engineers in hexagonal rules, hexagonal rotation can take several minutes. To rectify this problem, here is a hyperfast version of hexrot.py, working with cell lists instead of sets of rings.

Code: Select all

# Rotate selection in hexagonal neighborhood by 60 degrees,
#   with rotated pattern placed in new layer.  

import golly as g  
if g.empty(): g.exit("There is no pattern.")
rect = g.getselrect()  
if len(rect) == 0: g.exit("There is no selection.")
x = rect[0]  
y = rect[1]   
clL=g.getcells(rect)
lngth = len(clL)
nl = g.addlayer()
indx=0
incr=2
if lngth % 2 == 1: incr = 3
st = 1
while indx < lngth:
  i=clL[indx]
  j=clL[indx+1]
  if incr == 3: st = clL[indx+2]
  g.setcell(x+j,y-i+j,st)  # (x-j,y+i+j) before inverting y values
  indx = indx + incr

c0b0p0
Posts: 645
Joined: February 26th, 2014, 4:48 pm

Re: Golly scripts

Post by c0b0p0 » May 2nd, 2014, 6:32 pm

Here is the updated version (the previous version of the script put the rotated pattern outside the viewpoint) of the fast hexagonal rotation script.

Code: Select all

# Rotate selection in hexagonal neighborhood by 60 degrees,
#   with rotated pattern placed in new layer.  

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


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

#x = rect[0]  y = rect[1]   
wd = rect[2]   
ht = rect[3]
clL=g.getcells(rect)
lngth = len(clL)
if lngth == 0: g.exit("You selected nothing.")
nl = g.addlayer()

indx=0
if lngth % 2 == 1: 
  lngth = lngth - 1
  while indx < lngth:
    i=clL[indx]
    j=clL[indx+1]
    #g.setcell(i,j,clL[indx+2])
    g.setcell(j,-i+j,clL[indx+2])  # (-j,i+j) before inverting y value
    indx = indx + 3
else:
  while indx < lngth:
    i=clL[indx]
    j=clL[indx+1]
    g.setcell(j,-i+j,1)  # (-j,i+j) before inverting y value
    indx = indx + 2

g.setpos(`j`, `-i+j`) 

User avatar
codeholic
Moderator
Posts: 1142
Joined: September 13th, 2011, 8:23 am
Location: Hamburg, Germany

Re: Golly scripts

Post by codeholic » June 8th, 2014, 6:55 pm

Is there an easy way to rotate clockwise/counterclockwise a cell array?
Ivan Fomichev

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

Re: Golly scripts

Post by dvgrn » June 8th, 2014, 8:39 pm

codeholic wrote:Is there an easy way to rotate clockwise/counterclockwise a cell array?
In a regular square neighborhood rule, not hexagonal?

putcells(), transform(), and parse() all have optional transform parameters. Sample usage -- draw something in a new universe between (0,0) and (99,99) before you run it:

Code: Select all

import golly as g
all=g.getcells(g.getrect())
g.putcells(all,100,0,0,-1,1,0) # clockwise turn
g.putcells(all,0,100,0,1,-1,0)  # counterclockwise
g.putcells(all,100,100,-1,0,0,-1) # 180 degrees
g.fit()
But maybe golly.transform() is a better answer, if you want to put a cell array in and get a cell array out. (?)

Post Reply