Script request thread

For scripts to aid with computation or simulation in cellular automata.
User avatar
calcyman
Moderator
Posts: 2932
Joined: June 1st, 2009, 4:32 pm

Re: Script request thread

Post by calcyman » July 27th, 2019, 8:09 am

testitemqlstudop wrote:I would like a bulk apgcode to RLE, which converts a very long list of apgcodes (think 600K) to RLE.
To one RLE per apgcode, or to an RLE containing all of them?
What do you do with ill crystallographers? Take them to the mono-clinic!

User avatar
testitemqlstudop
Posts: 1367
Joined: July 21st, 2016, 11:45 am
Location: in catagolue
Contact:

Re: Script request thread

Post by testitemqlstudop » July 27th, 2019, 10:32 pm

An RLE containing all of them.

User avatar
2718281828
Posts: 738
Joined: August 8th, 2017, 5:38 pm

Re: Script request thread

Post by 2718281828 » August 15th, 2019, 7:42 am

I need a python script for checking if a glider constellation is valid for synthesis or not
e.g. this one is FALSE:

Code: Select all

x = 15, y = 13, rule = B3/S23
9b2o$10b2o$9bo2$12b3o$12bo$13bo$4bobo$5b2o$5bo$b2o$obo$2bo!
and this one TRUE:

Code: Select all

x = 16, y = 13, rule = B3/S23
10b2o$11b2o$10bo2$13b3o$13bo$14bo$4bobo$5b2o$5bo$b2o$obo$2bo!
The input is only the rle string, so the position and orientation of the gliders is unknown.

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

Re: Script request thread

Post by dvgrn » August 15th, 2019, 8:06 am

2718281828 wrote:I need a python script for checking if a glider constellation is valid for synthesis or not
e.g. this one is FALSE:

Code: Select all

x = 15, y = 13, rule = B3/S23
9b2o$10b2o$9bo2$12b3o$12bo$13bo$4bobo$5b2o$5bo$b2o$obo$2bo!
and this one TRUE:

Code: Select all

x = 16, y = 13, rule = B3/S23
10b2o$11b2o$10bo2$13b3o$13bo$14bo$4bobo$5b2o$5bo$b2o$obo$2bo!
The input is only the rle string, so the position and orientation of the gliders is unknown.
Seems like it's starting to be a good idea to ask a new question for this kind of request: is it okay to use lifelib, or should this script run in Golly Python with no additional prerequisites?

It's pretty easy to hack something together with a custom version of my old recognizer script. That's pretty archaic code by today's standards, but it doesn't have any external dependencies.

User avatar
2718281828
Posts: 738
Joined: August 8th, 2017, 5:38 pm

Re: Script request thread

Post by 2718281828 » August 15th, 2019, 8:12 am

lifelib would be fine.

User avatar
calcyman
Moderator
Posts: 2932
Joined: June 1st, 2009, 4:32 pm

Re: Script request thread

Post by calcyman » August 15th, 2019, 8:39 am

2718281828 wrote:lifelib would be fine.
Jeremy's Shinjuku project already has this functionality.
What do you do with ill crystallographers? Take them to the mono-clinic!

CoolCreeper39
Posts: 58
Joined: June 19th, 2019, 12:18 pm

Re: Script request thread

Post by CoolCreeper39 » August 15th, 2019, 4:28 pm

Is there a script that can search through all unique patters of an n-cell bounding box and produce the longest lasting possible methuselah of that bounding box?

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

Re: Script request thread

Post by dvgrn » August 15th, 2019, 4:48 pm

CoolCreeper39 wrote:Is there a script that can search through all unique patters of an n-cell bounding box and produce the longest lasting possible methuselah of that bounding box?
For Conway's Life rules specifically? For anything above really tiny bounding boxes that have been exhaustively searched multiple times already, this is the kind of task that really needs an optimized compiled program, rather than a Python or Lua script.

Start with simeks' search program (I don't think the newer version mentioned there has materialized yet). Early posts in the thread give various bounding boxes that have already been exhaustively searched.

If you really want a Python script, maybe start here -- there are some questions there that would need to be answered before an adaptation of apgsearch 1.x's code can be done. And then it's trivial to enumerate all 2^N patterns in an N-cell bounding box, or not quite so trivial but still fairly straightforward to enumerate just the unique patterns, discarding rotations and reflections.

User avatar
2718281828
Posts: 738
Joined: August 8th, 2017, 5:38 pm

Re: Script request thread

Post by 2718281828 » August 16th, 2019, 5:19 pm

calcyman wrote: Jeremy's Shinjuku project already has this functionality.
I did not find a function that supports this functionality in Shinjuku.

The only way I see is to apply canonical_time_finite() on e.g.

Code: Select all

past = 100

p = gset.extract(lt.pattern("9b2o$10b2o$9bo2$12b3o$12bo$13bo$4bobo$5b2o$5bo$b2o$obo$2bo!"))
ctime = p.canonical_time_finite()[1]
ctime_past = p[-past].canonical_time_finite()[1]-past
print(ctime, ctime_past)

p = gset.extract(lt.pattern("10b2o$11b2o$10bo2$13b3o$13bo$14bo$4bobo$5b2o$5bo$b2o$obo$2bo!"))
ctime = p.canonical_time_finite()[1]
ctime_past = p[-past].canonical_time_finite()[1]-past
print(ctime, ctime_past)
with the output

Code: Select all

2 -17
2 2
The first one is false, the latter true. Is there a better way, for doing so?

User avatar
calcyman
Moderator
Posts: 2932
Joined: June 1st, 2009, 4:32 pm

Re: Script request thread

Post by calcyman » August 17th, 2019, 6:27 am

2718281828 wrote:The first one is false, the latter true. Is there a better way, for doing so?
It's relatively straightforward like so (by the way, this assumes the pattern consists only of disjoint gliders):

Code: Select all

import lifelib
lt = lifelib.load_rules('b3s23').lifetree(n_layers=1)
x = lt.pattern('''x = 16, y = 13, rule = B3/S23 
10b2o$11b2o$10bo2$13b3o$13bo$14bo$4bobo$5b2o$5bo$b2o$obo$2bo!''')
gliders = x.components()
rewind_by = 4 * sum(x.bounding_box[2:])
y = lt.pattern()
for g in gliders:
    y += g[-rewind_by]
z = y[rewind_by]
print(z == x)
What do you do with ill crystallographers? Take them to the mono-clinic!

User avatar
2718281828
Posts: 738
Joined: August 8th, 2017, 5:38 pm

Re: Script request thread

Post by 2718281828 » August 17th, 2019, 7:17 am

calcyman wrote:
2718281828 wrote:The first one is false, the latter true. Is there a better way, for doing so?
It's relatively straightforward like so (by the way, this assumes the pattern consists only of disjoint gliders):

Code: Select all

import lifelib
lt = lifelib.load_rules('b3s23').lifetree(n_layers=1)
x = lt.pattern('''x = 16, y = 13, rule = B3/S23 
10b2o$11b2o$10bo2$13b3o$13bo$14bo$4bobo$5b2o$5bo$b2o$obo$2bo!''')
gliders = x.components()
rewind_by = 4 * sum(x.bounding_box[2:])
y = lt.pattern()
for g in gliders:
    y += g[-rewind_by]
z = y[rewind_by]
print(z == x)
Thanks, this is much more elegant.

User avatar
Moosey
Posts: 4306
Joined: January 27th, 2019, 5:54 pm
Location: here
Contact:

Re: Script request thread

Post by Moosey » September 1st, 2019, 1:35 pm

Does anyone know where that script for generating higher-range versions of bugs can be found?
not active here but active on discord

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

Re: Script request thread

Post by dvgrn » September 1st, 2019, 3:50 pm

Moosey wrote:Does anyone know where that script for generating higher-range versions of bugs can be found?
Saka's script?

Not sure I'm reading it right, but I think this is "Dean Hickerson's algorithm".

User avatar
Gustone
Posts: 744
Joined: March 6th, 2019, 2:26 am

Re: Script request thread

Post by Gustone » September 9th, 2019, 10:36 am

1. a history rule maker with this palette

Code: Select all

@COLORS
1 255 255   255
2   255 255   55
3   0   0 0
4   200 255 200
5 100 75 75
6 75 75 75
and these icons

Code: Select all

@ICONS

