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

Golly 3.0b1

For general discussion about Conway's Game of Life.

Golly 3.0b1

Postby Andrew » June 29th, 2017, 10:05 pm

EDIT: Golly 3.0b2 has been released so the links to version 3.0b1 have been removed.

Major changes since version 2.9b1:

- Golly has a new algorithm to support Larger than Life rules. See Help > Algorithms > Larger than Life.

- Support for MAP rules.

- Significant improvements to the overlay, including a number of new commands: ellipse, lineoption, optimize, replace, scale, target.

As always, see Help > Changes for the full list of changes.
User avatar
Andrew
Moderator
 
Posts: 629
Joined: June 2nd, 2009, 2:08 am
Location: Melbourne, Australia

Re: Golly 3.0b1

Postby gameoflifeboy » June 30th, 2017, 1:13 am

This is cool! Having never downloaded Golly 2.9 I don't know how much is really new, but I'm already loving some of the overlay features! Nice job! I'm sure it will take me quite a while to explore all of the features available.

I also like how the default file folder is now the main Golly folder, so that the sidebar includes both the patterns and scripts folders again. It was getting annoying to go into the file menu whenever I wanted to open a pattern.

I did notice a few issues, however. For one, mousing over a file in the file list in a way that causes alt text to appear seems to cause other Golly windows (like the pattern information window), if open, to hide behind the main window. Also, the descriptions for many of the Larger than Life patterns (which are super cool, and remind me of SmoothLife), seem to be taken straight from Mcell, which sometimes results in wrong descriptions of things like the colors of the cells.
Further updates if I discover more issues.

Nevertheless, this is a very exciting update and I look forward to see what new things will be discovered in Larger than Life rules!
User avatar
gameoflifeboy
 
Posts: 456
Joined: January 15th, 2015, 2:08 am
Location: New Mexico Tech

Re: Golly 3.0b1

Postby Saka » June 30th, 2017, 1:51 am

Why does LTL have to be on a torus?
Everyone, please stop posting B/S about CA
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: 2184
Joined: June 19th, 2015, 8:50 pm
Location: In the kingdom of Sultan Hamengkubuwono X

Re: Golly 3.0b1

Postby Andrew » June 30th, 2017, 4:36 am

gameoflifeboy wrote:Having never downloaded Golly 2.9 I don't know how much is really new

See Help > Changes for the list of changes since version 2.8.

I did notice a few issues, however. For one, mousing over a file in the file list in a way that causes alt text to appear seems to cause other Golly windows (like the pattern information window), if open, to hide behind the main window.

Is this on Windows? If so, which version? I don't see any such problems on my Win XP/7 systems, but I don't really know what you mean by "mousing over a file in the file list in a way that causes alt text to appear". What text exactly? Maybe post a screenshot.

Also, the descriptions for many of the Larger than Life patterns (which are super cool, and remind me of SmoothLife), seem to be taken straight from Mcell, which sometimes results in wrong descriptions of things like the colors of the cells.

Yep, I wasn't too sure what to do about some of those comments. The .mcl files were included to show that Golly can read MCell files, but I should probably convert them to .rle with updated comments.
User avatar
Andrew
Moderator
 
Posts: 629
Joined: June 2nd, 2009, 2:08 am
Location: Melbourne, Australia

Re: Golly 3.0b1

Postby Andrew » June 30th, 2017, 4:41 am

Saka wrote:Why does LTL have to be on a torus?

A bounded plane is also supported. If you're asking why the LtL algo only supports a bounded universe then the main reason is simplicity. This was my first foray into writing a new algorithm for Golly, so I wanted to keep things pretty simple, at least initially. The final 3.0 version may well allow an unbounded universe, but no promises.
User avatar
Andrew
Moderator
 
Posts: 629
Joined: June 2nd, 2009, 2:08 am
Location: Melbourne, Australia

Re: Golly 3.0b1

Postby rowett » June 30th, 2017, 4:52 am

Andrew wrote:Yep, I wasn't too sure what to do about some of those comments. The .mcl files were included to show that Golly can read MCell files, but I should probably convert them to .rle with updated comments.

Yes please do! A future build of LifeViewer may support LTL rules but it won't support .mcl format files.
rowett
Moderator
 
Posts: 725
Joined: January 31st, 2013, 2:34 am
Location: UK

Re: Golly 3.0b1

Postby Naszvadi » June 30th, 2017, 7:14 am

Please provide OSX panther/tiger/leopard powerpc versions of beta builds! I am a volunteer for testing on these platforms.

Thanks in advance!
Naszvadi
 
