ConwayLife.com - A community for Conway's Game of Life and related cellular automata
Home  •  LifeWiki  •  Forums  •  Download Golly

Script request thread

For scripts to aid with computation or simulation in cellular automata.

Re: Script request thread

Postby gameoflifemaniac » December 8th, 2018, 5:02 am

Can I have a script that finds the phase with the lowest population of an oscillator or spaceship?
https://www.youtube.com/watch?v=q6EoRBvdVPQ
One big dirty Oro. Yeeeeeeeeee...
User avatar
gameoflifemaniac
 
Posts: 721
Joined: January 22nd, 2017, 11:17 am
Location: There too

Re: Script request thread

Postby Naszvadi » December 8th, 2018, 4:14 pm

gameoflifemaniac wrote:Can I have a script that finds the phase with the lowest population of an oscillator or spaceship?


I'd say hold my beer if I had more spare time.
Naszvadi
 
Posts: 303
Joined: May 7th, 2016, 8:53 am

Re: Script request thread

Postby creeperman7002 » December 8th, 2018, 10:51 pm

I would like a script that would generate worm rule tables, so I can play with the ones not included in Golly.
creeperman7002
 
Posts: 10
Joined: December 4th, 2018, 11:52 pm

Re: Script request thread

Postby dvgrn » December 9th, 2018, 11:11 am

gameoflifemaniac wrote:Can I have a script that finds the phase with the lowest population of an oscillator or spaceship?

Drat, now I've spent longer looking for one of the last three times I've written this, than it would have taken me to write it from scratch. Time for rewrite number 4, I guess:

# getminpop.py
import golly as g

maxticks = g.getstring ("Enter maximum number of ticks to search: ", "1024")
count, minT, minpop = 0, 0, int(g.getpop())
while count<=int(maxticks):
  g.run(1)
  count+=1
  newpop = int(g.getpop())
  if newpop<minpop:
    minpop = newpop
    minT = count
  if count%256==0:
   g.show("T: " + str(count) + "    Current pop: "+str(newpop)+"    Current minimum pop: " + str(minpop) + " at T = " + str(minT))
   g.fit()
   g.update()
g.note("Finished scan of " + maxticks + " ticks.  Minimum population: " +str(minpop) + " at T = " + str(minT))

It may not be the fastest way of getting a minimum population, but it will get there eventually -- maybe with an all-day or overnight run for extreme cases like a Gemini spaceship or chris_c's new camelship. I'm running the camelship minpop now as a test -- 240422 cells minimum so far.

EDIT: Turned out to be 239822 cells. If the minimum bounding box is also needed, here's an even slower script that collects that statistic as well:

# getminpopandminbb.py
import golly as g

maxticks = g.getstring ("Enter maximum number of ticks to search: ", "1024")
r = g.getrect()
count, minT, minpop, minbbx, minbby, minbbt = 0, 0, int(g.getpop()), r[2], r[3], 0
while count<=int(maxticks):
  g.run(1)
  count+=1
  newpop = int(g.getpop())
  if newpop<minpop:
    minpop = newpop
    minT = count
  r = g.getrect()
  if r[2]*r[3]<minbbx*minbby:
    minbbx, minbby, minbbt = r[2], r[3], count
  if count%256==0:
   g.show("T: " + str(count) + "    Current pop: "+str(newpop)+"    Current minimum pop: " + str(minpop) + " at T = " + str(minT) + ". Min box = "+str([minbbx, minbby]) + " at T = " + str(minbbt))
   g.fit()
   g.update()
g.note("Finished scan of " + maxticks + " ticks.  Minimum population: " +str(minpop) + " at T = " + str(minT) + ". Min box = "+str([minbbx, minbby]) + " at T = " + str(minbbt))
User avatar
dvgrn
Moderator
 
Posts: 5340
Joined: May 17th, 2009, 11:00 pm
Location: Madison, WI

Re: Script request thread

Postby gameoflifemaniac » December 14th, 2018, 11:26 am