XPM
/* width height num_colors chars_per_pixel */
"31 186 5 1"
/* colors */
". c #000000"
"B c #404040"
"C c #808080"
"D c #C0C0C0"
"E c #FFFFFF"
/* icon for state 1 */
"..............................."
"..............................."
"..........BCDEEEEEDCB.........."
".........CEEEEEEEEEEEC........."
".......BEEEEEEEEEEEEEEEB......."
"......DEEEEEEEEEEEEEEEEED......"
".....DEEEEEEEEEEEEEEEEEEED....."
"....BEEEEEEEEEEEEEEEEEEEEEB...."
"....EEEEEEEEEEEEEEEEEEEEEEE...."
"...CEEEEEEEEEEEEEEEEEEEEEEEC..."
"..BEEEEEEEEEEEEEEEEEEEEEEEEEB.."
"..CEEEEEEEEEEEEEEEEEEEEEEEEEC.."
"..DEEEEEEEEEEEEEEEEEEEEEEEEED.."
"..EEEEEEEEEEEEEEEEEEEEEEEEEEE.."
"..EEEEEEEEEEEEEEEEEEEEEEEEEEE.."
"..EEEEEEEEEEEEEEEEEEEEEEEEEEE.."
"..EEEEEEEEEEEEEEEEEEEEEEEEEEE.."
"..EEEEEEEEEEEEEEEEEEEEEEEEEEE.."
"..DEEEEEEEEEEEEEEEEEEEEEEEEED.."
"..CEEEEEEEEEEEEEEEEEEEEEEEEEC.."
"..BEEEEEEEEEEEEEEEEEEEEEEEEEB.."
"...CEEEEEEEEEEEEEEEEEEEEEEEC..."
"....EEEEEEEEEEEEEEEEEEEEEEE...."
"....BEEEEEEEEEEEEEEEEEEEEEB...."
".....DEEEEEEEEEEEEEEEEEEED....."
"......DEEEEEEEEEEEEEEEEED......"
".......BEEEEEEEEEEEEEEEB......."
".........CEEEEEEEEEEEC........."
"..........BCDEEEEEDCB.........."
"..............................."
"..............................."
/* icon for state 2 */
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
/* icon for state 3 */
"..............................."
"..............................."
"..........BCDEEEEEDCB.........."
".........CEEEEEEEEEEEC........."
".......BEEEEEEEEEEEEEEEB......."
"......DEEEEEEEEEEEEEEEEED......"
".....DEEEEEEEEEEEEEEEEEEED....."
"....BEEEEEEEEEEEEEEEEEEEEEB...."
"....EEEEEEEEEEEEEEEEEEEEEEE...."
"...CEEEEEEEEEEEEEEEEEEEEEEEC..."
"..BEEEEEEEEEEEEEEEEEEEEEEEEEB.."
"..CEEEEEEEEEEEEEEEEEEEEEEEEEC.."
"..DEEEEEEEEEEEEEEEEEEEEEEEEED.."
"..EEEEEEEEEEEEEEEEEEEEEEEEEEE.."
"..EEEEEEEEEEEEEEEEEEEEEEEEEEE.."
"..EEEEEEEEEEEEEEEEEEEEEEEEEEE.."
"..EEEEEEEEEEEEEEEEEEEEEEEEEEE.."
"..EEEEEEEEEEEEEEEEEEEEEEEEEEE.."
"..DEEEEEEEEEEEEEEEEEEEEEEEEED.."
"..CEEEEEEEEEEEEEEEEEEEEEEEEEC.."
"..BEEEEEEEEEEEEEEEEEEEEEEEEEB.."
"...CEEEEEEEEEEEEEEEEEEEEEEEC..."
"....EEEEEEEEEEEEEEEEEEEEEEE...."
"....BEEEEEEEEEEEEEEEEEEEEEB...."
".....DEEEEEEEEEEEEEEEEEEED....."
"......DEEEEEEEEEEEEEEEEED......"
".......BEEEEEEEEEEEEEEEB......."
".........CEEEEEEEEEEEC........."
"..........BCDEEEEEDCB.........."
"..............................."
"..............................."
/* icon for state 4 */
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
/* icon for state 5 */
"..............................."
"..............................."
"..........BCDEEEEEDCB.........."
".........CEEEEEEEEEEEC........."
".......BEEEEEEEEEEEEEEEB......."
"......DEEEEEEEEEEEEEEEEED......"
".....DEEEEEEEEEEEEEEEEEEED....."
"....BEEEEEEEEEEEEEEEEEEEEEB...."
"....EEEEEEEEEEEEEEEEEEEEEEE...."
"...CEEEEEEEEEEEEEEEEEEEEEEEC..."
"..BEEEEEEEEEEEEEEEEEEEEEEEEEB.."
"..CEEEEEEEEEEEEEEEEEEEEEEEEEC.."
"..DEEEEEEEEEEEEEEEEEEEEEEEEED.."
"..EEEEEEEEEEEEEEEEEEEEEEEEEEE.."
"..EEEEEEEEEEEEEEEEEEEEEEEEEEE.."
"..EEEEEEEEEEEEEEEEEEEEEEEEEEE.."
"..EEEEEEEEEEEEEEEEEEEEEEEEEEE.."
"..EEEEEEEEEEEEEEEEEEEEEEEEEEE.."
"..DEEEEEEEEEEEEEEEEEEEEEEEEED.."
"..CEEEEEEEEEEEEEEEEEEEEEEEEEC.."
"..BEEEEEEEEEEEEEEEEEEEEEEEEEB.."
"...CEEEEEEEEEEEEEEEEEEEEEEEC..."
"....EEEEEEEEEEEEEEEEEEEEEEE...."
"....BEEEEEEEEEEEEEEEEEEEEEB...."
".....DEEEEEEEEEEEEEEEEEEED....."
"......DEEEEEEEEEEEEEEEEED......"
".......BEEEEEEEEEEEEEEEB......."
".........CEEEEEEEEEEEC........."
"..........BCDEEEEEDCB.........."
"..............................."
"..............................."
/* icon for state 6 */
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."

XPM
/* width height num_colors chars_per_pixel */
"15 90 5 1"
/* colors */
". c #000000"
"B c #404040"
"C c #808080"
"D c #C0C0C0"
"E c #FFFFFF"
/* icon for state 1 */
"..............."
"....BDEEEDB...."
"...DEEEEEEED..."
"..DEEEEEEEEED.."
".BEEEEEEEEEEEB."
".DEEEEEEEEEEED."
".EEEEEEEEEEEEE."
".EEEEEEEEEEEEE."
".EEEEEEEEEEEEE."
".DEEEEEEEEEEED."
".BEEEEEEEEEEEB."
"..DEEEEEEEEED.."
"...DEEEEEEED..."
"....BDEEEDB...."
"..............."
/* icon for state 2 */
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
/* icon for state 3 */
"..............."
"....BDEEEDB...."
"...DEEEEEEED..."
"..DEEEEEEEEED.."
".BEEEEEEEEEEEB."
".DEEEEEEEEEEED."
".EEEEEEEEEEEEE."
".EEEEEEEEEEEEE."
".EEEEEEEEEEEEE."
".DEEEEEEEEEEED."
".BEEEEEEEEEEEB."
"..DEEEEEEEEED.."
"...DEEEEEEED..."
"....BDEEEDB...."
"..............."
/* icon for state 4 */
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
/* icon for state 5 */
"..............."
"....BDEEEDB...."
"...DEEEEEEED..."
"..DEEEEEEEEED.."
".BEEEEEEEEEEEB."
".DEEEEEEEEEEED."
".EEEEEEEEEEEEE."
".EEEEEEEEEEEEE."
".EEEEEEEEEEEEE."
".DEEEEEEEEEEED."
".BEEEEEEEEEEEB."
"..DEEEEEEEEED.."
"...DEEEEEEED..."
"....BDEEEDB...."
"..............."
/* icon for state 6 */
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"

XPM
/* width height num_colors chars_per_pixel */
"7 42 6 1"
/* colors */
". c #000000"
"B c #404040"
"C c #808080"
"D c #C0C0C0"
"E c #FFFFFF"
"F c #E0E0E0"
/* icon for state 1 */
".BFEFB."
"BEEEEEB"
"FEEEEEF"
"EEEEEEE"
"FEEEEEF"
"BEEEEEB"
".BFEFB."
/* icon for state 2 */
".E.E.E."
"E.E.E.E"
".E.E.E."
"E.E.E.E"
".E.E.E."
"E.E.E.E"
".E.E.E."
/* icon for state 3 */
".BFEFB."
"BEEEEEB"
"FEEEEEF"
"EEEEEEE"
"FEEEEEF"
"BEEEEEB"
".BFEFB."
/* icon for state 4 */
"E.E.E.E"
".E.E.E."
"E.E.E.E"
".E.E.E."
"E.E.E.E"
".E.E.E."
"E.E.E.E"
/* icon for state 5 */
".BFEFB."
"BEEEEEB"
"FEEEEEF"
"EEEEEEE"
"FEEEEEF"
"BEEEEEB"
".BFEFB."
/* icon for state 6 */
"E.E.E.E"
".E.E.E."
"E.E.E.E"
".E.E.E."
"E.E.E.E"
".E.E.E."
"E.E.E.E"
makes a history of the current rule (in any rules folder) and sets the rule to it
2. extended instead of history, this palette