Posts: 185
Joined: May 7th, 2016, 8:53 am

Re: Golly 3.0b1

Postby Andrew » June 30th, 2017, 8:31 am

Naszvadi wrote:Please provide OSX panther/tiger/leopard powerpc versions of beta builds!

Sorry, but 10.6 is the oldest Mac OS I can support.
User avatar
Andrew
Moderator
 
Posts: 629
Joined: June 2nd, 2009, 2:08 am
Location: Melbourne, Australia

Re: Golly 3.0b1

Postby bprentice » June 30th, 2017, 3:26 pm

oscar.py doesn't report this knight ship correctly:

x = 11, y = 19, rule = R5,C4,M0,S83..98,B10..108,NN:T1000,1000
$4.C$5.CB$5.2CBA$5.2C2BA$5.2C2B2A$5.2C2B2A$5.2C2B2A$5.2C2B2A$4.3C2B2A
$4.2C3B2A$3.3C2B3A$2.3C3B2A$.3C3B3A$2.C3B3A$4.B3A$6.A!


I am running the Mac OS 10.6+ version of Golly 3.0b1.

Brian Prentice
bprentice
 
Posts: 407
Joined: September 10th, 2009, 6:20 pm
Location: Coos Bay, Oregon

Re: Golly 3.0b1

Postby dvgrn » June 30th, 2017, 3:30 pm

bprentice wrote:oscar.py doesn't report this knight ship correctly...

Heh, that's because when oscar.py was written, faster-than-light travel was impossible:

    # we found a moving oscillator
    if period == 1:
        g.show("Spaceship detected (speed = c)")

How times have changed, all of a sudden. Looks like a fairly simple fix.
dvgrn
Moderator
 
Posts: 3990
Joined: May 17th, 2009, 11:00 pm
Location: Madison, WI

Re: Golly 3.0b1

Postby dvgrn » June 30th, 2017, 5:24 pm

Copying in a useful question from another thread:

gameoflifeboy wrote:It seems that MAP patterns run upside-down and backwards when run in HashLife instead of QuickLife. Is this a known bug?

... "upside down and backwards" meaning that in Hashlife the neighborhoods are all reflected across the X axis, from the neighborhoods used in QuickLife. A simple example:

x = 22, y = 3, rule = MAPERYXfhZofugWaH7oaIDogBZofuhogOiAaIDogIAAgAAWaH7oaIDogGiA6ICAAIAAaIDogIAAgAAAAAAAAAAAAA
2o18b2o$bo18bo$b2o16b2o!
#C [[ AUTOFIT ]]

In the Hashlife algo, the right-hand polyplet survives instead of the left-hand one, and it moves SW instead of NW.

An even simpler example:
#C Minimal anisotropic rule where the neighbor to the northeast (only)
#C   triggers a birth, so patterns appear to move southwest.
#C Just the 64 bit is ON in the MAP bitstring
#C   -- see http://www.conwaylife.com/wiki/Rule_integer
#C 00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
x = 34, y = 22, rule = MAPAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
o9bo9bo9bo$bo9bo9bo$2bo9bo$3bo$4bo15bo$5bo13bo$6bo11bo5bo$7bo9bo5bo$8b
o7bo5bo4bo$9bo5bo5bo4bo$o13bo5bo4bo4bo$13bo15bo$33bo2$5bo8bo$4b3o$3b5o
$4b3o12b2o$5bo13b2o$27b3o$o9bo16b3o$27b3o!

The algorithm defaults to Quicklife when this pattern is opened, and the dots move southwest like they're supposed to. But if you switch to Hashlife the dots start moving northwest.
dvgrn
Moderator
 
Posts: 3990
Joined: May 17th, 2009, 11:00 pm
Location: Madison, WI

Re: Golly 3.0b1

Postby rowett » June 30th, 2017, 8:59 pm

dvgrn wrote:Copying in a useful question from another thread:

gameoflifeboy wrote:It seems that MAP patterns run upside-down and backwards when run in HashLife instead of QuickLife. Is this a known bug?

Thanks for reporting! This has been fixed.
rowett
Moderator
 
Posts: 725
Joined: January 31st, 2013, 2:34 am
Location: UK

Re: Golly 3.0b1

Postby Andrew » June 30th, 2017, 11:59 pm

bprentice wrote:oscar.py doesn't report this knight ship correctly:

Thanks -- I've now fixed this.

