Script request thread

For scripts to aid with computation or simulation in cellular automata.
User avatar
Entity Valkyrie
Posts: 247
Joined: November 30th, 2017, 3:30 am

Re: Script request thread

Post by Entity Valkyrie » November 8th, 2018, 6:05 am

Can you give me a lua code that can convert rle to apgcode? I need lua, not python because I don't have python.

User avatar
Saka
Posts: 3627
Joined: June 19th, 2015, 8:50 pm
Location: Indonesia
Contact:

Re: Script request thread

Post by Saka » November 8th, 2018, 6:07 am

Entity Valkyrie wrote:I need lua, not python because I don't have python.
Why dont you install python then?

User avatar
Entity Valkyrie
Posts: 247
Joined: November 30th, 2017, 3:30 am

Re: Script request thread

Post by Entity Valkyrie » November 8th, 2018, 11:27 pm

Saka wrote:
Entity Valkyrie wrote:I need lua, not python because I don't have python.
Why dont you install python then?
I did install python 3.7, but it still did't wprk.

User avatar
Ian07
Moderator
Posts: 891
Joined: September 22nd, 2018, 8:48 am
Location: New Jersey, US

Re: Script request thread

Post by Ian07 » November 8th, 2018, 11:41 pm

Entity Valkyrie wrote: I did install python 3.7, but it still did't wprk.
If you're on Windows 10, try setting the file path to C:\Windows\SysWOW64\python37.dll when it asks you to locate a .dll file. If that doesn't work, try C:\Windows\System32\python37.dll

With the first one, I got it to work after having the same problem for months.

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

Re: Script request thread

Post by dvgrn » November 9th, 2018, 12:07 am

Entity Valkyrie wrote:
Saka wrote:
Entity Valkyrie wrote:I need lua, not python because I don't have python.
Why dont you install python then?
I did install python 3.7, but it still did't wprk.
Only Python 2.7.x works with Golly. Try installing Python 2.7.15 -- and make sure it's 32-bit if you have 32-bit Golly, or 64-bit if you have 64-bit Golly.

Or if you prefer, work on your programming skills by porting whatever Python scripts you want to Lua -- it would definitely be good to have more people who have had some practice doing that.

User avatar
Ian07
Moderator
Posts: 891
Joined: September 22nd, 2018, 8:48 am
Location: New Jersey, US

Re: Script request thread

Post by Ian07 » November 9th, 2018, 12:56 am

dvgrn wrote: Only Python 2.7.x works with Golly. Try installing Python 2.7.15 -- and make sure it's 32-bit if you have 32-bit Golly, or 64-bit if you have 64-bit Golly.
Yeah, forgot about that. Anyway, if it still gives an error, the thing I suggested above should still work - just replace Python37 with Python27.

User avatar
Entity Valkyrie
Posts: 247
Joined: November 30th, 2017, 3:30 am

Re: Script request thread

Post by Entity Valkyrie » November 15th, 2018, 5:26 am

Ian07 wrote:
dvgrn wrote: Only Python 2.7.x works with Golly. Try installing Python 2.7.15 -- and make sure it's 32-bit if you have 32-bit Golly, or 64-bit if you have 64-bit Golly.
Yeah, forgot about that. Anyway, if it still gives an error, the thing I suggested above should still work - just replace Python37 with Python27.
I already have python 2.7.15.

dani
Posts: 1222
Joined: October 27th, 2017, 3:43 pm

Re: Script request thread

Post by dani » November 18th, 2018, 8:15 pm

No idea what's wrong with this script:

Code: Select all

--This is a preliminary version. If sufficiently interesting behaviours show
--up, it would be nice to get a full simulating algorithm in better-written
--softawre like Golly. Speaking of Golly, make sure you have a version that
--supports Lua, so you can run this script. Stinky.

--TERMS TO KNOW:
--Heat - The number returned when the previous equation is ran on all of the
--       other cells in relation to the given cell (basically what count()
--       does)

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

local rulesB = {2, 3, 4, 5}
local rulesS = {2, 3, 4, 5}