Code: Select all

@COLORS
1 255 255   255
2   255 255   55
3   0   0 0
4   200 255 200
5 100 75 75
6 75 75 75
and these icons

Code: Select all

@ICONS

XPM
/* width height num_colors chars_per_pixel */
"31 186 5 1"
/* colors */
". c #000000"
"B c #404040"
"C c #808080"
"D c #C0C0C0"
"E c #FFFFFF"
/* icon for state 1 */
"..............................."
"..............................."
"..........BCDEEEEEDCB.........."
".........CEEEEEEEEEEEC........."
".......BEEEEEEEEEEEEEEEB......."
"......DEEEEEEEEEEEEEEEEED......"
".....DEEEEEEEEEEEEEEEEEEED....."
"....BEEEEEEEEEEEEEEEEEEEEEB...."
"....EEEEEEEEEEEEEEEEEEEEEEE...."
"...CEEEEEEEEEEEEEEEEEEEEEEEC..."
"..BEEEEEEEEEEEEEEEEEEEEEEEEEB.."
"..CEEEEEEEEEEEEEEEEEEEEEEEEEC.."
"..DEEEEEEEEEEEEEEEEEEEEEEEEED.."
"..EEEEEEEEEEEEEEEEEEEEEEEEEEE.."
"..EEEEEEEEEEEEEEEEEEEEEEEEEEE.."
"..EEEEEEEEEEEEEEEEEEEEEEEEEEE.."
"..EEEEEEEEEEEEEEEEEEEEEEEEEEE.."
"..EEEEEEEEEEEEEEEEEEEEEEEEEEE.."
"..DEEEEEEEEEEEEEEEEEEEEEEEEED.."
"..CEEEEEEEEEEEEEEEEEEEEEEEEEC.."
"..BEEEEEEEEEEEEEEEEEEEEEEEEEB.."
"...CEEEEEEEEEEEEEEEEEEEEEEEC..."
"....EEEEEEEEEEEEEEEEEEEEEEE...."
"....BEEEEEEEEEEEEEEEEEEEEEB...."
".....DEEEEEEEEEEEEEEEEEEED....."
"......DEEEEEEEEEEEEEEEEED......"
".......BEEEEEEEEEEEEEEEB......."
".........CEEEEEEEEEEEC........."
"..........BCDEEEEEDCB.........."
"..............................."
"..............................."
/* icon for state 2 */
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
/* icon for state 3 */
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
/* icon for state 4 */
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
/* icon for state 5 */
"..............................."
"..............................."
"..........BCDEEEEEDCB.........."
".........CEEEEEEEEEEEC........."
".......BEEEEEEEEEEEEEEEB......."
"......DEEEEEEEEEEEEEEEEED......"
".....DEEEEEEEEEEEEEEEEEEED....."
"....BEEEEEEEEEEEEEEEEEEEEEB...."
"....EEEEEEEEEEEEEEEEEEEEEEE...."
"...CEEEEEEEEEEEEEEEEEEEEEEEC..."
"..BEEEEEEEEEEEEEEEEEEEEEEEEEB.."
"..CEEEEEEEEEEEEEEEEEEEEEEEEEC.."
"..DEEEEEEEEEEEEEEEEEEEEEEEEED.."
"..EEEEEEEEEEEEEEEEEEEEEEEEEEE.."
"..EEEEEEEEEEEEEEEEEEEEEEEEEEE.."
"..EEEEEEEEEEEEEEEEEEEEEEEEEEE.."
"..EEEEEEEEEEEEEEEEEEEEEEEEEEE.."
"..EEEEEEEEEEEEEEEEEEEEEEEEEEE.."
"..DEEEEEEEEEEEEEEEEEEEEEEEEED.."
"..CEEEEEEEEEEEEEEEEEEEEEEEEEC.."
"..BEEEEEEEEEEEEEEEEEEEEEEEEEB.."
"...CEEEEEEEEEEEEEEEEEEEEEEEC..."
"....EEEEEEEEEEEEEEEEEEEEEEE...."
"....BEEEEEEEEEEEEEEEEEEEEEB...."
".....DEEEEEEEEEEEEEEEEEEED....."
"......DEEEEEEEEEEEEEEEEED......"
".......BEEEEEEEEEEEEEEEB......."
".........CEEEEEEEEEEEC........."
"..........BCDEEEEEDCB.........."
"..............................."
"..............................."
/* icon for state 6 */
"..............................."
"..............................."
"..........BCDEEEEEDCB.........."
".........CEEEEEEEEEEEC........."
".......BEEEEEEEEEEEEEEEB......."
"......DEEEEEEEEEEEEEEEEED......"
".....DEEEEEEEEEEEEEEEEEEED....."
"....BEEEEEEEEEEEEEEEEEEEEEB...."
"....EEEEEEEEEEEEEEEEEEEEEEE...."
"...CEEEEEEEEEEEEEEEEEEEEEEEC..."
"..BEEEEEEEEEEEEEEEEEEEEEEEEEB.."
"..CEEEEEEEEEEEEEEEEEEEEEEEEEC.."
"..DEEEEEEEEEEEEEEEEEEEEEEEEED.."
"..EEEEEEEEEEEEEEEEEEEEEEEEEEE.."
"..EEEEEEEEEEEEEEEEEEEEEEEEEEE.."
"..EEEEEEEEEEEEEEEEEEEEEEEEEEE.."
"..EEEEEEEEEEEEEEEEEEEEEEEEEEE.."
"..EEEEEEEEEEEEEEEEEEEEEEEEEEE.."
"..DEEEEEEEEEEEEEEEEEEEEEEEEED.."
"..CEEEEEEEEEEEEEEEEEEEEEEEEEC.."
"..BEEEEEEEEEEEEEEEEEEEEEEEEEB.."
"...CEEEEEEEEEEEEEEEEEEEEEEEC..."
"....EEEEEEEEEEEEEEEEEEEEEEE...."
"....BEEEEEEEEEEEEEEEEEEEEEB...."
".....DEEEEEEEEEEEEEEEEEEED....."
"......DEEEEEEEEEEEEEEEEED......"
".......BEEEEEEEEEEEEEEEB......."
".........CEEEEEEEEEEEC........."
"..........BCDEEEEEDCB.........."
"..............................."
"..............................."

XPM
/* width height num_colors chars_per_pixel */
"15 90 5 1"
/* colors */
". c #000000"
"B c #404040"
"C c #808080"
"D c #C0C0C0"
"E c #FFFFFF"
/* icon for state 1 */
"..............."
"....BDEEEDB...."
"...DEEEEEEED..."
"..DEEEEEEEEED.."
".BEEEEEEEEEEEB."
".DEEEEEEEEEEED."
".EEEEEEEEEEEEE."
".EEEEEEEEEEEEE."
".EEEEEEEEEEEEE."
".DEEEEEEEEEEED."
".BEEEEEEEEEEEB."
"..DEEEEEEEEED.."
"...DEEEEEEED..."
"....BDEEEDB...."
"..............."
/* icon for state 2 */
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
/* icon for state 3 */
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
/* icon for state 4 */
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
/* icon for state 5 */
"..............."
"....BDEEEDB...."
"...DEEEEEEED..."
"..DEEEEEEEEED.."
".BEEEEEEEEEEEB."
".DEEEEEEEEEEED."
".EEEEEEEEEEEEE."
".EEEEEEEEEEEEE."
".EEEEEEEEEEEEE."
".DEEEEEEEEEEED."
".BEEEEEEEEEEEB."
"..DEEEEEEEEED.."
"...DEEEEEEED..."
"....BDEEEDB...."
"..............."
/* icon for state 6 */
"..............."
"....BDEEEDB...."
"...DEEEEEEED..."
"..DEEEEEEEEED.."
".BEEEEEEEEEEEB."
".DEEEEEEEEEEED."
".EEEEEEEEEEEEE."
".EEEEEEEEEEEEE."
".EEEEEEEEEEEEE."
".DEEEEEEEEEEED."
".BEEEEEEEEEEEB."
"..DEEEEEEEEED.."
"...DEEEEEEED..."
"....BDEEEDB...."
"..............."