Here is the fixed oscar.lua:
-- Oscar is an OSCillation AnalyzeR for use with Golly.
-- Author: Andrew Trevorrow (andrew@trevorrow.com), Mar 2016.
--
-- This script uses Gabriel Nivasch's "keep minima" algorithm.
-- For each generation, calculate a hash value for the pattern.  Keep all of
-- the record-breaking minimal hashes in a list, with the oldest first.
-- For example, after 5 generations the saved hash values might be:
--
--   8 12 16 24 25,
--
-- If the next hash goes down to 13 then the list can be shortened:
--
--   8 12 13.
--
-- If the current hash matches one of the saved hashes, it is highly likely
-- the pattern is oscillating.  By keeping a corresponding list of generation
-- counts we can calculate the period.  We also keep lists of population
-- counts and bounding boxes to reduce the chance of spurious oscillator
-- detection due to hash collisions.  The bounding box info also allows us
-- to detect moving oscillators (spaceships/knightships).

local g = golly()

-- initialize lists
local hashlist = {}     -- for pattern hash values
local genlist = {}      -- corresponding generation counts
local poplist = {}      -- corresponding population counts
local boxlist = {}      -- corresponding bounding boxes

-- check if outer-totalistic rule has B0 but not S8
local r = g.getrule()
r = string.match(r, "^(.+):") or r
local hasB0notS8 = r:find("B0") == 1 and r:find("/") > 1 and r:sub(-1,-1) ~= "8"

----------------------------------------------------------------------

local function show_spaceship_speed(period, deltax, deltay)
    -- we found a moving oscillator
    if deltax == deltay or deltax == 0 or deltay == 0 then
        local speed = ""
        if deltax == 0 or deltay == 0 then
            -- orthogonal spaceship
            if deltax > 1 or deltay > 1 then
                speed = speed..(deltax + deltay)
            end
        else
            -- diagonal spaceship (deltax == deltay)
            if deltax > 1 then
                speed = speed..deltax
            end
        end
        if period == 1 then
            g.show("Spaceship detected (speed = "..speed.."c)")
        else
            g.show("Spaceship detected (speed = "..speed.."c/"..period..")")
        end
    else
        -- deltax != deltay and both > 0
        local speed = deltay..","..deltax
        if period == 1 then
            g.show("Knightship detected (speed = "..speed.."c)")
        else
            g.show("Knightship detected (speed = "..speed.."c/"..period..")")
        end
    end
end

----------------------------------------------------------------------

local function oscillating()
    -- return true if the pattern is empty, stable or oscillating
   
    -- first get current pattern's bounding box
    local pbox = g.getrect()
    if #pbox == 0 then
        g.show("The pattern is empty.")
        return true
    end
   
    local h = g.hash(pbox)
   
    -- determine where to insert h into hashlist
    local pos = 1
    local listlen = #hashlist
    while pos <= listlen do
        if h > hashlist[pos] then
            pos = pos + 1
        elseif h < hashlist[pos] then
            -- shorten lists and append info below
            for i = 1, listlen - pos + 1 do
                table.remove(hashlist)
                table.remove(genlist)
                table.remove(poplist)
                table.remove(boxlist)
            end
            break
        else
            -- h == hashlist[pos] so pattern is probably oscillating, but just in
            -- case this is a hash collision we also compare pop count and box size
            local rect = boxlist[pos]
            if tonumber(g.getpop()) == poplist[pos] and pbox[3] == rect[3] and pbox[4] == rect[4] then
                local period = tonumber(g.getgen()) - genlist[pos]
               
                if hasB0notS8 and (period % 2) > 0 and
                   pbox[1] == rect[1] and pbox[2] == rect[2] and
                   pbox[3] == rect[3] and pbox[4] == rect[4] then
                    -- ignore this hash value because B0-and-not-S8 rules are
                    -- emulated by using different rules for odd and even gens,
                    -- so it's possible to have identical patterns at gen G and
                    -- gen G+p if p is odd
                    return false
                end
               
                if pbox[1] == rect[1] and pbox[2] == rect[2] and
                   pbox[3] == rect[3] and pbox[4] == rect[4] then
                    -- pattern hasn't moved
                    if period == 1 then
                        g.show("The pattern is stable.")
                    else
                        g.show("Oscillator detected (period = "..period..")")
                    end
                else
                    local deltax = math.abs(rect[1] - pbox[1])
                    local deltay = math.abs(rect[2] - pbox[2])
                    show_spaceship_speed(period, deltax, deltay)
                end
                return true
            else
                -- look at next matching hash value or insert if no more
                pos = pos + 1
            end
        end
    end
   
    -- store hash/gen/pop/box info at same position in various lists
    table.insert(hashlist, pos, h)
    table.insert(genlist, pos, tonumber(g.getgen()))
    table.insert(poplist, pos, tonumber(g.getpop()))
    table.insert(boxlist, pos, pbox)
   
    return false