function count(x1, y1) --determine cell's heat
	local pat
	local total = 0
	if g.getcell(x1, y1) == 1 then --ok i know it's ugly but it saves a lot of processing time than doing a conditional
		g.setcell(x1, y1, 0)
		pat = g.getcells(g.getrect())
		g.setcell(x1, y1, 1)
	else
		pat = g.getcells(g.getrect())
	end
	
	for i = 1, #pat, 2 do
		local x2 = pat[i]
		local y2 = pat[i+1] --ugly
		total = total+1 / ((x2-x1)^2+(y2-y1)^2) --i know i said i was using fourth powers, however the square root and fourth power cancel out leaving just a stray ^2
	end

	return total
end

function ring(r) --basically, it returns a 'outer moore birth ring' of the given size
	local pat = g.getcells(g.getrect())
	local x, y, w, h = table.unpack(r) --there a better way to do this?
	g.select({x-1, y-1, w+2, h+2})
	g.randfill(100)
	g.select({x, y, w, h})
	g.clear(0)
	local ring = g.getcells(g.getrect())
	g.putcells(pat)
	g.clear(1)
	g.select({})
	return ring
end

function step()
	--hoooo boy i hated writing this
	--don't read it if you don't want to get lost
	local pat = g.getcells(g.getrect())
	local rulesBclone = rulesB
	table.sort(rulesBclone)
	local minrulesB = rulesBclone[1] --math.min but with an array
	local lx, ly, lw, lh = table.unpack(g.getrect())
	while true do --this loop determines how far to check for births
		local localmax = 0
		local localring = ring({lx, ly, lw, lh})
		for i = 1, #localring, 2 do
			local localcount = count(localring[i], localring[i+1])
			if localcount > localmax then
				localmax = localcount
			end
		end
		if localmax < minrulesB then
			break
		end
		lx = lx - 1
		ly = ly - 1
		lw = lw + 2
		lh = lh + 2
	end
	--gosh that took me months to make, now onto processing
	g.select({lx, ly, lw, lh})
	g.randfill(100)
	g.putcells(pat, 0, 0, 1, 0, 0, 1, --[[ugh why]] "xor")
	local area = g.getcells(g.getrect())
	g.clear(0)
	g.putcells(pat)
	--NOW LET'S FINALLY PROCESS BIRTH, aka the reason that hellhole of lines above had to be done
	for i = 1, #area, 2 do
		g.setcell(area[i], area[i+1], 0)
		local localcount = count(area[i], area[i+1])
		for j = 1, #rulesB, 2 do
			if localcount >= rulesB[j] and localcount <= rulesB[j+1] then
				g.setcell(area[i], area[i+1], 1)
			end
		end
	end
	--and survival, the easy part
	for i = 1, #pat, 2 do
		g.setcell(pat[i], pat[i+1], 0)
		local localcount = count(pat[i], pat[i+1])
		for j = 1, #rulesS, 2 do
			if localcount >= rulesS[j] and localcount <= rulesS[j+1] then
				g.setcell(pat[i], pat[i+1], 1)
			end
		end
	end
end

while true do
	step()
	g.update()
end
This script is intended to simulate a type of CA-- that is, a CA that takes the euclidean distances from a base cell to every other cell, takes the reciprocal, and brings it to the fourth power, and adds them up, then checks if they're within a certain range, and if so, turns them on. This should be grid-symmetric.

When running a symmetric pattern, it turns asymmetric, and always seems to have the same shape. To the left is a starting pattern, to the right is it after 16 generations:

Code: Select all