XPM
/* width height num_colors chars_per_pixel */
"7 42 6 1"
/* colors */
". c #000000"
"B c #404040"
"C c #808080"
"D c #C0C0C0"
"E c #FFFFFF"
"F c #E0E0E0"
/* icon for state 1 */
".BFEFB."
"BEEEEEB"
"FEEEEEF"
"EEEEEEE"
"FEEEEEF"
"BEEEEEB"
".BFEFB."
/* icon for state 2 */
".E.E.E."
"E.E.E.E"
".E.E.E."
"E.E.E.E"
".E.E.E."
"E.E.E.E"
".E.E.E."
/* icon for state 3 */
"E.E.E.E"
".E.E.E."
"E.E.E.E"
".E.E.E."
"E.E.E.E"
".E.E.E."
"E.E.E.E"
/* icon for state 4 */
"E.E.E.E"
".E.E.E."
"E.E.E.E"
".E.E.E."
"E.E.E.E"
".E.E.E."
"E.E.E.E"
/* icon for state 5 */
".BFEFB."
"BEEEEEB"
"FEEEEEF"
"EEEEEEE"
"FEEEEEF"
"BEEEEEB"
".BFEFB."
/* icon for state 6 */
".BFEFB."
"BEEEEEB"
"FEEEEEF"
"EEEEEEE"
"FEEEEEF"
"BEEEEEB"
".BFEFB."
3. history to normal script (does not save the rule)
4. extended to normal script (same)

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

Re: Script request thread

Post by dvgrn » September 9th, 2019, 1:19 pm

Gustone wrote:1. a history rule maker with this palette...
Why yellow for state 2? I guess it's blue if the color scheme in Golly is inverted, but either black ON and blue OFF, or white ON and yellow OFF, seem a little difficult to tell apart from each other in busy patterns.

Anyway, the isotropic-history-rule-gen.py script posted on the Basic Questions thread this morning can easily be altered to include colors and icons:

Code: Select all

# isotropic-color-history-rule-gen.py, version 1.0
#   Minimal changes made to isotropic-rule-gen.py version 1.1
#     ( https://github.com/dvgrn/b3s23life/blob/master/rule-table-makers/isotropic-rule-gen.py )
#     to produce an equivalent three-state rule with state-2 History cells
#
# Most of the code is unchanged from isotropic-rule.py / isotropicRulegen.py,
# an auxillary rule generator from wildmyron's non-totalistic version of apgsearch.
# The rulespace is the set of isotropic non-totalistic rules on the Moore
# neighbourhood, using Alan Hensel's notation.
# See http://www.ibiblio.org/lifepatterns/neighbors2.html
# Generate a History rule table for an isotropic rule using Alan Hensel's
# isotropic, non-totalistic rule format for CA on the Moore neighbourhood

import golly as g
import os