end

----------------------------------------------------------------------

local function fit_if_not_visible()
    -- fit pattern in viewport if not empty and not completely visible
    local r = g.getrect()
    if #r > 0 and not g.visrect(r) then g.fit() end
end

----------------------------------------------------------------------

g.show("Checking for oscillation... (hit escape to abort)")

local oldsecs = os.clock()
while not oscillating() do
    g.run(1)
    local newsecs = os.clock()
    if newsecs - oldsecs >= 1.0 then   -- show pattern every second
        oldsecs = newsecs
        fit_if_not_visible()
        g.update()
    end
end
fit_if_not_visible()


And for all you dinosaurs still using Python, here's the fixed oscar.py:
# Oscar is an OSCillation AnalyzeR for use with Golly.
# Author: Andrew Trevorrow (andrew@trevorrow.com), March 2006.
# Modified to handle B0-and-not-S8 rules, August 2009.

# This script uses Gabriel Nivasch's "keep minima" algorithm.
# For each generation, calculate a hash value for the pattern.  Keep all of
# the record-breaking minimal hashes in a list, with the oldest first.
# For example, after 5 generations the saved hash values might be:
#
#   8 12 16 24 25,
#
# If the next hash goes down to 13 then the list can be shortened:
#
#   8 12 13.
#
# When the current hash matches one of the saved hashes, it is highly likely
# the pattern is oscillating.  By keeping a corresponding list of generation
# counts we can calculate the period.  We also keep lists of population
# counts and bounding boxes; they are used to reduce the chance of spurious
# oscillator detection due to hash collisions.  The bounding box info also
# allows us to detect moving oscillators (spaceships/knightships).

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

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

# initialize lists
hashlist = []        # for pattern hash values
genlist = []         # corresponding generation counts
poplist = []         # corresponding population counts
boxlist = []         # corresponding bounding boxes

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

def show_spaceship_speed(period, deltax, deltay):
    # we found a moving oscillator
    if (deltax == deltay) or (deltax == 0) or (deltay == 0):
        speed = ""
        if (deltax == 0) or (deltay == 0):
            # orthogonal spaceship
            if (deltax > 1) or (deltay > 1):
                speed += str(deltax + deltay)
        else:
            # diagonal spaceship (deltax == deltay)
            if deltax > 1:
                speed += str(deltax)
        if period == 1:
            g.show("Spaceship detected (speed = " + speed + "c)")
        else:
            g.show("Spaceship detected (speed = " + speed + "c/" +str(period) + ")")
    else:
        # deltax != deltay and both > 0
        speed = str(deltay) + "," + str(deltax)
        if period == 1:
            g.show("Knightship detected (speed = " + speed + "c)")
        else:
            g.show("Knightship detected (speed = " + speed + "c/" + str(period) + ")")

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

def oscillating():
    # return True if the pattern is empty, stable or oscillating

    # first get current pattern's bounding box
    prect = g.getrect()
    pbox = rect(prect)
    if pbox.empty:
        g.show("The pattern is empty.")
        return True

    # get current pattern and create hash of "normalized" version -- ie. shift
    # its top left corner to 0,0 -- so we can detect spaceships and knightships
    ## currpatt = pattern( g.getcells(prect) )
    ## h = hash( tuple( currpatt(-pbox.left, -pbox.top) ) )

    # use Golly's hash command (3 times faster than above code)
    h = g.hash(prect)

    # check if outer-totalistic rule has B0 but not S8
    rule = g.getrule().split(":")[0]
    hasB0notS8 = rule.startswith("B0") and (rule.find("/") > 1) and not rule.endswith("8")

    # determine where to insert h into hashlist
    pos = 0
    listlen = len(hashlist)
    while pos < listlen:
        if h > hashlist[pos]:
            pos += 1
        elif h < hashlist[pos]:
            # shorten lists and append info below
            del hashlist[pos : listlen]
            del genlist[pos : listlen]
            del poplist[pos : listlen]
            del boxlist[pos : listlen]
            break
        else:
            # h == hashlist[pos] so pattern is probably oscillating, but just in
            # case this is a hash collision we also compare pop count and box size
            if (int(g.getpop()) == poplist[pos]) and \
               (pbox.wd == boxlist[pos].wd) and \
               (pbox.ht == boxlist[pos].ht):
                period = int(g.getgen()) - genlist[pos]

                if hasB0notS8 and (period % 2 > 0) and (pbox == boxlist[pos]):
                    # ignore this hash value because B0-and-not-S8 rules are
                    # emulated by using different rules for odd and even gens,
                    # so it's possible to have identical patterns at gen G and
                    # gen G+p if p is odd
                    return False

                if pbox == boxlist[pos]:
                    # pattern hasn't moved
                    if period == 1:
                        g.show("The pattern is stable.")
                    else:
                        g.show("Oscillator detected (period = " + str(period) + ")")
                else:
                    deltax = abs(boxlist[pos].x - pbox.x)
                    deltay = abs(boxlist[pos].y - pbox.y)
                    show_spaceship_speed(period, deltax, deltay)
                return True
            else:
                # look at next matching hash value or insert if no more
                pos += 1

    # store hash/gen/pop/box info at same position in various lists
    hashlist.insert(pos, h)
    genlist.insert(pos, int(g.getgen()))
    poplist.insert(pos, int(g.getpop()))
    boxlist.insert(pos, pbox)

    return False

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