x = 105, y = 46, rule = B3/S23
o71bobobobobobobob12o2bob3o$o65bobo2bobobobobobobobo12bo4b2o$b2o60bo2b
o2bo12bo4bo2bobobobo2bo4bo$59bob2o2bo5bo4bo16bobobo$56bo2bo4bo3bo3bobo
3bobobobo3bobobo5b2o3b2o$54bobo3bo4bo3bo3bobo9bobo6bo5bo3bo$52bobo3bo
2bo2bobo4bo6bo2bobo7bo6bo5bo$51b2o7bobo2bo3bo3bo6bo4bo2bo5bobo7bo$50b
2o2bo4bo3bo2bo4bo2bobobo4bo3bobobobo3bo6bo$51bo6bo5bo2bobo25bo3bo2bobo
$56bo2bobo3bo4bo2bobobobobobobobobo3bo10bo$50b2o5bo8bobo2bo8bo11bo4bob
o4bo$51bo3bo5bo2bo8bobo7bobo4bo3bo4bo4bo$51bo4bo2bo6bo2bobo5bobobo4bob
o4bobobobo4bo$51bo3bobo2bobo2bo17bobo3bo2bo7bo3bo$51bo7bo4bo2bobobo2bo
bobo2bo9bo3bobobo4bo$51bo4bobo3bo12bo6bo4bobo4bo5bo3bo$51bo8bo4bobobob
obo6bo4bo5bo4bo7bo$51bo6bo3bo12bobobo2bobo2bobo3bo5bo4bo$51bobo6bo3bob
obo2bo2bo16bo2bobo3bo3bo$51bo6bo3bo6bo3bo5bobo2bobo3bo6bo6bo$51bo8bo3b
obo9bobo3bo5bo4bo5bo4bo$51bo3bo2bo3bo5bobobobo5bo3bo9bo5bo3bo$51bo4bo
3bo3bobo15bo2bobo2bobo4bo6bo$51bo3bo6bo5bobobo3bobobo2bo9bobo3bo4bo$
51bo6bobo12bo12bobobo9bo3bo$51bo3bo6bo2bo2bo2bo3bo2bo2bo7bo3bobobo6bo$
51bo4bobobo3bobo2bo6bo5bobo14bo4bo$51bo10bo8bo2bo3bobo5bobo3bo3bo3bo3b
o$51bo3bobo2bo2bobobo2bo2bobo7bobo3bobo2bo2bo6bo$51bo9bo6bo3bo7bobo9bo
6bo4bo$51bo5bo4bo2bobo2bo4bobobo7bo9bo6bo$51bobobo3bo3bo9bo8bobo3bobob
obo5bo3bo$51bo4bo11bo2bo8bo5bo10bobo4bo$51bo3bo2bobo2bobobo6bo4bo2bo
10bo2bo7bo$53bo15bobo3bobo7bobobobo8bo3bo$50bobo2bo2bobobo2bobo5bo5bo
2bo10bo4bo5bo$57bo19bo6bo3bo3bobobo3bobobo$50b2o2bo3bobobobobobobo2bob
o2bo2bo3bobobobo3bo2bo4b2o$53bobo5bo5bo6bobo5bo13bo2bo3bo$50b2o4bo22bo
5bo3bo3bo9b2o$53bo18bo31bo$50b2o5bobobobobobobo6bo2bobobo3bo3bobobobo
6bo$51bobo16bobobo11bo11bo2bob2o$50b2ob2obobobobobobobobobob3obobobobo
bobobobobobobobo2bo$51b2obobobobobobobobobobo3bobobobobobobobobobobobo
b2ob2o!

wildmyron
Posts: 1542
Joined: August 9th, 2013, 12:45 am
Location: Western Australia

Re: Script request thread

Post by wildmyron » November 18th, 2018, 9:35 pm

danny wrote:No idea what's wrong with this script:

Code: Select all

<snip>
This looks like your updating during the processing loop, so the neighbourhood for each cell is changing whilst you are processing the results.
The 5S project (Smallest Spaceships Supporting Specific Speeds) is now maintained by AforAmpere. The latest collection is hosted on GitHub and contains well over 1,000,000 spaceships.

Semi-active here - recovering from a severe case of LWTDS.

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

Re: Script request thread

Post by dvgrn » November 18th, 2018, 9:42 pm

wildmyron wrote:
danny wrote:No idea what's wrong with this script:

Code: Select all

<snip>
This looks like your updating during the processing loop, so the neighbourhood for each cell is changing whilst you are processing the results.
Yup, it's the old NaiveLife problem. Just adjust count() to work off of a different layer -- i.e., alternate between two layers -- or use a saved in-memory copy of the previous generation, instead of the current universe.