# Generates the helper rules for apgsearch-isotropic, given a base isotropic 
# rule in Hensel's notation.
class RuleGenerator:

    # notationdict adapted from Eric Goldstein's HenselNotation->Ruletable(1.3).py
    # ( http://conwaylife.com/forums/viewtopic.php?p=6815#p6815 )
    # Modified for neighbourhood2 version of Hensel's notation
    notationdict = {
        "0"  : [0,0,0,0,0,0,0,0],   #    
        "1e" : [1,0,0,0,0,0,0,0],   #   N
        "1c" : [0,1,0,0,0,0,0,0],   #   NE
        "2a" : [1,1,0,0,0,0,0,0],   #   N,  NE
        "2e" : [1,0,1,0,0,0,0,0],   #   N,  E
        "2k" : [1,0,0,1,0,0,0,0],   #   N,  SE
        "2i" : [1,0,0,0,1,0,0,0],   #   N,  S
        "2c" : [0,1,0,1,0,0,0,0],   #   NE, SE
        "2n" : [0,1,0,0,0,1,0,0],   #   NE, SW
        "3a" : [1,1,1,0,0,0,0,0],   #   N,  NE, E
        "3n" : [1,1,0,1,0,0,0,0],   #   N,  NE, SE
        "3r" : [1,1,0,0,1,0,0,0],   #   N,  NE, S
        "3q" : [1,1,0,0,0,1,0,0],   #   N,  NE, SW
        "3j" : [1,1,0,0,0,0,1,0],   #   N,  NE, W
        "3i" : [1,1,0,0,0,0,0,1],   #   N,  NE, NW
        "3e" : [1,0,1,0,1,0,0,0],   #   N,  E,  S
        "3k" : [1,0,1,0,0,1,0,0],   #   N,  E,  SW
        "3y" : [1,0,0,1,0,1,0,0],   #   N,  SE, SW
        "3c" : [0,1,0,1,0,1,0,0],   #   NE, SE, SW
        "4a" : [1,1,1,1,0,0,0,0],   #   N,  NE, E,  SE
        "4r" : [1,1,1,0,1,0,0,0],   #   N,  NE, E,  S
        "4q" : [1,1,1,0,0,1,0,0],   #   N,  NE, E,  SW
        "4i" : [1,1,0,1,1,0,0,0],   #   N,  NE, SE, S
        "4y" : [1,1,0,1,0,1,0,0],   #   N,  NE, SE, SW
        "4k" : [1,1,0,1,0,0,1,0],   #   N,  NE, SE, W
        "4n" : [1,1,0,1,0,0,0,1],   #   N,  NE, SE, NW
        "4z" : [1,1,0,0,1,1,0,0],   #   N,  NE, S,  SW
        "4j" : [1,1,0,0,1,0,1,0],   #   N,  NE, S,  W
        "4t" : [1,1,0,0,1,0,0,1],   #   N,  NE, S,  NW
        "4w" : [1,1,0,0,0,1,1,0],   #   N,  NE, SW, W
        "4e" : [1,0,1,0,1,0,1,0],   #   N,  E,  S,  W
        "4c" : [0,1,0,1,0,1,0,1],   #   NE, SE, SW, NW
        "5i" : [1,1,1,1,1,0,0,0],   #   N,  NE, E,  SE, S
        "5j" : [1,1,1,1,0,1,0,0],   #   N,  NE, E,  SE, SW
        "5n" : [1,1,1,1,0,0,1,0],   #   N,  NE, E,  SE, W
        "5a" : [1,1,1,1,0,0,0,1],   #   N,  NE, E,  SE, NW
        "5q" : [1,1,1,0,1,1,0,0],   #   N,  NE, E,  S,  SW
        "5c" : [1,1,1,0,1,0,1,0],   #   N,  NE, E,  S,  W
        "5r" : [1,1,0,1,1,1,0,0],   #   N,  NE, SE, S,  SW
        "5y" : [1,1,0,1,1,0,1,0],   #   N,  NE, SE, S,  W
        "5k" : [1,1,0,1,0,1,1,0],   #   N,  NE, SE, SW, W
        "5e" : [1,1,0,1,0,1,0,1],   #   N,  NE, SE, SW, NW
        "6a" : [1,1,1,1,1,1,0,0],   #   N,  NE, E,  SE, S,  SW
        "6c" : [1,1,1,1,1,0,1,0],   #   N,  NE, E,  SE, S,  W
        "6k" : [1,1,1,1,0,1,1,0],   #   N,  NE, E,  SE, SW, W
        "6e" : [1,1,1,1,0,1,0,1],   #   N,  NE, E,  SE, SW, NW
        "6n" : [1,1,1,0,1,1,1,0],   #   N,  NE, E,  S,  SW, W
        "6i" : [1,1,0,1,1,1,0,1],   #   N,  NE, SE, S,  SW, NW
        "7c" : [1,1,1,1,1,1,1,0],   #   N,  NE, E,  SE, S,  SW, W
        "7e" : [1,1,1,1,1,1,0,1],   #   N,  NE, E,  SE, S,  SW, NW
        "8"  : [1,1,1,1,1,1,1,1],   #   N,  NE, E,  SE, S,  SW, W,  NW
        }

    notationdict2 = {
        "0"  : "i,j,k,m,n,p,q,r",   #    
        "1e" : "1,j,k,m,n,p,q,r",   #   N
        "1c" : "i,1,k,m,n,p,q,r",   #   NE
        "2a" : "1,1,k,m,n,p,q,r",   #   N,  NE
        "2e" : "1,j,1,m,n,p,q,r",   #   N,  E
        "2k" : "1,j,k,1,n,p,q,r",   #   N,  SE
        "2i" : "1,j,k,m,1,p,q,r",   #   N,  S
        "2c" : "i,1,k,1,n,p,q,r",   #   NE, SE
        "2n" : "i,1,k,m,n,1,q,r",   #   NE, SW
        "3a" : "1,1,1,m,n,p,q,r",   #   N,  NE, E
        "3n" : "1,1,k,1,n,p,q,r",   #   N,  NE, SE
        "3r" : "1,1,k,m,1,p,q,r",   #   N,  NE, S
        "3q" : "1,1,k,m,n,1,q,r",   #   N,  NE, SW
        "3j" : "1,1,k,m,n,p,1,r",   #   N,  NE, W
        "3i" : "1,1,k,m,n,p,q,1",   #   N,  NE, NW
        "3e" : "1,j,1,m,1,p,q,r",   #   N,  E,  S
        "3k" : "1,j,1,m,n,1,q,r",   #   N,  E,  SW
        "3y" : "1,j,k,1,n,1,q,r",   #   N,  SE, SW
        "3c" : "i,1,k,1,n,1,q,r",   #   NE, SE, SW
        "4a" : "1,1,1,1,n,p,q,r",   #   N,  NE, E,  SE
        "4r" : "1,1,1,m,1,p,q,r",   #   N,  NE, E,  S
        "4q" : "1,1,1,m,n,1,q,r",   #   N,  NE, E,  SW
        "4i" : "1,1,k,1,1,p,q,r",   #   N,  NE, SE, S
        "4y" : "1,1,k,1,n,1,q,r",   #   N,  NE, SE, SW
        "4k" : "1,1,k,1,n,p,1,r",   #   N,  NE, SE, W
        "4n" : "1,1,k,1,n,p,q,1",   #   N,  NE, SE, NW
        "4z" : "1,1,k,m,1,1,q,r",   #   N,  NE, S,  SW
        "4j" : "1,1,k,m,1,p,1,r",   #   N,  NE, S,  W
        "4t" : "1,1,k,m,1,p,q,1",   #   N,  NE, S,  NW
        "4w" : "1,1,k,m,n,1,1,r",   #   N,  NE, SW, W
        "4e" : "1,j,1,m,1,p,1,r",   #   N,  E,  S,  W
        "4c" : "i,1,k,1,n,1,q,1",   #   NE, SE, SW, NW
        "5i" : "1,1,1,1,1,p,q,r",   #   N,  NE, E,  SE, S
        "5j" : "1,1,1,1,n,1,q,r",   #   N,  NE, E,  SE, SW
        "5n" : "1,1,1,1,n,p,1,r",   #   N,  NE, E,  SE, W
        "5a" : "1,1,1,1,n,p,q,1",   #   N,  NE, E,  SE, NW
        "5q" : "1,1,1,m,1,1,q,r",   #   N,  NE, E,  S,  SW
        "5c" : "1,1,1,m,1,p,1,r",   #   N,  NE, E,  S,  W
        "5r" : "1,1,k,1,1,1,q,r",   #   N,  NE, SE, S,  SW
        "5y" : "1,1,k,1,1,p,1,r",   #   N,  NE, SE, S,  W
        "5k" : "1,1,k,1,n,1,1,r",   #   N,  NE, SE, SW, W
        "5e" : "1,1,k,1,n,1,q,1",   #   N,  NE, SE, SW, NW
        "6a" : "1,1,1,1,1,1,q,r",   #   N,  NE, E,  SE, S,  SW
        "6c" : "1,1,1,1,1,p,1,r",   #   N,  NE, E,  SE, S,  W
        "6k" : "1,1,1,1,n,1,1,r",   #   N,  NE, E,  SE, SW, W
        "6e" : "1,1,1,1,n,1,q,1",   #   N,  NE, E,  SE, SW, NW
        "6n" : "1,1,1,m,1,1,1,r",   #   N,  NE, E,  S,  SW, W
        "6i" : "1,1,k,1,1,1,q,1",   #   N,  NE, SE, S,  SW, NW
        "7c" : "1,1,1,1,1,1,1,r",   #   N,  NE, E,  SE, S,  SW, W
        "7e" : "1,1,1,1,1,1,q,1",   #   N,  NE, E,  SE, S,  SW, NW
        "8"  : "1,1,1,1,1,1,1,1",   #   N,  NE, E,  SE, S,  SW, W,  NW
        }    
    allneighbours = [  
        ["0"],
        ["1e", "1c"],
        ["2a", "2e", "2k", "2i", "2c", "2n"],
        ["3a", "3n", "3r", "3q", "3j", "3i", "3e", "3k", "3y", "3c"],
        ["4a", "4r", "4q", "4i", "4y", "4k", "4n", "4z", "4j", "4t", "4w", "4e", "4c"],
        ["5i", "5j", "5n", "5a", "5q", "5c", "5r", "5y", "5k", "5e"],
        ["6a", "6c", "6k", "6e", "6n", "6i"],
        ["7c", "7e"],
        ["8"],
        ]
        
    allneighbours_flat = [n for x in allneighbours for n in x]
    
    numneighbours = len(notationdict)
    
    # Use dict to store rule elements, initialised by setrule():
    bee = {}
    ess = {}
    alphanumeric = ""
    rulename = ""
    
    # Save the isotropic rule
    def saveAllRules(self):    
        self.saveIsotropicRule()
    
    # Interpret birth or survival string
    def ruleparts(self, part):

        inverse = False
        nlist = []
        totalistic = True
        rule = { k: False for k, v in self.notationdict.iteritems() }
        
        # Reverse the rule string to simplify processing
        part = part[::-1]
        
        for c in part:
            if c.isdigit():
                d = int(c)
                if totalistic:
                    # Add all the neighbourhoods for this value
                    for neighbour in self.allneighbours[d]:
                        rule[neighbour] = True
                elif inverse:
                    # Add all the neighbourhoods not in nlist for this value
                    for neighbour in self.allneighbours[d]:
                        if neighbour[1] not in nlist:
                            rule[neighbour] = True
                else:
                    # Add all the neighbourhoods in nlist for this value
                    for n in nlist:
                        neighbour = c + n
                        if neighbour in rule:
                            rule[neighbour] = True
                        else:
                            # Error
                            return {}
                    
                inverse = False
                nlist = []
                totalistic = True

            elif (c == '-'):
                inverse = True

            else:
                totalistic = False
                nlist.append(c)
        
        return rule

    # Set isotropic, non-totalistic rule
    # Adapted from Eric Goldstein's HenselNotation->Ruletable(1.3).py
    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()
            

    # Save a rule file:
    def saverule(self, name, comments, table, colours, icons):
        
        ruledir = g.getdir("rules")
        filename = ruledir + name + ".rule"

        results = "@RULE " + name + "\n\n"
        results += "*** File autogenerated by saverule. ***\n\n"
        results += comments
        results += "\n\n@TABLE\n\n"
        results += table
        results += "\n\n@COLORS\n\n"
        results += colours
        results += "\n\n@ICONS\n\n"
        results += icons

        # Original script only created a rule file if it doesn't already exist
        # This version overwrites old rules with new ones, with no warning.
        try:
            f = open(filename, 'w')
            f.write(results)
            f.close()
        except:
             g.warn("Unable to create rule table:\n" + filename)

    # Defines a variable:
    def newvar(self, name, vallist):

        line = "var "+name+"={"
        for i in xrange(len(vallist)):
            if (i > 0):
                line += ','
            line += str(vallist[i])
        line += "}\n"

        return line

    # Defines a block of equivalent variables:
    def newvars(self, namelist, vallist):

        block = "\n"

        for name in namelist:
            block += self.newvar(name, vallist)

        return block

    def scoline(self, chara, charb, left, right, amount):

        line = str(left) + ","

        for i in xrange(8):
            if (i < amount):
                line += chara
            else:
                line += charb
            line += chr(97 + i)
            line += ","

        line += str(right) + "\n"

        return line

    def isotropicline(self, chara, charb, left, right, n):

        line = str(left) + ","
        neighbours = self.notationdict[n]
        
        for i in xrange(8):
            if neighbours[i]:
                line += chara
            else:
                line += charb
            line += chr(97 + i)
            line += ","

        line += str(right) + "\n"

        return line
        
    def saveIsotropicRule(self):
    
        comments = """
This is a two state, isotropic, non-totalistic rule on the Moore neighbourhood.
The notation used to define the rule was originally proposed by Alan Hensel.
See http://www.ibiblio.org/lifepatterns/neighbors2.html for details
"""

        table = """
n_states:3
neighborhood:Moore
symmetries:rotate4reflect
"""

        table += self.newvars(["a","b","c","d","e","f","g","h"], [0, 1, 2])
        table += self.newvars(["off","i","j","k","l","m","n","p","q","r"], [0, 2])
        
        table += "\n# Birth\n"
        for n in self.allneighbours_flat:
            if self.bee[n]:
                table += "off,"
                table += self.notationdict2[n]
                table += ",1\n"
        
        table += "\n# Survival\n"
        for n in self.allneighbours_flat:
            if self.ess[n]:
                table += "1,"
                table += self.notationdict2[n]
                table += ",1\n"

        table += "\n# Death\n"
        table += self.scoline("","",1,2,0)
        
        colours = """1 255 255   255
2   255 255   55
3   0   0 0
4   200 255 200
5 100 75 75
6 75 75 75
"""
        icons = """@ICONS

XPM
/* width height num_colors chars_per_pixel */
"31 186 5 1"
/* colors */
". c #000000"
"B c #404040"
"C c #808080"
"D c #C0C0C0"
"E c #FFFFFF"
/* icon for state 1 */
"..............................."
"..............................."
"..........BCDEEEEEDCB.........."
".........CEEEEEEEEEEEC........."
".......BEEEEEEEEEEEEEEEB......."
"......DEEEEEEEEEEEEEEEEED......"
".....DEEEEEEEEEEEEEEEEEEED....."
"....BEEEEEEEEEEEEEEEEEEEEEB...."
"....EEEEEEEEEEEEEEEEEEEEEEE...."
"...CEEEEEEEEEEEEEEEEEEEEEEEC..."
"..BEEEEEEEEEEEEEEEEEEEEEEEEEB.."
"..CEEEEEEEEEEEEEEEEEEEEEEEEEC.."
"..DEEEEEEEEEEEEEEEEEEEEEEEEED.."
"..EEEEEEEEEEEEEEEEEEEEEEEEEEE.."
"..EEEEEEEEEEEEEEEEEEEEEEEEEEE.."
"..EEEEEEEEEEEEEEEEEEEEEEEEEEE.."
"..EEEEEEEEEEEEEEEEEEEEEEEEEEE.."
"..EEEEEEEEEEEEEEEEEEEEEEEEEEE.."
"..DEEEEEEEEEEEEEEEEEEEEEEEEED.."
"..CEEEEEEEEEEEEEEEEEEEEEEEEEC.."
"..BEEEEEEEEEEEEEEEEEEEEEEEEEB.."
"...CEEEEEEEEEEEEEEEEEEEEEEEC..."
"....EEEEEEEEEEEEEEEEEEEEEEE...."
"....BEEEEEEEEEEEEEEEEEEEEEB...."
".....DEEEEEEEEEEEEEEEEEEED....."
"......DEEEEEEEEEEEEEEEEED......"
".......BEEEEEEEEEEEEEEEB......."
".........CEEEEEEEEEEEC........."
"..........BCDEEEEEDCB.........."
"..............................."
"..............................."
/* icon for state 2 */
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
/* icon for state 3 */
"..............................."
"..............................."
"..........BCDEEEEEDCB.........."
".........CEEEEEEEEEEEC........."
".......BEEEEEEEEEEEEEEEB......."
"......DEEEEEEEEEEEEEEEEED......"
".....DEEEEEEEEEEEEEEEEEEED....."
"....BEEEEEEEEEEEEEEEEEEEEEB...."
"....EEEEEEEEEEEEEEEEEEEEEEE...."
"...CEEEEEEEEEEEEEEEEEEEEEEEC..."
"..BEEEEEEEEEEEEEEEEEEEEEEEEEB.."
"..CEEEEEEEEEEEEEEEEEEEEEEEEEC.."
"..DEEEEEEEEEEEEEEEEEEEEEEEEED.."
"..EEEEEEEEEEEEEEEEEEEEEEEEEEE.."
"..EEEEEEEEEEEEEEEEEEEEEEEEEEE.."
"..EEEEEEEEEEEEEEEEEEEEEEEEEEE.."
"..EEEEEEEEEEEEEEEEEEEEEEEEEEE.."
"..EEEEEEEEEEEEEEEEEEEEEEEEEEE.."
"..DEEEEEEEEEEEEEEEEEEEEEEEEED.."
"..CEEEEEEEEEEEEEEEEEEEEEEEEEC.."
"..BEEEEEEEEEEEEEEEEEEEEEEEEEB.."
"...CEEEEEEEEEEEEEEEEEEEEEEEC..."
"....EEEEEEEEEEEEEEEEEEEEEEE...."
"....BEEEEEEEEEEEEEEEEEEEEEB...."
".....DEEEEEEEEEEEEEEEEEEED....."
"......DEEEEEEEEEEEEEEEEED......"
".......BEEEEEEEEEEEEEEEB......."
".........CEEEEEEEEEEEC........."
"..........BCDEEEEEDCB.........."
"..............................."
"..............................."
/* icon for state 4 */
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
/* icon for state 5 */
"..............................."
"..............................."
"..........BCDEEEEEDCB.........."
".........CEEEEEEEEEEEC........."
".......BEEEEEEEEEEEEEEEB......."
"......DEEEEEEEEEEEEEEEEED......"
".....DEEEEEEEEEEEEEEEEEEED....."
"....BEEEEEEEEEEEEEEEEEEEEEB...."
"....EEEEEEEEEEEEEEEEEEEEEEE...."
"...CEEEEEEEEEEEEEEEEEEEEEEEC..."
"..BEEEEEEEEEEEEEEEEEEEEEEEEEB.."
"..CEEEEEEEEEEEEEEEEEEEEEEEEEC.."
"..DEEEEEEEEEEEEEEEEEEEEEEEEED.."
"..EEEEEEEEEEEEEEEEEEEEEEEEEEE.."
"..EEEEEEEEEEEEEEEEEEEEEEEEEEE.."
"..EEEEEEEEEEEEEEEEEEEEEEEEEEE.."
"..EEEEEEEEEEEEEEEEEEEEEEEEEEE.."
"..EEEEEEEEEEEEEEEEEEEEEEEEEEE.."
"..DEEEEEEEEEEEEEEEEEEEEEEEEED.."
"..CEEEEEEEEEEEEEEEEEEEEEEEEEC.."
"..BEEEEEEEEEEEEEEEEEEEEEEEEEB.."
"...CEEEEEEEEEEEEEEEEEEEEEEEC..."
"....EEEEEEEEEEEEEEEEEEEEEEE...."
"....BEEEEEEEEEEEEEEEEEEEEEB...."
".....DEEEEEEEEEEEEEEEEEEED....."
"......DEEEEEEEEEEEEEEEEED......"
".......BEEEEEEEEEEEEEEEB......."
".........CEEEEEEEEEEEC........."
"..........BCDEEEEEDCB.........."
"..............................."
"..............................."
/* icon for state 6 */
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E.E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E.E.E.E.E.E.E.E.E."

XPM
/* width height num_colors chars_per_pixel */
"15 90 5 1"
/* colors */
". c #000000"
"B c #404040"
"C c #808080"
"D c #C0C0C0"
"E c #FFFFFF"
/* icon for state 1 */
"..............."
"....BDEEEDB...."
"...DEEEEEEED..."
"..DEEEEEEEEED.."
".BEEEEEEEEEEEB."
".DEEEEEEEEEEED."
".EEEEEEEEEEEEE."
".EEEEEEEEEEEEE."
".EEEEEEEEEEEEE."
".DEEEEEEEEEEED."
".BEEEEEEEEEEEB."
"..DEEEEEEEEED.."
"...DEEEEEEED..."
"....BDEEEDB...."
"..............."
/* icon for state 2 */
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
/* icon for state 3 */
"..............."
"....BDEEEDB...."
"...DEEEEEEED..."
"..DEEEEEEEEED.."
".BEEEEEEEEEEEB."
".DEEEEEEEEEEED."
".EEEEEEEEEEEEE."
".EEEEEEEEEEEEE."
".EEEEEEEEEEEEE."
".DEEEEEEEEEEED."
".BEEEEEEEEEEEB."
"..DEEEEEEEEED.."
"...DEEEEEEED..."
"....BDEEEDB...."
"..............."
/* icon for state 4 */
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
/* icon for state 5 */
"..............."
"....BDEEEDB...."
"...DEEEEEEED..."
"..DEEEEEEEEED.."
".BEEEEEEEEEEEB."
".DEEEEEEEEEEED."
".EEEEEEEEEEEEE."
".EEEEEEEEEEEEE."
".EEEEEEEEEEEEE."
".DEEEEEEEEEEED."
".BEEEEEEEEEEEB."
"..DEEEEEEEEED.."
"...DEEEEEEED..."
"....BDEEEDB...."
"..............."
/* icon for state 6 */
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"
".E.E.E.E.E.E.E."
"E.E.E.E.E.E.E.E"

XPM
/* width height num_colors chars_per_pixel */
"7 42 6 1"
/* colors */
". c #000000"
"B c #404040"
"C c #808080"
"D c #C0C0C0"
"E c #FFFFFF"
"F c #E0E0E0"
/* icon for state 1 */
".BFEFB."
"BEEEEEB"
"FEEEEEF"
"EEEEEEE"
"FEEEEEF"
"BEEEEEB"
".BFEFB."
/* icon for state 2 */
".E.E.E."
"E.E.E.E"
".E.E.E."
"E.E.E.E"
".E.E.E."
"E.E.E.E"
".E.E.E."
/* icon for state 3 */
".BFEFB."
"BEEEEEB"
"FEEEEEF"
"EEEEEEE"
"FEEEEEF"
"BEEEEEB"
".BFEFB."
/* icon for state 4 */
"E.E.E.E"
".E.E.E."
"E.E.E.E"
".E.E.E."
"E.E.E.E"
".E.E.E."
"E.E.E.E"
/* icon for state 5 */
".BFEFB."
"BEEEEEB"
"FEEEEEF"
"EEEEEEE"
"FEEEEEF"
"BEEEEEB"
".BFEFB."
/* icon for state 6 */
"E.E.E.E"
".E.E.E."
"E.E.E.E"
".E.E.E."
"E.E.E.E"
".E.E.E."
"E.E.E.E"
"""
        self.saverule(self.rulename, comments, table, colours, icons)