def fit_if_not_visible():
    # fit pattern in viewport if not empty and not completely visible
    r = rect(g.getrect())
    if (not r.empty) and (not r.visible()): g.fit()

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

g.show("Checking for oscillation... (hit escape to abort)")

oldsecs = time()
while not oscillating():
    g.run(1)
    newsecs = time()
    if newsecs - oldsecs >= 1.0:     # show pattern every second
        oldsecs = newsecs
        fit_if_not_visible()
        g.update()

fit_if_not_visible()

Let me know if there are still any problems with those scripts.
User avatar
Andrew
Moderator
 
Posts: 629
Joined: June 2nd, 2009, 2:08 am
Location: Melbourne, Australia

Re: Golly 3.0b1

Postby bprentice » July 1st, 2017, 4:57 pm

Please consider adding Cross, Saltire and Star neighborhoods to the Square and Diamond neighborhoods that are currently implemented in your 'Larger than Life' family of rules.

Brian Prentice
bprentice
 
Posts: 407
Joined: September 10th, 2009, 6:20 pm
Location: Coos Bay, Oregon

Re: Golly 3.0b1

Postby dvgrn » July 1st, 2017, 5:33 pm

bprentice wrote:Please consider adding Cross, Saltire and Star neighborhoods to the Square and Diamond neighborhoods that are currently implemented in your 'Larger than Life' family of rules.

Cross is the orthogonal "+" pattern that Andrew originally implemented, correct? And Saltire would be a diagonal "x", and Star would be Cross and Saltire superimposed? Is there any prior art for Larger than Life patterns with these extended neighborhoods?

If so, is there any standard for the "N" suffix used in the rule strng? "NN" for von Neumann, "NM" for Moore -- so presumably "NC" for cross, but the other two words both start with S. Maybe "NS" for Star, and then "NX" for the saltire?
dvgrn
Moderator
 
Posts: 3990
Joined: May 17th, 2009, 11:00 pm
Location: Madison, WI

Re: Golly 3.0b1

Postby bprentice » July 1st, 2017, 6:56 pm

dvgrn wrote:Cross is the orthogonal "+" pattern that Andrew originally implemented, correct? And Saltire would be a diagonal "x", and Star would be Cross and Saltire superimposed?


Yes.

dvgrn wrote:Is there any prior art for Larger than Life patterns with these extended neighborhoods?


Not that I am aware of. Square Cell implements all five neighborhood types. I have not found many interesting rules using the Cross, Saltire or Star neighborhoods, but finding interesting rules using the Square and Diamond neighborhoods is also difficult. Since we have just started experimenting with 'Larger than Life' using Golly, I was curious to see what the active members of the Forum find. For example in just a few hours of the 3.0b1 release of Golly drc posted this beauty.

viewtopic.php?f=11&t=2933#p45539

Some of the pictures posted here:

viewtopic.php?f=12&t=2853#p43283

use the Cross, Saltire or Star neighborhoods and each of them exhibits unique characteristics.

dvgrn wrote:...is there any standard for the "N" suffix used in the rule strng? "NN" for von Neumann, "NM" for Moore -- so presumably "NC" for cross, but the other two words both start with S. Maybe "NS" for Star, and then "NX" for the saltire?


No, your suggestion would work.

Brian Prentice
bprentice
 
Posts: 407
Joined: September 10th, 2009, 6:20 pm
Location: Coos Bay, Oregon

Re: Golly 3.0b1

Postby drc » July 1st, 2017, 7:40 pm

What if we have rule tables with custom neighbourhoods? For example if I wanted this neighbourhood, I could specify it per:
@RULE JackLife
Life simulated using a 16-cell neighbourhood seen below.
@NEIGHBORHOOD
X.X.X
.XXX
XXOXX
.XXX
X.X.X
@TABLE
n_states:2
symmetries: rotate4reflect
neighborhood:custom