dani
Posts: 1222
Joined: October 27th, 2017, 3:43 pm

Re: Script request thread

Post by dani » November 18th, 2018, 10:01 pm

Would it work if I instead stored the coordinates of each on cell in a cell list and then placed that after the fact?

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

Re: Script request thread

Post by dvgrn » November 18th, 2018, 10:56 pm

danny wrote:Would it work if I instead stored the coordinates of each on cell in a cell list and then placed that after the fact?
Yeah, was just about to edit my last message to suggest that. Probably that's simpler than the layer-switching trick, and about the same as putting the previous generation into a cell list.

dani
Posts: 1222
Joined: October 27th, 2017, 3:43 pm

Re: Script request thread

Post by dani » November 19th, 2018, 2:30 am

I don't think I did it right...

Code: Select all

--This is a preliminary version. If sufficiently interesting behaviours show
--up, it would be nice to get a full simulating algorithm in better-written
--softawre like Golly. Speaking of Golly, make sure you have a version that
--supports Lua, so you can run this script. Stinky.

--TERMS TO KNOW:
--Heat - The number returned when the previous equation is ran on all of the
--       other cells in relation to the given cell (basically what count()
--       does)

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

local rulesB = {2, 3, 4, 5}
local rulesS = {2, 3, 4, 5}

function count(x1, y1) --determine cell's heat
	local pat
	local total = 0
	if g.getcell(x1, y1) == 1 then --ok i know it's ugly but it saves a lot of processing time than doing a conditional
		g.setcell(x1, y1, 0)
		pat = g.getcells(g.getrect())
		g.setcell(x1, y1, 1)
	else
		pat = g.getcells(g.getrect())
	end
	
	for i = 1, #pat, 2 do
		local x2 = pat[i]
		local y2 = pat[i+1] --ugly
		total = total+1 / ((x2-x1)^2+(y2-y1)^2) --i know i said i was using fourth powers, however the square root and fourth power cancel out leaving just a stray ^2
	end

	return total
end

function ring(r) --basically, it returns a 'outer moore birth ring' of the given size
	local pat = g.getcells(g.getrect())
	local x, y, w, h = table.unpack(r) --there a better way to do this?
	g.select({x-1, y-1, w+2, h+2})
	g.randfill(100)
	g.select({x, y, w, h})
	g.clear(0)
	local ring = g.getcells(g.getrect())
	g.putcells(pat)
	g.clear(1)
	g.select({})
	return ring
end

function step()
	--hoooo boy i hated writing this
	--don't read it if you don't want to get lost
	local pat = g.getcells(g.getrect())
	if pat == {} then
		g.exit("All cells are dead.")
	end
	local rulesBclone = rulesB
	table.sort(rulesBclone)
	local minrulesB = rulesBclone[1] --math.min but with an array
	local lx, ly, lw, lh = table.unpack(g.getrect())
	while true do --this loop determines how far to check for births
		local localmax = 0
		local localring = ring({lx, ly, lw, lh})
		for i = 1, #localring, 2 do
			local localcount = count(localring[i], localring[i+1])
			if localcount > localmax then
				localmax = localcount
			end
		end
		if localmax < minrulesB then
			break
		end
		lx = lx - 1
		ly = ly - 1
		lw = lw + 2
		lh = lh + 2
	end
	--gosh that took me months to make, now onto processing
	g.select({lx, ly, lw, lh})
	g.randfill(100)
	g.putcells(pat, 0, 0, 1, 0, 0, 1, --[[ugh why]] "xor")
	local area = g.getcells(g.getrect())
	g.clear(0)
	g.putcells(pat)
	--NOW LET'S FINALLY PROCESS BIRTH, aka the reason that hellhole of lines above had to be done
	local localcells = {}
	for i = 1, #area, 2 do
		local localcount = count(area[i], area[i+1])
		for j = 1, #rulesB, 2 do
			if localcount >= rulesB[j] and localcount <= rulesB[j+1] then
				table.insert(localcells, pat[i])
				table.insert(localcells, pat[i+1]) --can't think of a way to insert two at once
			end
		end
	end
	--and survival, the easy part
	for i = 1, #pat, 2 do
		local localcount = count(pat[i], pat[i+1])
		for j = 1, #rulesS, 2 do
			if localcount >= rulesS[j] and localcount <= rulesS[j+1] then
				table.insert(localcells, pat[i])
				table.insert(localcells, pat[i+1])
			end
		end
	end
	g.select(g.getrect())
	g.clear(0)
	g.putcells(localcells)
	g.select({})
	g.setgen(tonumber(g.getgen()) + 1)