rulestring = g.getstring("To make a History rule, enter rule string in Alan Hensel's isotropic rule notation", 
                         "B2-a/S12")

rg = RuleGenerator()

rg.setrule(rulestring)
rg.saveIsotropicRule()
g.setrule(rg.rulename)

g.show("Created rule in file: " + rg.rulename + ".rule")
Gustone wrote:... makes a history of the current rule (in any rules folder) and sets the rule to it
I'm not clear what you mean by this. It's a highly nontrivial problem to analyze the current rule, which might be a multistate rule-table rule already, and make a history version of it. So the above script only works on standard isotropic two-state rules that are not saved in any rules folder, they're just supported natively.

Code: Select all

3. history to normal script (does not save the rule)
One way to do this would be to adapt toChangeState.lua, which is checked in to Golly's codebase and should be available in Golly 3.3 unless someone finds major problems with it:

Code: Select all

-- toChangeState.lua
--   adapted in August 2019 from change-state.py by Andrew Trevorrow,
--   and toChangeColors.py by Dave Greene
-- Switch all cells of a clicked-on color in the selected pattern to the current brush color

local g = golly()
local gp = require "gplus"
local split = gp.split
local oldsecs
local newsecs
local oldeditbar = g.setoption("showeditbar",1)

local function savestate(filename, state)
    local f = io.open(filename, "w")
    if f then
        f:write(state)
        f:close()
    else
        g.warn("Can't save target state in filename:\n"..filename)
    end
