Has anyone tried making a script at this request?calcyman wrote: ↑April 2nd, 2023, 8:37 amConsider the following list of eight OTTs, arranged in increasing order of estimated cost. They're all slmake-constructible in all orientations:dvgrn wrote: ↑March 31st, 2023, 5:48 pmHowever, it now seems unlikely that any synchronized perpendicular gliders will be needed at all, let alone clock-inserter recipes. The script will probably be able to build a spacefiller seed using a much smaller toolkit of turners and splitters. So now we're just working out exactly what needs to be in the script's toolkit.
I think that it's reasonable to do something like the following pseudocode:Code: Select all
# [[ ZOOM 2 THEME Book WIDTH 800 HEIGHT 480 ]]
x = 366, y = 35, rule = B3/S23
352bo$353b2o$351b2o$353bo4$359bo$359b3o$362bo$361b2o$204bo46bo99bo$
203bobo44bobo97bobo11b2o$107b2o95bobo44b2o96bobo12b2o$51b2o53bobo49b2o
45b2o48b2o92b2o$52bo52bobo50b2o50b2o42bobo$52bobo51bo102bo2bo41b2o103b
2o$6bo46b2o154bo2bo93bo40b2o10bobo$5bobo155b2o45b2o93bobo39bobo10bo$6b
2o155b2o141b2o40bobo$349bo3$313b2o$3o47b3o47b3o47b3o47b3o47b3o47b3o9bo
bo35b3o$2bo49bo49bo49bo49bo49bo49bo8bobo38bo$bo49bo49bo49bo49bo49bo49b
o10bo38bo5$308b2o$307bo2bo$308bo2bo$309b2o!
This is using the same 'backward' approach as slmake, constructing the gliders in the salvo in reverse order. It's guaranteed to be successful, because the last OTT is just a single-glider version of the clock inserter, and we know that there's always a glider at the front of the salvo that can be inserted in this manner. By greedily choosing the first OTT in the list that works at each stage, it should be very rare (maybe so rare as to never be needed in the spacefiller synthesis!) that it falls back on the last OTT, but even that isn't terribly expensive*.Code: Select all
for each salvo: while salvo is nonempty: for each of the eight OTTs: for each glider in the salvo: if this glider can be built by that OTT (in either orientation) without interfering with the rest of the salvo: subtract it from the salvo and jump to the 'while' statement.
* the adjustable splitter is 3sL, so if we use the clock inserter then the cost for that glider is 9sL, just over twice the 4sL cost for a glider that's built using the cheapest mechanism (or 3x the absolute minimum if we can use a 2sL non-adjustable splitter).
Golly scripts
-
- Posts: 1077
- Joined: January 28th, 2022, 7:18 pm
- Location: Planet Z
Re: Golly scripts
I’ve requested a kind of script for golly similar to octohash, but completely independent. It was mentioned here, but I really don’t know where to start. As mentioned before, it will be able to take an unstable object/component and find a way to make a 1g seed for it without using splitters.
Re: Golly scripts
Why did you quote an entire post of mine from a different thread about something completely irrelevant to your script request?AlbertArmStain wrote: ↑April 7th, 2023, 2:23 pmI’ve requested a kind of script for golly similar to octohash, but completely independent. It was mentioned here, but I really don’t know where to start. As mentioned before, it will be able to take an unstable object/component and find a way to make a 1g seed for it without using splitters.
Has anyone tried making a script at this request?
What do you do with ill crystallographers? Take them to the mono-clinic!
Re: Golly scripts
No.
The link you gave above outlined exactly how to make the script -- most of the code already exists, though admittedly it's my code so it's fairly terrible -- but it also lists a series of objections to the idea of bothering to make such a script.
Here would probably be a good place to explain how you expect the script to accomplish the "not limited to 3 objects" part of the description, without taking months or years for each individual search. As far as I can tell, that's what your idea amounts to: basically "octohash without a database".
- SuperSupermario24
- Posts: 121
- Joined: July 22nd, 2014, 12:59 pm
- Location: Within the infinite expanses of the Life universe
Re: Golly scripts
So I was looking through some of my Golly stuff and I realized I never actually posted this "random fill" script I made. So, uh, here it is:
The comment at the top should hopefully contain all the info you need. As you can see I made this quite some time ago (it says updated 2020 but I think most of this was actually made in 2018). I think I was holding off on posting it until I implemented some additional features, but then I apparently never did and I don't even remember what they would've been at this point.
I don't plan on maintaining this or adding any additional features at this point, though of course anyone's free to add stuff on their own :p
Code: Select all
--[[
random-fill.lua
by SSM24, last updated 2020-11-16
This script fills the selection randomly, with density and states
determined by the user.
This script is partially based off of the random-fill.py script by
Andrew Trevorrow from the Golly Scripts Database, but contains the
following additional features:
- non-contiguous state ranges
- ability to save the default input for each rule individually
rather than one for every single rule
- non-integer density percentage values
- state multipliers, allowing certain states to be more likely than
others
Additionally, it is significantly faster than the Python version,
although Golly's native random fill is still faster.
Usage information:
- Inputs are of the form "density, <states and ranges>".
- Values are delimited by commas. Ranges are of the form min-max.
Multipliers are given with a colon (:) or lowercase x.
- If no states are provided, every live state in the rule will be
used.
- Spaces are optional. (They are immediately stripped from the input
if they are present.)
Example inputs:
50 - 50% density using every live state in the rule
20, 1 - 20% density using only state 1
100, 1-20 - 100% density using states 1 through 20
0.1, 1, 4-7, 10 - 0.1% density using states 1, 4 through 7, and 10
50, 1:20, 2 - 50% density with a 20x multiplier on state 1
100, 1-4x10, 5 - 100% density with a 10x multiplier on 1 through 4
]]
--------------------------------------------------------------------------------
local g = golly()
local gp = require "gplus"
-- if true, save default inputs
local saveinputs = true
-- set to true if you want to benchmark the random fill process
-- might only work properly on Windows?
local benchmark = false
--------------------------------------------------------------------------------
-- plain replace function because lua doesn't have one for some reason
function string.replace(s, orig, new)
-- escape magic characters
orig = orig:gsub("[%(%)%.%%%+%-%*%?%[%]%^%$]", "%%%0")
-- perform the subsitution
return s:gsub(orig, new)
end
--------------------------------------------------------------------------------
-- get the selection rectangle
local r = gp.rect(g.getselrect())
if r.empty then
g.exit("There is no selection.")
end
local maxlive = g.numstates() - 1
local rule = g.getrule()
local prompt = [[
Enter density, followed by the states that should be included.
Separate ranges or individual values with commas.
Use format min-max for ranges.
Leave states blank to use every state.]]
-- default is just "50" for 2-state rules
local default = "50"
-- if rule has more than 2 states, add a range
if g.numstates() > 2 then
default = default..",".."1-"..maxlive
end
local inipath = g.getdir("data").."random-fill-lua.ini"
local rulefound = false
-- get previous used values for rule if they exist
if saveinputs then
file = io.open(inipath, "r")
if file then
local line = ""
-- check every line until rule is found or end of file is reached
while line ~= nil do
-- if rule is found, grab input and break from loop
if line:find(rule) then
local _,result = gp.split(line, "=")
default = result
rulefound = true
break
end
line = file:read()
end
file:close()
end
end
--------------------------------------------------------------------------------
-- get user input and put it in a table
local input = g.getstring(prompt, default, "Randomly fill selection")
-- if blank, silently exit
if input == "" then g.exit() end
-- save input to ini file
if saveinputs then
-- if rule was found earlier, overwrite its entry
if rulefound then
-- function so that pcall() can be used to handle write failure
local function update()
-- copy file to string
file = io.open(inipath, "r")
local contents = file:read("a")
file:close()
-- replace old line with new line
contents = contents:replace(rule.."="..default, rule.."="..input)
-- overwrite file with new contents
file = io.open(inipath, "w+")
file:write(contents)
file:close()
end
-- show message if file could not be written to
if not pcall(update) then
g.warn("Could not save input to ini file.")
end
-- if rule was not found, add a new entry for it
-- this will create the file if it doesn't exist
else
local function update()
file = io.open(inipath, "a")
file:write(rule.."="..input.."\n")
file:close()
end
if not pcall(update) then
g.warn("Could not save input to ini file.")
end
end
end
-- strip all spaces from the result
input = input:gsub(" ", "")
-- take the input, split it, and put it in a table
local results = table.pack(gp.split(input, ","))
--------------------------------------------------------------------------------
-- get density and then remove it from table
local density = tonumber(results[1])
table.remove(results, 1)
-- check if density is valid
if density == nil then
g.exit("Density must be a number.")
elseif density < 0 or density > 100 then
g.exit("Density must be in the range 0-100.")
end
-- put density in range 0.0 - 1.0
-- math.random() is faster than math.random(100)
density = density / 100
--------------------------------------------------------------------------------
-- use a range containing all states if states were blank
if #results == 0 then
table.insert(results, "1-"..maxlive)
end
-- collect all states into a table
local states = {}
-- for every entry in the table
for i = 1, #results do
-- get result
local result = results[i]
-- replace any lowercase Xs with a colon for parsing
result = result:replace("x", ":")
-- get the state/range and the multiplier
local str, mult = gp.split(result, ":")
-- if weight not provided, default to 1
mult = mult or 1
-- add to states table the number of times given by multiplier
for _ = 1, mult do
-- if it's a range, add every state within it
if str:find("%d%-%d") ~= nil then
-- get min and max values
local minval, maxval = gp.split(str, "-")
minval = math.tointeger(minval)
maxval = math.tointeger(maxval)
-- make sure both are valid integers
if minval == nil or maxval == nil then
g.exit("\""..str.."\" is not a valid state or range.")
end
-- make sure both are within range
if minval < 0 or minval > maxlive
or maxval < 0 or maxval > maxlive then
g.exit("Values must be in range 0-"..maxlive..".")
end
-- reverse if min > max for some reason
local inc = 1
if minval > maxval then inc = -1 end
-- add states between min and max to table
for j = minval, maxval, inc do
table.insert(states, j)
end
-- if it's an individual value, add that value
elseif math.tointeger(str) ~= nil then
local num = math.tointeger(str)
-- make sure value is within range
if num < 0 or num > maxlive then
g.exit("Values must be in range 0-"..maxlive..".")
end
-- add to states table
table.insert(states, num)
-- if any value is invalid, exit
else
g.exit("\""..str.."\" is not a valid state or range.")
end
end
end
--------------------------------------------------------------------------------
--[[
-- debugging, lists all states in the states table
local str = ""
for i = 1, #states do
str = str..tostring(states[i]).." "
end
g.show(str)
]]
local numstates = #states
local currstate = 0
local oldsecs = os.time()
-- function to update the view if enough time has passed
function checktime()
local newsecs = os.time()
if newsecs - oldsecs >= 1 then
oldsecs = newsecs
g.update()
end
end
local starttime = os.clock()
-- the following is the generation of the random fill
--
-- it's done like this to minimize the amount of math.random() calls
-- in case of special conditions
-- if only one state, don't generate currstate every time
if numstates == 1 then
currstate = states[1]
-- if density is 100%, just fill the selection
if density == 1.0 then
for y = r.top, r.bottom do
for x = r.left, r.right do
g.setcell(x, y, currstate)
end
checktime()
end
-- otherwise, randomly fill it
else
for y = r.top, r.bottom do
for x = r.left, r.right do
if math.random() < density then
g.setcell(x, y, currstate)
else
g.setcell(x, y, 0)
end
end
checktime()
end
end
-- if more than one state, generate currstate every time
else
-- if density is 100%, completely fill it
if density == 1.0 then
for y = r.top, r.bottom do
for x = r.left, r.right do
currstate = states[math.random(numstates)]
g.setcell(x, y, currstate)
end
checktime()
end
-- otherwise, randomly fill it
else
for y = r.top, r.bottom do
for x = r.left, r.right do
if math.random() < density then
currstate = states[math.random(numstates)]
g.setcell(x, y, currstate)
else
g.setcell(x, y, 0)
end
end
checktime()
end
end
end
-- end of random fill generation
local endtime = os.clock()
if benchmark then
local timetaken = string.format("%.3f", endtime-starttime)
g.show("Took "..timetaken.." seconds.")
end
I don't plan on maintaining this or adding any additional features at this point, though of course anyone's free to add stuff on their own :p
Code: Select all
bobo2b3o2b2o2bo3bobo$obobobo3bo2bobo3bobo$obobob2o2bo2bobo3bobo$o3bobo3bo2bobobobo$o3bob3o2b2o3bobo2bo!
-
- Posts: 1077
- Joined: January 28th, 2022, 7:18 pm
- Location: Planet Z
Re: Golly scripts
I forgot that it pings you, they were intended to be separated from each other, but it look like I’m still talking about the top on. I’m supposed to be talking about making a script for both ideas
Re: Golly scripts
This is a script I got from EvinZL in a PM that may help with setting up LLS searches.
How to use it:
Code: Select all
import golly as g
if len(g.getselrect()) == 0: g.exit("No selection")
sr = g.getselrect()
generations = int(g.getstring("How many generations back?"))
cell_arr = []
for y in range(sr[1], sr[1]+sr[3]):
row = []
for x in range(sr[0], sr[0]+sr[2]):
row.append(g.getcell(x, y))
cell_arr.append(row)
search_file = ""
def writecells(l):
global search_file
for _ in range(sr[2]+2):
search_file += "0 "
search_file += "\n"
for i in cell_arr:
search_file += "0 "
for j in i:
search_file += l[j] + " "
search_file += "0\n"
for _ in range(sr[2]+2):
search_file += "0 "
search_file += "\n\n"
writecells("0**00")
for _ in range(generations-1):
writecells("0****")
writecells("01010")
g.setclipstr(search_file)
EvinZL wrote:September 21st, 2023, 6:59 pmCreate the search in LifeHistory, with 1 and 3=cells that are on in the final state, others=cells that must be off in the final state, 1 and 2=cells that can be on in the starting state and the intermediate states, and 3, 4=cells that can be on in the intermediate states but not the starting state. All other cells must be off in all states. Select the search, then run it, and it will paste the LLS input to clipboard.
EvinZL used this script to generate the diehard-related LLS files.EvinZL wrote:September 22nd, 2023, 12:16 pmState 0: must be off in all generations
State 1: must be on in final generation, can be on in starting and intermediate generations
State 2: must be off in final generation, can be on in starting and intermediate generations
State 3: must be on in final generation, can be on in intermediate but NOT starting generation
State 4: must be off in final generation, can be on in intermediate but NOT starting generation
Support Conway's Story Mode!
- EvinZL
- Posts: 796
- Joined: November 8th, 2018, 4:15 pm
- Location: A tungsten pool travelling towards the sun
- Contact:
Re: Golly scripts
This is a script to download rule files from LifeWiki to Golly's rules folder
Code: Select all
import golly as g
import urllib.request
rulename = g.getstring("Rule name:", "StateInvestigator", "Get rule")
try:
req = urllib.request.urlopen(f"https://conwaylife.com/w/index.php?title=Rule:{rulename}&action=raw")
except:
g.exit("Rule not found")
rulefile = req.read()
path = g.getdir("rules") + rulename + ".rule"
with open(path, "wb") as f:
f.write(rulefile)
g.setrule(rulename)
g.exit(f"Saved rule {rulename}")
Re: Golly scripts
No urllib module in luaEvinZL wrote: ↑October 13th, 2023, 7:45 pmThis is a script to download rule files from LifeWiki to Golly's rules folderCode: Select all
import golly as g import urllib.request ...