end

while true do
	step()
	g.update()
end
I hate my spaghetti code ;;

wildmyron
Posts: 1542
Joined: August 9th, 2013, 12:45 am
Location: Western Australia

Re: Script request thread

Post by wildmyron » November 19th, 2018, 5:04 am

danny wrote:I don't think I did it right...
There's a bug in the birth loop - you are adding cells from the 'pat' table to 'localcells' instead of using the 'area' table.
With that bug fixed, symmetric patterns stay symmetric, but there seems to be another bug in the heat calculation.

Code: Select all

total = total+1 / ((x2-x1)^2+(y2-y1)^2) --i know i said i was using fourth powers, however the square root and fourth power cancel out leaving just a stray ^2
The leftover ^2 appears to have been lost. I think you meant

Code: Select all

total = total+1 / ((x2-x1)^2+(y2-y1)^2)^2
danny wrote:I hate my spaghetti code ;;
Hey, don't worry about it too much - it's not really spaghetti code in my opinion. Some of the calculations you are doing are perhaps a bit convoluted, but once you have a working reference implementation you can clean parts of it up and easily check that it's still working correctly.
The 5S project (Smallest Spaceships Supporting Specific Speeds) is now maintained by AforAmpere. The latest collection is hosted on GitHub and contains well over 1,000,000 spaceships.

Semi-active here - recovering from a severe case of LWTDS.

dani
Posts: 1222
Joined: October 27th, 2017, 3:43 pm

Re: Script request thread

Post by dani » November 19th, 2018, 8:59 am

"The leftover 2 appears to have been lost"

No idea how that happened, it's a good thing I comment out my while thought process. I'll give the script a go during my spare time when I have computer access

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

Re: Script request thread

Post by calcyman » November 19th, 2018, 9:03 am

wildmyron wrote:
danny wrote:I hate my spaghetti code ;;
Hey, don't worry about it too much - it's not really spaghetti code in my opinion. Some of the calculations you are doing are perhaps a bit convoluted, but once you have a working reference implementation you can clean parts of it up and easily check that it's still working correctly.
I agree. Spaghetti code (where the control flow is difficult to determine from looking at the code) is actually quite difficult to write without using jump statements.
What do you do with ill crystallographers? Take them to the mono-clinic!

dani
Posts: 1222
Joined: October 27th, 2017, 3:43 pm

Re: Script request thread

Post by dani » November 19th, 2018, 10:58 am

The main optimization I want to make is to make it instead run a tick in B12345678/S012345678, AND it with the pattern (or previous ring), and store that instead, so that a pattern like this doesn't kill the memory:

Code: Select all

x = 0, y = 0, rule = B/S
o100$100bo!

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

Re: Script request thread

Post by dvgrn » November 19th, 2018, 11:38 am

danny wrote:The main optimization I want to make is to make it instead run a tick in B12345678/S012345678, AND it with the pattern (or previous ring), and store that instead...
To get the list of cells that might be relevant for the next tick, you mean? What if you ran B12345678/S to get the "possible-birth" cells, and just kept the original pattern's cell list for the "possible-survival" cells?

dani
Posts: 1222
Joined: October 27th, 2017, 3:43 pm

Re: Script request thread

Post by dani » November 19th, 2018, 12:02 pm

dvgrn wrote:
danny wrote:The main optimization I want to make is to make it instead run a tick in B12345678/S012345678, AND it with the pattern (or previous ring), and store that instead...
To get the list of cells that might be relevant for the next tick, you mean? What if you ran B12345678/S to get the "possible-birth" cells, and just kept the original pattern's cell list for the "possible-survival" cells?
That would make further rings have cells in the middle;