How to fix this?
# diehard.py
# Finds diehards. When it finds a diehard with a larger lifespan than the previous one, it lists it in a different layer.
local g = golly()
local gp = require "gplus"
local selection = g.getselrect()
if #selection == 0 then
   g.exit("There is no selection.")
end
largest lifespan found so far = 0
g.addlayer()
g.setlayer(0)
while ( true ) do
   g.new("")
   g.select(selection)
   g.randfill(37)
   g.run(10000)
   if tonumber(g.getpop()) == 0 then
      g.reset()
      count = 0
      while ( true ) do
         g.run(1)
         count = count+1
         if tonumber(g.getpop()) == 0 then
            if (count > largest lifespan found so far) then
               largest lifespan found so far == count
            g.show("Found "..largest lifespan found so far.."-generation diehard")
            g.reset()
            g.setlayer(1)
            g.dellayer()
            g.setlayer(0)
            g.duplicate()
            g.exit()
            break
         end
      end
   end
end
https://www.youtube.com/watch?v=q6EoRBvdVPQ
One big dirty Oro. Yeeeeeeeeee...
User avatar
gameoflifemaniac
 
Posts: 721
Joined: January 22nd, 2017, 11:17 am
Location: There too

Re: Script request thread

Postby dvgrn » December 14th, 2018, 11:44 am

gameoflifemaniac wrote:How to fix this?...

It's almost all right, just a few syntax hiccups. Let's see...

1) comments start with --, not #, in Lua
2) variables in almost any language can't have spaces in them, so "largest life span found so far" is definitely a non-starter.
3) you used the comparison operator, ==, in one place where you meant to use the assignment operator, =.
4) right after that, there was a missing "end" after the innermost "if" statement.
5) ... might as well take out the g.exit() so the script keeps working and finding more diehards.

After that it seems to work pretty well! I added a line to name each record-breaking layer, but that isn't really necessary.

-- diehard.py
-- Finds diehards. When it finds a diehard with a larger lifespan than the previous one, it lists it in a different layer.
local g = golly()
local gp = require "gplus"
local selection = g.getselrect()
if #selection == 0 then
   g.exit("There is no selection.")
end
largestlifespanfoundsofar = 0
g.addlayer()
g.setlayer(0)
while ( true ) do
   g.new("")
   g.select(selection)
   g.randfill(37)
   g.run(10000)
   if tonumber(g.getpop()) == 0 then
      g.reset()
      count = 0
      while ( true ) do
         g.run(1)
         count = count+1
         if tonumber(g.getpop()) == 0 then
            if (count > largestlifespanfoundsofar) then
               largestlifespanfoundsofar = count
            end
            g.show("Found "..largestlifespanfoundsofar.."-generation diehard")
            g.reset()
            g.setlayer(1)
            g.dellayer()
            g.setlayer(0)
            g.duplicate()
            g.setname(largestlifespanfoundsofar.."-generation diehard")
            g.update()
            break
         end
      end
   end
end
User avatar
dvgrn
Moderator
 
Posts: 5340
Joined: May 17th, 2009, 11:00 pm
Location: Madison, WI

Re: Script request thread

Postby gameoflifemaniac » December 15th, 2018, 3:22 am

Could it be faster? And why after stopping the script it doesn't store the newest output?
https://www.youtube.com/watch?v=q6EoRBvdVPQ
One big dirty Oro. Yeeeeeeeeee...
User avatar
gameoflifemaniac
 
Posts: 721
Joined: January 22nd, 2017, 11:17 am
Location: There too

Re: Script request thread

Postby dvgrn » December 15th, 2018, 9:00 am

gameoflifemaniac wrote:Could it be faster?

One improvement to look at might be to compare speeds using QuickLife vs. HashLife, and include that setting in the script. Maybe use a number that's a power of 8 for the test step size if HashLife turns out to be faster. But it will probably depend on the rule you're testing, so maybe it's not worth worrying about.