Oh my God! -- it's full of search space!
- NimbleRogue
- Posts: 444
- Joined: January 11th, 2021, 11:48 pm
Re: Golly scripts
carsoncheng asked me to put my slight modification for ship searching here
All I did was add this if statement if g.getcells(g.getrect())!=testcells: to check if the thing is a ship, and it can be easily commented out when needed, and a simple symmetry Ship for only symmetries that support ships
Code: Select all
import golly as g
import math
import random
from timeit import default_timer as timer
from glife.text import make_text
from glife import getminbox, rect
autoRAB=True #automatically detect rule, algorithm and border
group_by_period=True
auto_exclude=50 #maximal number of oscillators of specific period (if group_by_period)
show_periods=True #print list of periods (if group_by_period)
auto_stop=True #stop if no more oscillators can be added (if group_by_period)
max_period=200
result_spacing=250
stab_step=8
x=15
main_fill=75
count_update=1000
if autoRAB:
rule=g.getrule()
algo=g.getalgo()
if ":" in rule:
rule,bound=rule.split(":")
bound=":"+bound
else: bound=""
else:
rule=g.getstring("Rule:","B3/S23")
algo=g.getstring("Algorithm:","QuickLife")
bound=g.getstring("Bound:","T32,32")
if not (bound=="" or bound.startswith(":")): bound=":"+bound
s=g.getstring("Symmetry","All")
symm=0
if s!="All":
symm=s
#symm can be either C1, C2_1, C2_2, C2_4, D2_x, D2_+1, D2_+2, C4_1, C4_4, D4_x1, D4_x4, D4_+1, D4_+2, D4_+4, D8_1, D8_4, All, Rot
max_period+=1
oc=[0]*max_period
if rule=="GlideLife":
exclude_periods=[1,2,4,6,12,16]
if rule=="olife":
exclude_periods=[1,2,3,4,5,6,9,10,12,15,18,20,26,30,35]
if rule=="B3/S23":
exclude_periods=[1,2,3,6,8,4,5,10,15,30,14]
if rule in ["tlife","B3/S2-i34q"]:
exclude_periods=[1,2,4,5,160]
if rule=="salad":
exclude_periods=[1,2,4]
if rule=="B2inkce_S12":
exclude_periods=[1,2,4]
if rule=="B3678/S235678":
exclude_periods=[1,2,3,4,6,12,8]
if rule=="MoveIt":
exclude_periods=[1,2,3,4,6,8,12,16,24,32,48]
if rule=="B35678/S357":
exclude_periods=[1,2,6,4,3,8,12,35,5,14,24,13,10,15]
if rule=="B2-aS12":
exclude_periods=[1,14,6,3,2,4,7,26,42,9,28,12,78,16,48,236,24,84,182,13,156,5,130,21,10,208,234,15,11,70,8,19]
if rule=="B2i35r_S023-a4i":
exclude_periods=[1,2,4]
if rule=="B2in3S02-in3-n":
exclude_periods=[1,4,5,8,7,6,20,12,28,2,9,16,36,10,42,72,14,56,3,40,63,30,140,45,35]
if rule=="B37/S2-i34q":
exclude_periods=[1,2,5,4,3,20]
if rule=="B3/S235e":
exclude_periods=[1,2,15,3,5,10,8,30,4,6,14,40]
if rule=="randomnn":
exclude_periods=[20,4,14,7,28,140,84]
if rule=="Rotator":
exclude_periods=[12,40,120,4,60,10,20,24,8]
if rule=="B2ein3/S13":
exclude_periods=[1,2,4,6,5,10]
if rule=="PuffLife":
exclude_periods=[1,2,4,8,3,6,16,12]
if rule=="B3-k/S2-i3-k4cen":
exclude_periods=[1,2,5,4,3]
if rule=="B34ek5ak/S2-c34iz5y":
exclude_periods=[1,2,4,6]
if rule=="B35/S2":
exclude_periods=[2,4,1,3]
if rule=="B3568/S256":
exclude_periods=[1,2,3,4,6,12,5,10,15,20,14,42]
if rule=="B356/S234i":
exclude_periods=[1,2,4,6,12]
if rule=="b2ce3aiys12aei3r":
exclude_periods=[1,2,4,6,7,8,10,12,14,15,24,26,28,29,30,58,42,62,94,126,138,170,186,202,234,266]
if rule=="B3-cnry4-acery5i/S23-a4-jknqr5y8":
exclude_periods=[1,2,36,92,4,28,12,18,8]
if rule=="B3/S23-a4eiktz":
exclude_periods=[1,2,4,5,10,78,7,14,9,36,3,6]
if rule=="B34e5e/S2-in3-y5jk":
exclude_periods=[1,2,4,10,13,26,6,3]
if rule=="B2e3-r5i8/S23-a4kz7c":
exclude_periods=[1,2,7,14,4]
if rule=="B3/S23-e4k":
exclude_periods=[1,2,4,5,6,10,98,294,14,22,12]
if rule=="B34aq5c/S135":
exclude_periods=[1,2,4,3,6,13,26,8,12,52,39]
if rule=="B2-a3/S1c23-ainr4cekn":
exclude_periods=[1,2,4,12,31,6,62,8,5,10,124,28,20]
if rule=="B2-a3-in/S23":
exclude_periods=[1,2,6,4,44,12,3,16,9,18,132,5,8,36,220,20,30,22,60]
if rule=="B2-a3-in/S235c":
exclude_periods=[1,2,4,3,6,44,12,10,20,132,16,60,5,58,8]
exclude_periods=[]
def all_periods(q):
if not show_periods: return ""
gmin = gmax = 0
text = "["
for i in q+[0]:
if i==0: text += str(gmin) + ("-"+str(gmax)+"]" if gmax>gmin else "]")
elif gmin==0: gmin = gmax = i
elif i-gmax==1: gmax = i
else:
text += str(gmin) + ("-"+str(gmax)+"," if gmax>gmin else ",")
gmin = gmax = i
return text
def osc_test():
global exclude_periods
if g.empty():
return False
testcells=g.getcells(g.getrect())
testpop=g.getpop() # String representation
testhash=g.hash(g.getrect())
for i in range(1,max_period):
g.run(1)
if g.empty():
return False
if g.getpop()==testpop and g.hash(g.getrect())==testhash:
if g.getcells(g.getrect())!=testcells:
if i not in exclude_periods:
if auto_exclude==1: exclude_periods+=[i]
return i
return 0
return 0
def put_symm(cell_list,x0=0,y0=0,axx=1,axy=0,ayx=0,ayy=1,mode="or"):
global symm
if s=="All":
symm=["C1", "C2_1", "C2_2", "C2_4", "D2_x", "D2_+1", "D2_+2", "C4_1", "C4_4", "D4_x1", "D4_x4", "D4_+1", "D4_+2", "D4_+4", "D8_1", "D8_4"][random.randrange(16)]
if s=="Ship":
symm=["C1", "D2_x","D2_+1", "D2_+2"][random.randrange(4)]
if s=="Rot":
symm=["C1", "C2_1", "C2_2", "C2_4", "C4_1", "C4_4"][random.randrange(6)]
# g.putcells(cell_list,x0,y0,axx,axy,ayx,ayy,mode)
if symm=="C2_1" or symm=="C4_1" or symm=="D4_+1" or symm=="D8_1" or symm=="D4_x1":
g.putcells(cell_list,-x0,-y0,-axx,-axy,-ayx,-ayy,mode)
if symm=="C4_1" or symm=="D8_1":
g.putcells(cell_list,y0,-x0,ayx,ayy,-axx,-axy,mode)
g.putcells(cell_list,-y0,x0,-ayx,-ayy,axx,axy,mode)
if symm=="C2_2" or symm=="D4_+2":
g.putcells(cell_list,-x0-1,-y0,-axx,-axy,-ayx,-ayy,mode)
if symm=="C2_4" or symm=="C4_4" or symm=="D4_+4" or symm=="D8_4" or symm=="D4_x4":
g.putcells(cell_list,-x0-1,-y0-1,-axx,-axy,-ayx,-ayy,mode)
if symm=="D2_+1" or symm=="D8_1" or symm=="D4_+1":
g.putcells(cell_list,-x0,y0,-axx,-axy,ayx,ayy,mode)
if symm=="D4_+1" or symm=="D8_1" or symm=="D4_+2":
g.putcells(cell_list,x0,-y0,axx,axy,-ayx,-ayy,mode)
if symm=="D2_+2" or symm=="D4_+2" or symm=="D4_+4" or symm=="D8_4":
g.putcells(cell_list,-x0-1,y0,-axx,-axy,ayx,ayy,mode)
if symm=="D4_+4" or symm=="D8_4":
g.putcells(cell_list,x0,-y0-1,axx,axy,-ayx,-ayy,mode)
if symm=="C4_4" or symm=="D8_4":
g.putcells(cell_list,y0,-x0-1,ayx,ayy,-axx,-axy,mode)
g.putcells(cell_list,-y0-1,x0,-ayx,-ayy,axx,axy,mode)
if symm=="D8_4":
g.putcells(cell_list,-y0-1,-x0-1,-ayx,-ayy,-axx,-axy,mode)
if symm=="D2_x" or symm=="D8_1" or symm=="D8_4" or symm=="D4_x1" or symm=="D4_x4":
g.putcells(cell_list,y0,x0,ayx,ayy,axx,axy,mode)
if symm=="D4_x1" or symm=="D8_1":
g.putcells(cell_list,-y0,-x0,-ayx,-ayy,-axx,-axy,mode)
if symm=="D4_x4" or symm=="D8_4":
g.putcells(cell_list,-y0-1,-x0-1,-ayx,-ayy,-axx,-axy,mode)
def clear_layer():
r = g.getrect()
if r:
g.select(r)
g.clear(0)
return
def main():
global oc
g.new("RandOsc")
g.setrule(rule+bound)
g.setalgo(algo)
g.setbase(2)
test_layer=g.getlayer()
if g.numlayers()<g.maxlayers():
results_layer=g.addlayer()
g.setname('OscResults')
g.setrule(rule)
for i in range(max_period-1):
t = make_text(str(i+1), "mono")
t.put((i+1)*result_spacing,0)
g.setlayer(test_layer)
else:
resultslayer=-1
results=0
count=0
prevcount=0
t_start=timer()
t_prev=t_start
while True:
clear_layer()
g.select([0,0,x,x])
g.randfill(main_fill)
cell_list=g.getcells([0,0,x,x])
# g.clear(0)
put_symm(cell_list)
g.setstep(stab_step)
g.step()
test=osc_test()
if test>0:
osc = g.getcells(g.getrect())
if group_by_period:
if oc[test]==0: results+=1
if oc[test]<auto_exclude:
if results_layer>=0:
oc[test]+=1
g.setlayer(results_layer)
g.putcells(osc, result_spacing*test, result_spacing*oc[test])
g.setname('OscResults (%d)' % results)
g.fit()
g.update()
g.setlayer(test_layer)
g.setname('RandOsc (%d)' % results)
else:
return True
else:
results+=1
if results_layer>=0:
g.setlayer(results_layer)
g.putcells(osc, result_spacing*results, 0)
g.setname('OscResults (%d)' % results)
g.fit()
g.update()
g.setlayer(test_layer)
g.setname('RandOsc (%d)' % results)
else:
return True
count+=1
if count%count_update==0:
t_end=timer()
g.show("%d results found after %d soups tested (%d/sec current, %d/sec overall)" % (results, count, (count-prevcount)/(t_end-t_prev), (count)/(t_end-t_start))+" "+all_periods([i for i in range(max_period) if oc[i]>0]))
g.select([])
g.update()
g.new("")
g.setbase(2)
t_prev=t_end
prevcount=count
if auto_stop and auto_exclude>0:
if sum(oc)==(max_period-1-len([i for i in exclude_periods if i<max_period]))*auto_exclude: break
main()
Code: Select all
x = 7, y = 8, rule = B2i3aeikq4aciqtz5e/S2en3ijq4aiqrw5-cn6aei7e8
2b3o$b2ob2o$2obob2o$obo$2obo$b2ob2o$2b4o$4bo!
Code: Select all
x = 5, y = 6, rule = B2in3-ekny4ckqtz5ekry6in7c/S2aek3-ace4ceiyz5n6n7
2bo$b3o$bobo$bob2o$2bo$obo!