Code: Select all

x = 0, y = 0, rule = B12345678/S
o!

dani
Posts: 1222
Joined: October 27th, 2017, 3:43 pm

Re: Script request thread

Post by dani » November 19th, 2018, 1:22 pm

Alright I fixed a few things. But, how would I improve the birth process? It seems really slow.

Code: Select all

--This is a preliminary version. If sufficiently interesting behaviours show
--up, it would be nice to get a full simulating algorithm in better-written
--softawre like Golly. Speaking of Golly, make sure you have a version that
--supports Lua, so you can run this script. Stinky.

--TERMS TO KNOW:
--Heat - The number returned when the previous equation is ran on all of the
--		 other cells in relation to the given cell (basically what count()
--		 does)

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

local rulesB = {1.33, 1.7}
local rulesS = {2.5, 5.1}

function count(x1, y1) --determine cell's heat
	local pat
	local total = 0
	if g.getcell(x1, y1) == 1 then --ok i know it's ugly but it saves a lot of processing time than doing a conditional
		g.setcell(x1, y1, 0)
		pat = g.getcells(g.getrect())
		g.setcell(x1, y1, 1)
	else
		pat = g.getcells(g.getrect())
	end
	
	for i = 1, #pat, 2 do
		local x2 = pat[i]
		local y2 = pat[i+1] --ugly
		total = total+1 / ((x2-x1)^2+(y2-y1)^2)^2 --i know i said i was using fourth powers, however the square root and fourth power cancel out leaving just a stray ^2
	end

	return total
end

function ring(r) --basically, it returns a 'outer moore birth ring' of the given size
	local pat = g.getcells(g.getrect())
	local x, y, w, h = table.unpack(r) --there a better way to do this?
	g.select({x-1, y-1, w+2, h+2})
	g.randfill(100)
	g.select({x, y, w, h})
	g.clear(0)
	local nring = g.getcells(g.getrect())
	g.putcells(pat)
	g.clear(1)
	g.select({})
	return nring
end

function step()
	--hoooo boy i hated writing this
	--don't read it if you don't want to get lost
	local pat = g.getcells(g.getrect())
	if g.getpop() == "0" then
	  g.exit("All cells are dead.")
	  return
	end
	local rulesBclone = rulesB
	table.sort(rulesBclone)
	local minrulesB = rulesBclone[1] --math.min but with an array
	local lx, ly, lw, lh = table.unpack(g.getrect())
	while true do --this loop determines how far to check for births
		local localmax = 0
		local localring = ring({lx, ly, lw, lh})
		for i = 1, #localring, 2 do
			local localcount = count(localring[i], localring[i+1])
			if localcount > localmax then
				localmax = localcount
			end
		end
		if localmax < minrulesB then
			break
		end
		lx = lx - 1
		ly = ly - 1
		lw = lw + 2
		lh = lh + 2
	end
	--gosh that took me months to make, now onto processing
	g.select({lx, ly, lw, lh})
	g.randfill(100)
	g.putcells(pat, 0, 0, 1, 0, 0, 1, --[[ugh why]] "xor")
	local area = g.getcells(g.getrect())
	g.clear(0)
	g.putcells(pat)
	--NOW LET'S FINALLY PROCESS BIRTH, aka the reason that hellhole of lines above had to be done
	local localcells = {}
	for i = 1, #area, 2 do
		local localcount = count(area[i], area[i+1])
		for j = 1, #rulesB, 2 do
			if localcount >= rulesB[j] and localcount <= rulesB[j+1] then
				table.insert(localcells, area[i])
				table.insert(localcells, area[i+1]) --can't think of a way to insert two at once
			end
		end
	end
	--and survival, the easy part
	for i = 1, #pat, 2 do
		local localcount = count(pat[i], pat[i+1])
		for j = 1, #rulesS, 2 do
			if localcount >= rulesS[j] and localcount <= rulesS[j+1] then
				table.insert(localcells, pat[i])
				table.insert(localcells, pat[i+1])
			end
		end
	end
	g.select(g.getrect())
	g.clear(0)
	g.putcells(localcells)
	g.select({})
	g.setgen(tonumber(g.getgen())+1)