gameoflifemaniac wrote:And why after stopping the script it doesn't store the newest output?

Oh, I didn't notice that the save-latest logic wasn't quite right. You can figure that out. Look at the last few lines. g.duplicate() automatically sets the copied layer to be the new layer... so after the first iteration, all the simulation work is actually being done in layer 1, and you're probably just saving a copy of the first soup in layer 0.
User avatar
dvgrn
Moderator
 
Posts: 5340
Joined: May 17th, 2009, 11:00 pm
Location: Madison, WI

Re: Script request thread

Postby gameoflifemaniac » December 15th, 2018, 10:34 am

dvgrn wrote:
gameoflifemaniac wrote:Could it be faster?

One improvement to look at might be to compare speeds using QuickLife vs. HashLife, and include that setting in the script. Maybe use a number that's a power of 8 for the test step size if HashLife turns out to be faster. But it will probably depend on the rule you're testing, so maybe it's not worth worrying about.

gameoflifemaniac wrote:And why after stopping the script it doesn't store the newest output?

Oh, I didn't notice that the save-latest logic wasn't quite right. You can figure that out. Look at the last few lines. g.duplicate() automatically sets the copied layer to be the new layer... so after the first iteration, all the simulation work is actually being done in layer 1, and you're probably just saving a copy of the first soup in layer 0.

I did those things, but this is supposed to be a 142-generation diehard?
x = 121, y = 39, rule = B3/S23
2ob7ob2o$2ob5ob8o2b4ob2ob5obob7ob4obob6ob8ob4ob3ob8ob3o2b2ob5ob2ob2obo
b9ob5o$5obobob7o$5ob2obob7ob7o$5ob9obobob12o$2ob10ob2obob4o$3bob11ob2o
b2ob9ob2o$3o$25obobo$ob11o$ob11o$5obob4obob2o$3bob7o$3bob17o$3bob12o$
3bob10o$3b2ob10ob9ob2obob4o$6bob7o$6b5obobo$6b5obob4obob2o$9bob6o$9b5o
bob7o$9b2ob10ob9ob2obob4o$12b2ob6obob26ob4o$15b25obob5o$12b3o$12bob11o
bo2b25o2b12ob9o$12bob7o$12bob11o$12bob8o$12bob7o2bo2b5o$12bob33o2b12ob
9o$12bob11o$12bob8o$12b5o$9b3o$6b3o$3b3o$3o!
https://www.youtube.com/watch?v=q6EoRBvdVPQ
One big dirty Oro. Yeeeeeeeeee...
User avatar
gameoflifemaniac
 
Posts: 721
Joined: January 22nd, 2017, 11:17 am
Location: There too

Re: Script request thread

Postby dvgrn » December 15th, 2018, 10:38 am

gameoflifemaniac wrote:I did those things, but this is supposed to be a 142-generation diehard?

No, that's a copy of your latest code interpreted as RLE -- a little difficult for me to find any further bugs in.

Looks like I added back the missing "end" statement in the wrong place, though, after the check for a new record. This should work better:

-- diehardv2.py
-- Finds diehards. When it finds a diehard with a larger lifespan than the previous one, it lists it in a different layer.
local g = golly()
local gp = require "gplus"
local selection = g.getselrect()
if #selection == 0 then
   g.exit("There is no selection.")
end
largestlifespanfoundsofar = 0
g.addlayer()
g.setlayer(0)
while ( true ) do
   g.new("")
   g.select(selection)
   g.randfill(37)
   g.run(10000)
   if tonumber(g.getpop()) == 0 then
      g.reset()
      count = 0
      while ( true ) do
         g.run(1)
         count = count+1
         if tonumber(g.getpop()) == 0 then
            if (count > largestlifespanfoundsofar) then
               largestlifespanfoundsofar = count
               g.show("Found "..largestlifespanfoundsofar.."-generation diehard")
               g.reset()
               g.setlayer(1)
               g.dellayer()
               g.setlayer(0)
               g.duplicate()
               g.setname(largestlifespanfoundsofar.."-generation diehard")
               g.update()
               g.setlayer(0)
            end
            break
         end
      end
   end