X=Active cell
.=Passive cell
O=Center cell

Then, the transitions would be specified by going through each cell in each row, left-right, then advancing to the next row. Or maybe it could be customly specified like so?:
@NEIGHBORHOOD
1.2.3
.456.
78O9A
.BCD.
E.F.G

That would have the downside of only allowing 36 neighbours unless symbols get involved. I dunno, maybe they could be optional.
This post was brought to you by the letter D, for dishes that Andrew J. Wade won't do. (Also Daniel, which happens to be me.)
Current rule interest: B2ce3-ir4a5y/S2-c3-y
User avatar
drc
 
Posts: 1665
Joined: December 3rd, 2015, 4:11 pm
Location: creating useless things in OCA

Re: Golly 3.0b1

Postby AforAmpere » July 1st, 2017, 8:18 pm

I wan't to have a format for LtL rule tables, even just to do neighborhood 2, because then I can do stuff like create a true LogicLand ruletable, because the actual thing uses neighborhood 2 for a crossover. Some other things only possible in neighborhood 2 rules would be able to be done, and it would be really cool.

The neighborhood 2 table could be like this:
23 24  9 10 11
22 8   1  2 12
21 7      3 13
20 6   5  4 14
19 18 17 16 15

And obviously after neighborhood 2, it would become even more insanely complicated, but it would really be able to show the variety of these rules, and just neighborhood 2 has some cool applications.
Things to work on:
- An Isotropic version of All_Speeds
- Find more ships in B2ek3-ajny4ajqr5a/S02ack3ackny4aq5y
- Find a (3,1)c/5 ship in a Non-totalistic rule (someone please search the rules)
AforAmpere
 
Posts: 267
Joined: July 1st, 2016, 3:58 pm

Re: Golly 3.0b1

Postby Saka » July 1st, 2017, 8:21 pm

drc wrote:What if we have rule tables with custom neighbourhoods? For example if I wanted this neighbourhood, I could specify it per:
@RULE JackLife
Life simulated using a 16-cell neighbourhood seen below.
@NEIGHBORHOOD
X.X.X
.XXX
XXOXX
.XXX
X.X.X
@TABLE
n_states:2
symmetries: rotate4reflect
neighborhood:custom

X=Active cell
.=Passive cell
O=Center cell

Then, the transitions would be specified by going through each cell in each row, left-right, then advancing to the next row. Or maybe it could be customly specified like so?:
@NEIGHBORHOOD
1.2.3
.456.
78O9A
.BCD.
E.F.G

That would have the downside of only allowing 36 neighbours unless symbols get involved. I dunno, maybe they could be optional.
I have designed some neighborhood formats. Just have to find them...
Everyone, please stop posting B/S about CA
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: 2184
Joined: June 19th, 2015, 8:50 pm
Location: In the kingdom of Sultan Hamengkubuwono X

Re: Golly 3.0b1

Postby Andrew » July 1st, 2017, 10:13 pm

bprentice wrote:Please consider adding Cross, Saltire and Star neighborhoods to the Square and Diamond neighborhoods that are currently implemented in your 'Larger than Life' family of rules.

I'd have to say I'm unlikely to write the necessary code. Any chance you'd be willing to write it? Note that you could write and test it by building bgolly rather than Golly, so no need to install and build wxWidgets.

If you download Golly's current git repository from sourceforge the only changes needed are to ltlalgo.cpp in the gollybase folder. In that file we currently have these routines:

slow_torus_Moore
slow_torus_Neumann
slow_plane_Moore
slow_plane_Neumann
fast_Moore
fast_Neumann

So these new routines will be needed:

slow_torus_Cross
slow_torus_Saltire
slow_torus_Star
slow_plane_Cross
slow_plane_Saltire
slow_plane_Star
fast_Cross
fast_Saltire
fast_Star

The slow* routines are used to process rectangles near the grid edges. The fast* routines are used to process inner rectangles where no edge checking is needed.

Building bgolly is easy. Open Terminal.app, cd to golly/gui-wx, then run "make -f makefile-mac bgolly".

Email me if you need more details.
User avatar
Andrew
Moderator
 
Posts: 629
Joined: June 2nd, 2009, 2:08 am
Location: Melbourne, Australia

Re: Golly 3.0b1

Postby bprentice » July 1st, 2017, 11:13 pm

Andrew,