end

while true do
	step()
	g.update()
end
step()
Funnily, in the rule I gave above, this 47-generation methuselah exists:

Code: Select all

x = 4, y = 4, rule = B/S012345678
3bo$2b2o$bobo$3o!
It has a lot of spaceships.

EDIT: In the rule B(1.32, 1.57)/S(2.3, 3)(4, 5), there is a sparky ship and what I'm pretty sure is either a gun or a chaotic replicator:

Code: Select all

x = 3, y = 3, rule = B/S012345678
2o$3o$2bo!

Code: Select all

x = 3, y = 7000, rule = B/S012345678
2o$3o$2bo2$2bo$3o$2o!

User avatar
BlinkerSpawn
Posts: 1992
Joined: November 8th, 2014, 8:48 pm
Location: Getting a snacker from R-Bee's

Re: Script request thread

Post by BlinkerSpawn » November 19th, 2018, 9:23 pm

Looks good, danny!

I hacked in a short segment which I definitely didn't rip from giffer.lua that prompts the user for a rule (no B/S tags yet, just two comma-delimited lists separated by a space, like it shows):

Code: Select all

--This is a preliminary version. If sufficiently interesting behaviours show
--up, it would be nice to get a full simulating algorithm in better-written
--software like Golly. Speaking of Golly, make sure you have a version that
--supports Lua, so you can run this script. Stinky.

--TERMS TO KNOW:
--Heat - The number returned when the previous equation is ran on all of the
--       other cells in relation to the given cell (basically what count()
--       does)

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

local prompt = [[
Enter birth and survival (e.g. 2,3,4,5 2,3,4,5):
]]
local answer = g.getstring(prompt, "2,3,4,5 2,3,4,5", "Set Rule...")
local birth, survival = gp.split(answer)

local rulesB = {gp.split(birth, ",")}
local rulesS = {gp.split(survival, ",")}

for i = 1, #rulesB do
   rulesB[i] = tonumber(rulesB[i])
end
for j = 1, #rulesS do
   rulesS[j] = tonumber(rulesS[j])
end

function count(x1, y1) --determine cell's heat
   local pat
   local total = 0
   if g.getcell(x1, y1) == 1 then --ok i know it's ugly but it saves a lot of processing time than doing a conditional
      g.setcell(x1, y1, 0)
      pat = g.getcells(g.getrect())
      g.setcell(x1, y1, 1)
   else
      pat = g.getcells(g.getrect())
   end
   
   for i = 1, #pat, 2 do
      local x2 = pat[i]
      local y2 = pat[i+1] --ugly
      total = total+1 / ((x2-x1)^2+(y2-y1)^2)^2 --i know i said i was using fourth powers, however the square root and fourth power cancel out leaving just a stray ^2
   end

   return total
end

function ring(r) --basically, it returns a 'outer moore birth ring' of the given size
   local pat = g.getcells(g.getrect())
   local x, y, w, h = table.unpack(r) --there a better way to do this?
   g.select({x-1, y-1, w+2, h+2})
   g.randfill(100)
   g.select({x, y, w, h})
   g.clear(0)
   local nring = g.getcells(g.getrect())
   g.putcells(pat)
   g.clear(1)
   g.select({})
   return nring
end