end
User avatar
dvgrn
Moderator
 
Posts: 5340
Joined: May 17th, 2009, 11:00 pm
Location: Madison, WI

Re: Script request thread

Postby calcyman » December 15th, 2018, 11:58 am

dvgrn wrote:
gameoflifemaniac wrote:I did those things, but this is supposed to be a 142-generation diehard?

No, that's a copy of your latest code interpreted as RLE -- a little difficult for me to find any further bugs in.


'Run Clipboard' rather than 'Open Clipboard'... :D
What do you do with ill crystallographers? Take them to the mono-clinic!
User avatar
calcyman
 
Posts: 1945
Joined: June 1st, 2009, 4:32 pm

Re: Script request thread

Postby gameoflifemaniac » December 15th, 2018, 12:46 pm

dvgrn wrote:
gameoflifemaniac wrote:I did those things, but this is supposed to be a 142-generation diehard?

No, that's a copy of your latest code interpreted as RLE -- a little difficult for me to find any further bugs in.

Looks like I added back the missing "end" statement in the wrong place, though, after the check for a new record. This should work better:

-- diehardv2.py
-- Finds diehards. When it finds a diehard with a larger lifespan than the previous one, it lists it in a different layer.
local g = golly()
local gp = require "gplus"
local selection = g.getselrect()
if #selection == 0 then
   g.exit("There is no selection.")
end
largestlifespanfoundsofar = 0
g.addlayer()
g.setlayer(0)
while ( true ) do
   g.new("")
   g.select(selection)
   g.randfill(37)
   g.run(10000)
   if tonumber(g.getpop()) == 0 then
      g.reset()
      count = 0
      while ( true ) do
         g.run(1)
         count = count+1
         if tonumber(g.getpop()) == 0 then
            if (count > largestlifespanfoundsofar) then
               largestlifespanfoundsofar = count
               g.show("Found "..largestlifespanfoundsofar.."-generation diehard")
               g.reset()
               g.setlayer(1)
               g.dellayer()
               g.setlayer(0)
               g.duplicate()
               g.setname(largestlifespanfoundsofar.."-generation diehard")
               g.update()
               g.setlayer(0)
            end
            break
         end
      end
   end
end

Now it works, yay! Thanks!
But when I run it from a folder, it says:
---------------------------
Python error:
---------------------------
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "C:\Users\marek\Desktop\Franek\golly-2.8-win-32bit\Scripts\Python\diehard.py", line 2
    -- Finds diehards. When it finds a diehard with a larger lifespan than the previous one, it lists it in a different layer.                                        ^
                                                            SyntaxError: invalid syntax

but it doesn't, when I run it from the clipboard. Why?
https://www.youtube.com/watch?v=q6EoRBvdVPQ
One big dirty Oro. Yeeeeeeeeee...
User avatar
gameoflifemaniac
 
Posts: 721
Joined: January 22nd, 2017, 11:17 am
Location: There too

Re: Script request thread

Postby dvgrn » December 15th, 2018, 1:09 pm

gameoflifemaniac wrote:But when I run it from a folder, it says
...
Python error:
...
but it doesn't, when I run it from the clipboard. Why?

Another detail I missed. It's not a good idea to name this script as if it's written in Python. With the script on the clipboard, Golly has no way of knowing what its name is.
User avatar
dvgrn
Moderator
 
Posts: 5340
Joined: May 17th, 2009, 11:00 pm
Location: Madison, WI

Re: Script request thread

Postby Gamedziner » December 15th, 2018, 1:26 pm

gameoflifemaniac wrote:But when I run it from a folder, it says:
---------------------------
Python error:
---------------------------
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "C:\Users\marek\Desktop\Franek\golly-2.8-win-32bit\Scripts\Python\diehard.py", line 2
    -- Finds diehards. When it finds a diehard with a larger lifespan than the previous one, it lists it in a different layer.                                        ^
                                                            SyntaxError: invalid syntax