Here is the Square Cell step code for all five neighborhoods:

  public int step(int row, int column, byte[][] cells, int rows, int columns)
  {
    int cell = cells[row][column];
    int neighborCount = 0;
    if (neighborhoodType == SQUARE)
    {
      if (((row - neighborhoodSize) >= 0) && ((row + neighborhoodSize) < rows) &&
          ((column - neighborhoodSize) >= 0) && ((column + neighborhoodSize) < columns))
      {
        for (int r = row - neighborhoodSize; r <= row + neighborhoodSize; r++)
          for (int c = column - neighborhoodSize; c <= column + neighborhoodSize; c++)
            if (cells[r][c] == 1)
              neighborCount++;
      }
      else
      {
        for (int r = row - neighborhoodSize; r <= row + neighborhoodSize; r++)
          for (int c = column - neighborhoodSize; c <= column + neighborhoodSize; c++)
            if (cells[(r + rows) % rows][(c + columns) % columns] == 1)
              neighborCount++;
      }
      if ((! includeCenter) && (cell == 1))
        neighborCount--;
    }
    else if (neighborhoodType == CROSS)
    {
      for (int i = 1; i <= neighborhoodSize; i++)
      {
        if (cells[(row + rows) % rows][(column - i + columns) % columns] == 1)
          neighborCount++;
        if (cells[(row + rows) % rows][(column + i + columns) % columns] == 1)
          neighborCount++;
        if (cells[(row - i + rows) % rows][(column + columns) % columns] == 1)
          neighborCount++;
        if (cells[(row + i + rows) % rows][(column + columns) % columns] == 1)
          neighborCount++;
      }
      if (includeCenter && (cell == 1))
        neighborCount++;
    }
    else if (neighborhoodType == SALTIRE)
    {
      for (int i = 1; i <= neighborhoodSize; i++)
      {
        if (cells[(row - i + rows) % rows][(column - i + columns) % columns] == 1)
          neighborCount++;
        if (cells[(row - i + rows) % rows][(column + i + columns) % columns] == 1)
          neighborCount++;
        if (cells[(row + i + rows) % rows][(column - i + columns) % columns] == 1)
          neighborCount++;
        if (cells[(row + i + rows) % rows][(column + i + columns) % columns] == 1)
          neighborCount++;
      }
      if (includeCenter && (cell == 1))
        neighborCount++;
    }
    else if (neighborhoodType == STAR)
    {
      for (int i = 1; i <= neighborhoodSize; i++)
      {
        if (cells[(row + rows) % rows][(column - i + columns) % columns] == 1)
          neighborCount++;
        if (cells[(row + rows) % rows][(column + i + columns) % columns] == 1)
          neighborCount++;
        if (cells[(row - i + rows) % rows][(column + columns) % columns] == 1)
          neighborCount++;
        if (cells[(row + i + rows) % rows][(column + columns) % columns] == 1)
          neighborCount++;
        if (cells[(row - i + rows) % rows][(column - i + columns) % columns] == 1)
          neighborCount++;
        if (cells[(row - i + rows) % rows][(column + i + columns) % columns] == 1)
          neighborCount++;
        if (cells[(row + i + rows) % rows][(column - i + columns) % columns] == 1)
          neighborCount++;
        if (cells[(row + i + rows) % rows][(column + i + columns) % columns] == 1)
          neighborCount++;
      }
      if (includeCenter && (cell == 1))
        neighborCount++;
    }
    else if (neighborhoodType == DIAMOND)
    {
      int columnSize = 0;
      if (((row - neighborhoodSize) >= 0) && ((row + neighborhoodSize) < rows) &&
          ((column - neighborhoodSize) >= 0) && ((column + neighborhoodSize) < columns))
      {
        for (int r = row - neighborhoodSize; r <= row + neighborhoodSize; r++)
        {
          for (int c = column - columnSize; c <= column + columnSize; c++)
            if (cells[r][c] == 1)
              neighborCount++;
          if (r < row)
            columnSize++;
          else
            columnSize--;
        }
      }
      else
      {
        for (int r = row - neighborhoodSize; r <= row + neighborhoodSize; r++)
        {
          for (int c = column - columnSize; c <= column + columnSize; c++)
            if (cells[(r + rows) % rows][(c + columns) % columns] == 1)
              neighborCount++;
          if (r < row)
            columnSize++;
          else
            columnSize--;
        }
      }
      if ((! includeCenter) && (cell == 1))
        neighborCount--;
    }
    if (cell == 0)
    {
      if ((neighborCount >= birthMin) && (neighborCount <= birthMax))
        return 1;
      else
        return 0;
    }
    else if (cell == 1)
    {
      if ((neighborCount >= survivalMin) && (neighborCount <= survivalMax))
        return 1;
    }
    if (noStates > 2)
      return (cell + 1) % noStates;
    else
      return 0;
  }