function step()
   --hoooo boy i hated writing this
   --don't read it if you don't want to get lost
   local pat = g.getcells(g.getrect())
   if g.getpop() == "0" then
     g.exit("All cells are dead.")
     return
   end
   local rulesBclone = rulesB
   table.sort(rulesBclone)
   local minrulesB = rulesBclone[1] --math.min but with an array
   local lx, ly, lw, lh = table.unpack(g.getrect())
   while true do --this loop determines how far to check for births
      local localmax = 0
      local localring = ring({lx, ly, lw, lh})
      for i = 1, #localring, 2 do
         local localcount = count(localring[i], localring[i+1])
         if localcount > localmax then
            localmax = localcount
         end
      end
      if localmax < minrulesB then
         break
      end
      lx = lx - 1
      ly = ly - 1
      lw = lw + 2
      lh = lh + 2
   end
   --gosh that took me months to make, now onto processing
   g.select({lx, ly, lw, lh})
   g.randfill(100)
   g.putcells(pat, 0, 0, 1, 0, 0, 1, --[[ugh why]] "xor")
   local area = g.getcells(g.getrect())
   g.clear(0)
   g.putcells(pat)
   --NOW LET'S FINALLY PROCESS BIRTH, aka the reason that hellhole of lines above had to be done
   local localcells = {}
   for i = 1, #area, 2 do
      local localcount = count(area[i], area[i+1])
      for j = 1, #rulesB, 2 do
         if localcount >= rulesB[j] and localcount <= rulesB[j+1] then
            table.insert(localcells, area[i])
            table.insert(localcells, area[i+1]) --can't think of a way to insert two at once
         end
      end
   end
   --and survival, the easy part
   for i = 1, #pat, 2 do
      local localcount = count(pat[i], pat[i+1])
      for j = 1, #rulesS, 2 do
         if localcount >= rulesS[j] and localcount <= rulesS[j+1] then
            table.insert(localcells, pat[i])
            table.insert(localcells, pat[i+1])
         end
      end
   end
   g.select(g.getrect())
   g.clear(0)
   g.putcells(localcells)
   g.select({})
   g.setgen(tonumber(g.getgen())+1)
end

while true do
   step()
   g.update()
end
step()
LifeWiki: Like Wikipedia but with more spaceships. [citation needed]

Image

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

Re: Script request thread

Post by muzik » December 3rd, 2018, 4:44 pm

The Fredkin rule generation script outputs rules rules that replicate similarly to this one:

Code: Select all

x = 1, y = 1, rule = B1e2ak3einqy4jnry5einqy6ak7e/S1e2ak3einqy4jnry5einqy6ak7e
o!
Could it be modified to also be able to create (multi state generalisations of) rules similar to the following, where the center is preserved while still allowing replication overall (giving a core rule of 150 for 2-state versions)?

Code: Select all

x = 1, y = 1, rule = B1e2ak3einqy4jnry5einqy6ak7e/S01c2-ak3acjkr4-jnry5acjkr6-ak7c8
o!

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

Re: Script request thread

Post by dvgrn » December 3rd, 2018, 5:15 pm

muzik wrote:The Fredkin rule generation script outputs rules rules that replicate similarly to this one...

Code: Select all

(replication of one dot into four increasingly widely separated dots)
Could it be modified to also be able to create (multi state generalisations of) rules similar to the following, where the center is preserved while still allowing replication overall (giving a core rule of 150 for 2-state versions)?
You mean Golly's Scripts/Python/Rule-Generators/FredkinModN-gen.py ? Funny, I had either totally forgotten that that was in there, or possibly I never knew.

The behavior you describe is generated for von Neumann (N) inputs, but for Moore neighborhood rules you get a similar pattern with eight cells in a ring and a missing cell in the center.

The only thing I know about this is that if you want the middle to be empty you use B1357/S1357:

Code: Select all

x = 1, y = 1, rule = B1357/S1357
o!
whereas if you want the middle not to be empty you use the related totalistic rule 13579, a.k.a. Replicator 2, a.k.a. B1357/S02468:

Code: Select all

x = 1, y = 1, rule = B1357/S02468
o!
It seems likely that this behavior also generalizes to multiple states, but I can't immediately see what to change in the script to change the survival states appropriately.

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

Re: Script request thread

Post by muzik » December 3rd, 2018, 5:20 pm

It can be seen with hexagonal rules as well, as well as the TriLife script. I wouldn't be surprised if it also continued up the XOR rule trend past rules 90 and 150 as well.

User avatar
Entity Valkyrie
Posts: 247
Joined: November 30th, 2017, 3:30 am

Re: Script request thread

Post by Entity Valkyrie » December 4th, 2018, 10:49 pm


Post Reply