but it doesn't, when I run it from the clipboard. Why?

It seems to me that the comment is getting read as code. If the code is being read as Python rather than Lua, it may be related to compatibility issues between the two languages, such as the difference between "#" and "--" as comment indicators.
Gamedziner
 
Posts: 637
Joined: May 30th, 2016, 8:47 pm
Location: Milky Way Galaxy: Planet Earth

Re: Script request thread

Postby dvgrn » December 15th, 2018, 1:38 pm

Gamedziner wrote:It seems to me that the comment is getting read as code...

Specifically, Golly is reading it as Python code because gameoflifemaniac saved it with a Python .py extension. Call it .lua and the problem goes away.
User avatar
dvgrn
Moderator
 
Posts: 5340
Joined: May 17th, 2009, 11:00 pm
Location: Madison, WI

Re: Script request thread

Postby gameoflifemaniac » December 15th, 2018, 1:47 pm

dvgrn wrote:
Gamedziner wrote:It seems to me that the comment is getting read as code...

Specifically, Golly is reading it as Python code because gameoflifemaniac saved it with a Python .py extension. Call it .lua and the problem goes away.

The problem was that it was supposed to be a Lua script, but forgot it was Lua and I don't know why I told myself it's Python.
https://www.youtube.com/watch?v=q6EoRBvdVPQ
One big dirty Oro. Yeeeeeeeeee...
User avatar
gameoflifemaniac
 
Posts: 721
Joined: January 22nd, 2017, 11:17 am
Location: There too

Re: Script request thread

Postby 77topaz » January 12th, 2019, 2:42 am

Does anyone have a copy of the catagoluer.py script for finding apgcodes and Catagolue pattern pages for objects? I accidentally deleted mine when I updated my Golly.
User avatar
77topaz
 
Posts: 1340
Joined: January 12th, 2018, 9:19 pm

Re: Script request thread

Postby dvgrn » January 12th, 2019, 8:36 am

77topaz wrote:Does anyone have a copy of the catagoluer.py script for finding apgcodes and Catagolue pattern pages for objects? I accidentally deleted mine when I updated my Golly.

From your Discord comment it sounds like you don't like biggiemac's script from this thread, but that's the only one I can remember seeing.

It's trivial to modify biggiemac's script to avoid creating a new layer, and to add g.select(g.getrect()) at the beginning of the script so that no advance selection is needed. You could also create a temporary HTML file and then tell Golly to open it, to produce the other effect you mentioned. Not sure why any of these changes would be improvements, though.
User avatar
dvgrn
Moderator
 
Posts: 5340
Joined: May 17th, 2009, 11:00 pm
Location: Madison, WI

Re: Script request thread

Postby Ian07 » January 18th, 2019, 10:39 pm

Is there an RLE-to-apgcode script out there for linear growth patterns?
Ian07
 
Posts: 160
Joined: September 22nd, 2018, 8:48 am

Re: Script request thread

Postby calcyman » January 18th, 2019, 11:21 pm

Ian07 wrote:Is there an RLE-to-apgcode script out there for linear growth patterns?


Download the latest apgsearch and run:

./recompile.sh --symmetry "stdin_test"
cat "path/to/file.rle" | ./apgluxe


and look inside the log file that's produced.
What do you do with ill crystallographers? Take them to the mono-clinic!
User avatar
calcyman
 
Posts: 1945
Joined: June 1st, 2009, 4:32 pm

Re: Script request thread

Postby Saka » January 19th, 2019, 12:36 am

Where is the code for golly's parse function? I cant find it.
--(Or any other RLE -> clist function, I dont really need the translation stuff.)
EDIT:
Specifically in Python if possible
If you're the person that uploaded to Sakagolue illegally, please PM me.
x = 17, y = 10, rule = B3/S23
b2ob2obo5b2o$11b4obo$2bob3o2bo2b3o$bo3b2o4b2o$o2bo2bob2o3b4o$bob2obo5b
o2b2o$2b2o4bobo2b3o$bo3b5ob2obobo$2bo5bob2o$4bob2o2bobobo!