Notice that it is 130 lines, 56 lines of which deal with the CROSS, SALTIRE and STAR neighborhoods.

If this is too much trouble then so be it. My priority is still better rule management in Golly. See the following post:

viewtopic.php?f=4&t=1669&p=20087#p18485

Brian Prentice
bprentice
 
Posts: 407
Joined: September 10th, 2009, 6:20 pm
Location: Coos Bay, Oregon

Re: Golly 3.0b1

Postby Saka » July 2nd, 2017, 12:02 am

Saka wrote: I have designed some neighborhood formats. Just have to find them...

Here:
@NEIGHBORHOOD NeighborhoodName
#This will use the Moore+2 neighborhood
#All neighborhoods created will have "none" or "permute" symmetry only
#Specify the cells using 0 for out-of-neighborhood cell or 1 for inside-of-neighborhood cell
#Use a "o" for the "origin" cell

@NEIGHBORS
x:5 #Width
y:5 #Height
11111
11111
11o11
11111
11111

@ORDER
#Optional, this is for the order when creating rule tables
#Default is c, NNWW, NNW, NN... c' (AKA. top left to bottom right)
#o for origin
0,1,2,3,4
5,6,7,8,9
10,11,o,12,13
14,15,16,17,18
19,20,21,22,23

Once this neighborhood is installed you can use it in rule tables.
Everyone, please stop posting B/S about CA
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: 2184
Joined: June 19th, 2015, 8:50 pm
Location: In the kingdom of Sultan Hamengkubuwono X

Re: Golly 3.0b1

Postby Andrew » July 2nd, 2017, 12:10 am

bprentice wrote:Here is the Square Cell step code for all five neighborhoods:

That's the update code for *one* cell in a grid (and only a toroidal grid -- I don't see any code to handle a planar grid). That might be good enough for a simple Java app and small grid sizes but it's nowhere near fast enough for the large grid sizes we want to support in Golly.

If this is too much trouble then so be it.

Writing efficient code for those neighborhoods is quite a bit of work. It would be nice to have some help.

My priority is still better rule management in Golly. See the following post:

I've nothing to add to the reply I gave there.
User avatar
Andrew
Moderator
 
Posts: 629
Joined: June 2nd, 2009, 2:08 am
Location: Melbourne, Australia

Re: Golly 3.0b1

Postby dvgrn » July 2nd, 2017, 11:41 am

Andrew wrote:
bprentice wrote:My priority is still better rule management in Golly. See the following post:

I've nothing to add to the reply I gave there.

One idea I thought of that seems worth adding:

@Brian, with your interests and methods I think you must be managing an order of magnitude more rules than any other CA experimenter, by this time! But that's not a reason for changes to Golly source code -- since nobody else seems to need this feature, you just need one additional helper script to customize your copy of Golly.

A script with just a dozen lines or so could empty an AllRules folder, then copy all the rule files in your subdirectory structure into it. That script could even be arranged to run when Golly starts, or assign a shortcut key to do a rule refresh. Then you'd do all your rule management in your subdirectories, as you do now... but Golly's Rules folder setting would always point to AllRules, and every rule would always be available to Golly with no fiddling around with settings.

That wouldn't work if you have competing rules with the same name in different subdirectories... but it seems like that would be a problem worth fixing anyway.
dvgrn
Moderator
 
Posts: 3990
Joined: May 17th, 2009, 11:00 pm
Location: Madison, WI

Re: Golly 3.0b1

Postby drc » July 2nd, 2017, 1:43 pm

Alright, I have a new question. Is it possible for, when pasting into Golly, LifeHistory rules (or any ###History rule although that's a different request considering Golly doesn't support them.) to be converted to Life patterns if the requirements aren't met for a rule change? (If the checkbox saying 'Change rule when empty universe' isn't checked, or when there's already cells on the board.) Then it would convert all odd-state cells to alive cells, and all even-state cells to dead cells.

(Still, the @NEIGHBORHOOD thingy I suggested would be pretty cool.)
This post was brought to you by the letter D, for dishes that Andrew J. Wade won't do. (Also Daniel, which happens to be me.)
Current rule interest: B2ce3-ir4a5y/S2-c3-y
User avatar
drc
 
Posts: 1665
Joined: December 3rd, 2015, 4:11 pm
Location: creating useless things in OCA

Next

Return to General Discussion

Who is online

Users browsing this forum: No registered users and 2 guests