end

local ChangeStateINIFileName = g.getdir("data").."changestate.ini"
local targetstate = "0"
local f = io.open(ChangeStateINIFileName, "r")
if f then
    targetstate = f:read("*l") or ""
    f:close()
end
if targetstate==nil then
    targetstate = "0"
    savestate(ChangeStateINIFileName, targetstate)
end

limits = "selection"
seltype = " selected"
r = g.getselrect()
if #r==0 then
    limits = "pattern's bounding box"
    seltype = ""
    r = g.getrect()
    if #r==0 then
        g.exit("No pattern to change.")
    end
end

-- set fill limits to the chosen rectangle
minx, miny, sizex, sizey = table.unpack(r)
maxx = minx + sizex - 1
maxy = miny + sizey - 1

area = g.getcells(r)
if g.numstates() == 2 then
    g.exit("Rule must be multistate.  Use 'Clear' editing tools and invert.lua for cell changes in two-state patterns.")
end

saveoldstate = g.setoption("drawingstate",targetstate)
newstate = targetstate
oldstate = newstate

-- wait for user to click a cell
g.show("Click a cell to change all" .. seltype .. " cells of that type to target state "..newstate.. 
       ". Change drawing state on Edit toolbar to adjust target state. Esc to cancel.")
while true do
    event = g.getevent()
    -- user may change drawing state at any time
    newstate = g.getoption("drawingstate")
    if newstate ~= oldstate then
        g.show("Click a cell to change all" .. seltype .. " cells of that type to target state "..newstate.. 
               ". Change drawing state on Edit toolbar to adjust target state. Esc to cancel.")
        oldstate = newstate
        savestate(ChangeStateINIFileName, newstate)
    end
 
    if event:sub(1,5)==("click") then
        -- event is a string like "click 10 20 left none"
        evt, xstr, ystr, button, mods = split(event)
        x = tonumber(xstr)
        y = tonumber(ystr)
        if x < minx or x > maxx or y < miny or y > maxy then
            g.warn("Click inside the "..limits..".  To change the region affected by the script, hit Esc to cancel, then adjust the selection.")
        else
            oldstate = g.getcell(x, y)
            if oldstate == newstate then
                g.warn("The clicked cell must have a different state\n"
                      .."from the current drawing state, "..newstate..".")
            else
                break
            end
        end
    else
        g.doevent(event)
    end
end
 
-- tell Golly to handle all further keyboard/mouse events
g.getevent(false)

if oldstate == 0 then
    -- special handling for state-0 cells, which don't show up in cell lists
    --   so they must be tested individually by scanning the entire bounding box
    changed = 0
    total = sizex * sizey
    oldsecs = os.clock()
    for row = miny, maxy do
        -- might be large pattern so show percentage done each second
        newsecs = os.clock()
        if newsecs - oldsecs >= 1.0 then
            oldsecs = newsecs
            g.show("Changing cell states: "..string.format("%.1f", 100 * (row - miny) * sizex / total).."%")
            g.update()
        end
        -- allow keyboard interaction
        g.doevent( g.getevent() )
     
        for col = minx, maxx do
            if g.getcell(col, row) == oldstate then
                g.setcell(col, row, newstate)
            end
            changed = changed + 1
        end
    end
    g.show("Changed "..changed.." state "..oldstate.." cells to state "..newstate..".")
else
    -- faster handling for changing nonzero states to another state (including zero)
    oldsecs = os.clock()
    numcellsx3 = #area
    count = 0
    for i=1, numcellsx3-2, 3 do
        -- might be large pattern so show percentage done each second
        newsecs = os.clock()
        if newsecs - oldsecs >= 1.0 then
            oldsecs = newsecs
            g.show("Changing cell states: "..string.format("%.1f",100 * i / numcellsx3).."%")
            g.update()
        end
        -- allow keyboard interaction
        g.doevent( g.getevent() )
        
        if area[i+2]==oldstate then
            g.setcell(area[i],area[i+1],newstate)
            count = count + 1
        end
    end
    g.show("Changed "..count.." state "..oldstate.." cells to state "..newstate..".")
end

-- return to previous Edit Bar setting
g.setoption("showeditbar", oldeditbar)
If you use this unmodified, there's a two-step manual process to get rid of the history cells. First run toChangeState.lua and change all state 2 cells to state 0, then go to Control > Set Rule and remove the suffix "History" from the rule name.

If that seems like too much work, it's easy to make a customized toChangeState2to0.lua that always works on the entire pattern and not the selection, and then add a line or two to do the rule change.

This won't be particularly quick for huge patterns with lots of history cells, though. If speed is an issue, the script to adapt would be simsim314's LifeHistory2Life.py. That writes a state-changing rule table, but it doesn't leave the pattern set to that rule, so I'm again not clear if that would be a problem with the mysterious "(does not save the rule)" part of your request.

User avatar
Gustone
Posts: 744
Joined: March 6th, 2019, 2:26 am

Re: Script request thread

Post by Gustone » September 9th, 2019, 3:08 pm

dvgrn wrote:Why yellow for state 2?
My The Custom Color Palette!
dvgrn wrote:
Gustone wrote:... makes a history of the current rule (in any rules folder) and sets the rule to it
I'm not clear what you mean by this. It's a highly nontrivial problem to analyze the current rule, which might be a multistate rule-table rule already, and make a history version of it. So the above script only works on standard isotropic two-state rules that are not saved in any rules folder, they're just supported natively.
Well if this supports any hensel 2 state rule I'm good
dvgrn wrote:3. history to normal script (does not save the rule)
One way to do this would be to adapt toChangeState.lua
Well it might look for the rule currently set and if it is a hensel 2 state rule just remove the "history" from the name , replace cell states and set algorithm to quicklife?

User avatar
rowett
Moderator
Posts: 3777
Joined: January 31st, 2013, 2:34 am
Location: UK
Contact:

Re: Script request thread

Post by rowett » September 9th, 2019, 3:34 pm