(Check gen 2)
User avatar
Saka
 
Posts: 2780
Joined: June 19th, 2015, 8:50 pm
Location: In the kingdom of Sultan Hamengkubuwono X

Re: Script request thread

Postby wildmyron » January 21st, 2019, 2:54 am

Saka wrote:Where is the code for golly's parse function? I cant find it.
--(Or any other RLE -> clist function, I dont really need the translation stuff.)
EDIT:
Specifically in Python if possible

Golly's code for the golly.parse() Python call can be found in the py_parse() function: [https://sourceforge.net/p/golly/code/ci/master/tree/gui-wx/wxpython.cpp#l915 It is implemented in C++.
Similarly, Golly's native code to read an rle pattern, readrle(), is also implemented in C++ https://sourceforge.net/p/golly/code/ci ... n.cpp#l169

Line numbers may change in future.

I don't know of any code to specifically translate rle to clists, mostly because if you want to do that you can just use g.parse(). A good place to start for adapting existing scripts might be the various scripts posted in response to Goldtiger's request for a rle to ascii converter: viewtopic.php?f=9&t=2032&p=64421
wildmyron
 
Posts: 1028
Joined: August 9th, 2013, 12:45 am

Re: Script request thread

Postby Moosey » February 7th, 2019, 4:56 pm

A script that throws together random n-glider synthesis in CGoL, please.
Python.
You’d give it a number n and it would output a random n-G synth.
My rules:
They can be found here

Bill Watterson once wrote: "How do soldiers killing each other solve the world's problems?"
User avatar
Moosey
 
Posts: 822
Joined: January 27th, 2019, 5:54 pm
Location: A house, or perhaps the OCA board.

Re: Script request thread

Postby dvgrn » February 7th, 2019, 5:13 pm

Moosey wrote:A script that throws together random n-glider synthesis in CGoL, please.
Python.
You’d give it a number n and it would output a random n-G synth.

Check out simsim314's script from... yikes, that was almost five years ago already. It might not precisely match your request, but it might be close enough, and it should be easy to make adjustments.

Also not completely relevant: is the code checked in somewhere that would get apgsearch to submit random unidirectional slow-salvo "soups"? Or is that something only calcyman can do? (I haven't tried looking around in gitlab/apgoucher yet.)
User avatar
dvgrn
Moderator
 
Posts: 5340
Joined: May 17th, 2009, 11:00 pm
Location: Madison, WI

Re: Script request thread

Postby Moosey » February 7th, 2019, 5:20 pm

dvgrn wrote:
Moosey wrote:A script that throws together random n-glider synthesis in CGoL, please.
Python.
You’d give it a number n and it would output a random n-G synth.

Check out simsim314's script from... yikes, that was almost five years ago already. It might not precisely match your request, but it might be close enough, and it should be easy to make adjustments.

Also not completely relevant: is the code checked in somewhere that would get apgsearch to submit random unidirectional slow-salvo "soups"? Or is that something only calcyman can do? (I haven't tried looking around in gitlab/apgoucher yet.)

It seems an anonymous contributor has contributed to the SS census, so...

EDIT:
problem:
Screen Shot 2019-02-07 at 4.22.44 PM.png
ERGH
Screen Shot 2019-02-07 at 4.22.44 PM.png (24.88 KiB) Viewed 813 times

This is a problem with almost any python script I get from Conwaylife.com
My rules:
They can be found here

Bill Watterson once wrote: "How do soldiers killing each other solve the world's problems?"
User avatar
Moosey
 
Posts: 822
Joined: January 27th, 2019, 5:54 pm
Location: A house, or perhaps the OCA board.

PreviousNext

Return to Scripts

Who is online

Users browsing this forum: No registered users and 4 guests