Gustone wrote:Well it might look for the rule currently set and if it is a hensel 2 state rule just remove the "history" from the name , replace cell states and set algorithm to quicklife?
On a related note if you have an [R]History rule in LifeViewer and want to copy it to the clipboard as just [R] do the following:
  • Alt-H (hides states 3-6)
  • Ctrl-C (copies to the clipboard as 2-state rule [R])
  • Alt-J (shows states 3-6)
Now you can paste into Golly.

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

Re: Script request thread

Post by dvgrn » September 10th, 2019, 8:05 am

On the Basic Questions thread, testitemqlstudop wrote:
dvgrn wrote:
testitemqlstudop wrote:How do I make a History rule of a non-totalistic rule, like the ones displayed in LV (B2c3aei4ajnr5acn/S2-ci3-ck4in5jkq6c7cHistory)
Version 1.0 of a History-rule-making script is checked in at isotropic-history-rule-gen.py.
Can I have one that also includes the standard LifeHistory red cells?
I've checked in Version 1.0 of isotropic-markedhistory-rule-gen.py.

I only tried it on Just Friends, B3/S23, and a random strobing rule (where it had the expected horrible population-exploding behavior, but it does seem to work if you really just want to see strobing behavior for a few generations).

If anyone wants to give the script a more thorough trial run, please let me know if any bad behavior shows up. This script uses the same rule name as the previous isotropic-history-rule-gen.py script, just appending "History" to the isotropic rule name. But now the number of states has been bumped up to 7, and the generated rules support all the same marked-ON, marked-OFF, yellow marked-ON, and gray boundary cells as LifeHistory does.

I'll leave it to someone else to make the minor adjustments needed to create isotropic ExtendedLife equivalent rule tables instead. I've named the rule variables appropriately, like "on" and "off" and "markedon" and so forth instead of mysterious single letters a, b, c, d, etc. Hopefully that will make this script a little easier to modify.

I highly recommend looking at some of the generated rules long enough to understand rule table format in detail. For different combinations of cell states and neighbor cells, just read down the list of rule lines to find the line that will match in each case. Multiple lines might match -- there are often "catch-all" lines at the bottom of the list, like the "Death" lines here. Golly will choose the first matching transition that it finds and ignore the rest.

User avatar
muzik
Posts: 5614
Joined: January 28th, 2016, 2:47 pm
Location: Scotland

Re: Script request thread

Post by muzik » September 13th, 2019, 8:55 am

Can someone make a script that converts any range-1 von Neumann rule into an equivalent range-1 isotropic non-totalistic Moore rule rotated by 45 degrees, such that two "universes" can exist on checkerboards of different parity?

Such that, for example, this:

Code: Select all

x = 1, y = 1, rule = B13/S024V
o!
becomes this:

Code: Select all

x = 1, y = 1, rule = B1c2ak3acjkr4jnry5acjkr6ak7c/S01e2-ak3einqy4-jnry5einqy6-ak7e8
o!

Code: Select all

x = 44, y = 42, rule = B1c2ak3acjkr4jnry5acjkr6ak7c/S01e2-ak3einqy4-jnry5einqy6-ak7e8
9bo$2bo$bo$o$3bobo3bo$6bo$5bobobo21$41bobo2$43bo4$41bobo$40bobo$39bobo
2$41bo2$41bobo2$43bo!
Last edited by muzik on September 13th, 2019, 10:12 am, edited 1 time in total.

User avatar
testitemqlstudop
Posts: 1367
Joined: July 21st, 2016, 11:45 am
Location: in catagolue
Contact:

Re: Script request thread

Post by testitemqlstudop » September 13th, 2019, 9:09 am

* rotated by 45 degrees

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

Re: Script request thread

Post by dvgrn » September 13th, 2019, 9:47 am

muzik wrote:Can someone make a script that converts any range-1 von Neumann rule into an equivalent range-1 isotropic non-totalistic Moore rule rotated by 90 degrees, such that two "universes" can exist on checkerboards of different parity?
This seems to be just a matter of concatenating a bunch of isotropic bits for each bit in the von Neumann rulestring. Can you double-check the table below, and correct it if I've made mistakes? It should be just the von Neumann bit as applied to only the corner cells, plus zero to four optional ON neighbors in the four cardinal directions. It's pretty easy to read this off of the neighbors2 table, but also fairly easy to make mistakes.

Code: Select all

If you see -> Replace with
0          -> 0      ,     1e 2e 2i 3e 4e
1          -> 1c     ,     2a 2k 3a 3j 3k 3r 4j 4r 5c
2          -> 2c 2n  ,     3i 3n 3y 3q 4a 4i 4k 4q 4t 4w 4z 5i 5n 5q 5y 6c 6n
3          -> 3c     ,     4n 4y 5a 5j 5k 5r 6k 6a 7c
4          -> 4c     ,     5e 6e 6i 7e 8
EDIT: Patched table with fluffykitty's corrections -- thanks!

Once that's done, converting the actual pattern from a normal square grid to a checkerboard is just a few more lines of code.

fluffykitty
Posts: 1175
Joined: June 14th, 2014, 5:03 pm
Contact:

Re: Script request thread

Post by fluffykitty » September 13th, 2019, 1:37 pm

Your table does not include 3->5k or 4->8.

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

Re: Script request thread

Post by dvgrn » September 13th, 2019, 2:08 pm

fluffykitty wrote:Your table does not include 3->5k or 4->8.
Thanks! Okay, that was the hard part. This code seems to work:

Code: Select all

# make-diagonal-vN.py

import golly as g

relevantisotropicbits=dict()
relevantisotropicbits["0"] = "01e2e2i3e4e"
relevantisotropicbits["1"] = "1c2a2k3a3j3k3r4j4r5c"
relevantisotropicbits["2"] = "2c2n3i3n3q3y4a4i4k4q4t4w4z5i5n5q5y6c6n"
relevantisotropicbits["3"] = "3c4n4y5a5j5k5r6k6a7c"
relevantisotropicbits["4"] = "4c5e6e6i7e8"

r = g.getrule()
if r[-1:] != "V":
   g.note("Sorry, this script only works on patterns using rules with the von Neumann neighborhood.")
   g.exit()

b, s = r[:-1].split("/")
out = "B"
for bbit in b[1:]: out += relevantisotropicbits[bbit]
out += "/S"
for sbit in s[1:]: out += relevantisotropicbits[sbit]

cells = g.getcells(g.getrect())
g.select(g.getrect())
g.clear(0)
g.select([])
for i in range(0,len(cells)-1,2):
  x, y = cells[i],cells[i+1]
  g.setcell(x+y,y-x,1)

g.setrule(out)
Ported to Lua:

Code: Select all

-- make-diagonal-vN.lua

local g = golly()
local gp    = require "gplus"
local split = gp.split

relevantisotropicbits = {}
relevantisotropicbits["0"]="01e2e2i3e4e"
relevantisotropicbits["1"]="1c2a2k3a3j3k3r4j4r5c"
relevantisotropicbits["2"]="2c2n3i3n3q3y4a4i4k4q4t4w4z5i5n5q5y6c6n"
relevantisotropicbits["3"]="3c4n4y5a5j5k5r6k6a7c"
relevantisotropicbits["4"]="4c5e6e6i7e8"

r = g.getrule()
if string.sub(r,#r) ~= "V" then
   g.note("Sorry, this script only works on patterns using rules with the von Neumann neighborhood.")
   g.exit()
end

b, s = split(string.sub(r,1,#r-1),"/")
out = "B"
for bbit = 2, #b do
  out = out..relevantisotropicbits[string.sub(b,bbit,bbit)]
end
out = out.."/S"
for sbit = 2, #s do
  out = out..relevantisotropicbits[string.sub(s,sbit,sbit)]
end

cells = g.getcells(g.getrect())
g.select(g.getrect())
g.clear(0)
g.select({})
for i = 1,#cells-1,2 do
  x = cells[i]
  y = cells[i+1]
  g.setcell(x+y,y-x,1)
end
g.setrule(out)

User avatar
muzik
Posts: 5614
Joined: January 28th, 2016, 2:47 pm
Location: Scotland

Re: Script request thread

Post by muzik » September 17th, 2019, 3:40 am

Brilliant.

...however, now the question arises, could a similar such script be made that converts a range-1 Moore isotropic rule into an equivalent range 2 von Neumann rule using this sort of neighbourhood?

Code: Select all

x = 12, y = 5, rule = bs012345678
9bo$3o5bobo$3o4bobobo$3o5bobo$9bo!
Using Feb 24 notation, since it seems to be the agreed on notation for the rulespace.

User avatar
muzik
Posts: 5614
Joined: January 28th, 2016, 2:47 pm
Location: Scotland

Re: Script request thread

Post by muzik » October 19th, 2019, 9:52 am

A script to generate multistate 1D CA that wolframalpha can simulate.

Post Reply