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 slmakeconstructible 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 clockinserter 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 singleglider 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 nonadjustable splitter).
Golly scripts

 Posts: 1331
 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 monoclinic!
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
[[
randomfill.lua
by SSM24, last updated 20201116
This script fills the selection randomly, with density and states
determined by the user.
This script is partially based off of the randomfill.py script by
Andrew Trevorrow from the Golly Scripts Database, but contains the
following additional features:
 noncontiguous state ranges
 ability to save the default input for each rule individually
rather than one for every single rule
 noninteger 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 minmax.
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, 120  100% density using states 1 through 20
0.1, 1, 47, 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, 14x10, 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 minmax for ranges.
Leave states blank to use every state.]]
 default is just "50" for 2state 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").."randomfilllua.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 0100.")
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", endtimestarttime)
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: 1331
 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(generations1):
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 diehardrelated 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: 856
 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: 559
 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/S2i34q"]:
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=="B2aS12":
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_S023a4i":
exclude_periods=[1,2,4]
if rule=="B2in3S02in3n":
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/S2i34q":
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=="B3k/S2i3k4cen":
exclude_periods=[1,2,5,4,3]
if rule=="B34ek5ak/S2c34iz5y":
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=="B3cnry4acery5i/S23a4jknqr5y8":
exclude_periods=[1,2,36,92,4,28,12,18,8]
if rule=="B3/S23a4eiktz":
exclude_periods=[1,2,4,5,10,78,7,14,9,36,3,6]
if rule=="B34e5e/S2in3y5jk":
exclude_periods=[1,2,4,10,13,26,6,3]
if rule=="B2e3r5i8/S23a4kz7c":
exclude_periods=[1,2,7,14,4]
if rule=="B3/S23e4k":
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=="B2a3/S1c23ainr4cekn":
exclude_periods=[1,2,4,12,31,6,62,8,5,10,124,28,20]
if rule=="B2a3in/S23":
exclude_periods=[1,2,6,4,44,12,3,16,9,18,132,5,8,36,220,20,30,22,60]
if rule=="B2a3in/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 igmax==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,x01,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,x01,y01,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,x01,y0,axx,axy,ayx,ayy,mode)
if symm=="D4_+4" or symm=="D8_4":
g.putcells(cell_list,x0,y01,axx,axy,ayx,ayy,mode)
if symm=="C4_4" or symm=="D8_4":
g.putcells(cell_list,y0,x01,ayx,ayy,axx,axy,mode)
g.putcells(cell_list,y01,x0,ayx,ayy,axx,axy,mode)
if symm=="D8_4":
g.putcells(cell_list,y01,x01,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,y01,x01,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_period1):
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, (countprevcount)/(t_endt_prev), (count)/(t_endt_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_period1len([i for i in exclude_periods if i<max_period]))*auto_exclude: break
main()
Code: Select all
x = 4, y = 3, rule = B3cnqy4e5kr6n7c/S2i3ay4einrtyz5cejn6cin78
bo$3o$ob2o!
Code: Select all
#14c/85265o
x = 10, y = 4, rule = B2an3iqy4iknrtz5aijqy6aei78/S02ck3nqy4eiqrtwy5ekq6i78
2bo4bo$3b4o$ob6obo$2b6o!
Re: Golly scripts
Hey, these are my first steps with Python.
Please bear with me
About this 2 old scripts :
So, I've managed a script that produces a number (requested from the user) of image files of the selected pattern according to a generation increment (requested from the user).
The user is also asked where to save the files.
The original idea was to create a GIF but I don't have the knowledge to do that ...
If anyone would like to correct me and help me create the GIF file, they are most welcome.
At least you have all the image files to create a GIF with the software of your choice
Edit:
I used a hard coded version to make my avatar.
Please bear with me
About this 2 old scripts :
The site python2to3.com works finedvgrn wrote: ↑February 11th, 2024, 10:15 amNo. I don't believe any of those scripts have been updated since Golly moved to Python 3.x. An 'xrange' error is unambiguous evidence of a Python 2.x script.Tawal wrote: ↑February 11th, 2024, 9:17 amAbout this 2 scripts :
savebmp.py
saveimage.py
Are they Python3 compatible ?
https://python2to3.com/ can probably fix most such errors for you very quickly, but no guarantees. If anyone is willing to run through all of those old scripts and upgrade them to Python 3, I can work to get the old versions replaced.
Otherwise it might be simplest just to remove that page from conwaylife.com  a GitHub or GitLab repo would probably be a better way to serve up that kind of content these days.
So, I've managed a script that produces a number (requested from the user) of image files of the selected pattern according to a generation increment (requested from the user).
The user is also asked where to save the files.
The original idea was to create a GIF but I don't have the knowledge to do that ...
If anyone would like to correct me and help me create the GIF file, they are most welcome.
At least you have all the image files to create a GIF with the software of your choice
Code: Select all
# Uses PIL (Python Imaging Library) to save the current selection or pattern
# in a userspecified image file (.png/.bmp/.gif/.tif/.jpg).
# See http://www.pythonware.com/products/pil/ for more info about PIL.
# Author: Andrew Trevorrow (andrew@trevorrow.com), Oct 2009.
import golly as g
import os.path
import webbrowser
import urllib.request, urllib.parse, urllib.error
try:
from PIL import Image
except:
g.exit("You need to install PIL (Python Imaging Library).")
### Rapid exit if iznogood ...
if g.empty(): g.exit("There is no pattern.")
# prevent Image.new allocating a huge amount of memory
prect = g.getrect()
srect = g.getselrect()
if len(srect) > 0: prect = srect # save selection rather than pattern
wd = prect[2]
ht = prect[3]
if wd * ht >= 100000000:
g.exit("Image area is restricted to < 100 million cells.")
#set initial directory for the save dialog
initdir = ""
savename = g.getdir("data") + "saveimage.ini"
try:
# try to get the directory saved by an earlier run
f = open(savename, 'r')
initdir = f.readline()
f.close()
except:
# this should only happen the very 1st time
initdir = g.getdir("data")
# remove any existing extension from layer name and append .png
initfile = g.getname().split('.')[0] + ".png"
# prompt user for the number of images
gens = int( g.getstring("Enter the number of images : ", "", "Make a GIF") )
# prompt user for the step (one image each n genearations)
step = int( g.getstring("Enter the step \n (one image each n genearations) :", "", "Make a GIF") )
# prompt user for output file (image type depends on extension)
outfile = g.savedialog("Make a GIF  Save image files",
"PNG (*.png)*.png" ,
initdir, initfile)
# iteration 'step' by 'step' and get image
for nb_img in range(gens) :
prect = g.getrect()
srect = g.getselrect()
if len(srect) > 0: prect = srect # save selection rather than pattern
x = prect[0]
y = prect[1]
wd = prect[2]
ht = prect[3]
# create RGB image filled initially with state 0 color
multistate = g.numstates() > 2
colors = g.getcolors() # [0,r0,g0,b0, ... N,rN,gN,bN]
im = Image.new("RGB", (wd,ht), (colors[1],colors[2],colors[3]))
# get a row of cells at a time to minimize use of Python memory
cellcount = 0
for row in range(ht):
cells = g.getcells( [ x, y + row, wd, 1 ] )
clen = len(cells)
if clen > 0:
inc = 2
if multistate:
# cells is multistate list (clen is odd)
inc = 3
if clen % 3 > 0: clen = 1 # ignore last 0
for i in range(0, clen, inc):
if multistate:
n = cells[i+2] * 4 + 1
im.putpixel((cells[i]x,row), (colors[n],colors[n+1],colors[n+2]))
else:
im.putpixel((cells[i]x,row), (colors[5],colors[6],colors[7]))
cellcount += 1
if cellcount % 1000 == 0:
# allow user to abort huge pattern/selection
g.dokey( g.getkey() )
if cellcount == 0:
g.show("Pattern died toot early  Only get " + str(nb_img) + " images.")
break
g.show("Creating images...")
outfile = outfile.split('.')[0] + "." + str(nb_img) + ".png"
if len(outfile) > 0:
im.save(outfile)
g.run(step)
# remember file's directory for next time
try:
f = open(savename, 'w')
f.write(os.path.dirname(outfile))
f.close()
except:
g.warn("Unable to save directory to file:\n" + savename)
g.reset()
I used a hard coded version to make my avatar.
Alone we go faster … Together we go further …
Avatar's pattern
Possible uses found by Dave Green
Jormungant's explanation and uses
Currently investigating signal collisions … (stand by)
Avatar's pattern
Possible uses found by Dave Green
Jormungant's explanation and uses
Currently investigating signal collisions … (stand by)
Re: Golly scripts
Well, I've had a bit of a look at the Python language and I've realised what I was kindly asking for
Here's a script that creates an animated GIF file from a selected pattern. It's intended for small patterns rather than large ones.
It opens a window asking the user for 5 parameters:
 The duration of the GIF in tenths of a second.
 The number of captures to take from the selection.
 The incremental step of the generations.
 The number of the first capture to be inserted at the beginning of the GIF, creating a start delay.
 The number of the last capture to be added at the end of the GIF, creating an end delay.
On the Python side, the script uses Python 3, of course.
It also uses several libraries:
 PIL = Python Imaging Library
 tkinter
 ttk
 tkfont
I wrote the script on a Linux Debian 12 and it works very well for me.
There may be some modifications to make it work on Windows or MacOSX.
As this is really my very first script in Python, I'm quite happy with it.
Well, enough said, the script :
makeagif.py
Code: Select all
# Original Script : saveimage..py
# Uses PIL (Python Imaging Library) to save the current selection or pattern
# in a userspecified image file (.png/.bmp/.gif/.tif/.jpg).
# See http://www.pythonware.com/products/pil/ for more info about PIL.
# Author: Andrew Trevorrow (andrew@trevorrow.com), Oct 2009.
# Modifications : makeagif.py
# Always use PIL (see above).
# Also use 'tkinter', 'ttk' and 'tkfont'.
# See https://docs.python.org/fr/3/library/tk.html for more about tkinter, ttk and tkfont.
# Now the script makes an animated GIF file from the selected pattern
#+ and its evolving according to a generation step.
# It has 5 userprovided parameters :
#  Duration : the duration of the GIF file in tenths of a second.
#  Number of images to capture from the selected pattern.
#  Step for the evolving pattern (must be an integer).
#  Starting Delay : Number of the first captured image
# to insert at the beginning of the GIF file.
#  Ending Delay : Number of the last captured image
# to append at the end of the GIF file.
# The script creates a new working layer which is destroyed at the end.
#+ So it doesn't touch the original pattern layer :)
# The script stops to capture if the pattern dies. The GIF file is created yet.
#+ This affects the start and end delays.
# Contributor : Tawal (https://conwaylife.com/forums  user : Tawal), Feb 2024.
import golly as g
import os.path
import urllib.request, urllib.parse, urllib.error
try:
from PIL import Image
except:
g.exit("You need to install 'PIL' (Python Imaging Library).")
try:
import tkinter as tk
from tkinter import ttk
from tkinter import font
except:
g.exit("You need to install 'tkinter' (Tkinter  Python Module.")
# Rapid exit if iznogood ...
srect = g.getselrect()
if len(srect) == 0:
g.exit("There is no selection.")
x = srect[0]
y = srect[1]
wd = srect[2]
ht = srect[3]
# prevent Image.new allocating a huge amount of memory
if wd * ht >= 100000000:
g.exit("Image area is restricted to < 100 million cells.")
# for all further normal exit
def clean_exit(msg):
g.dellayer()
g.exit(msg)
# get the rule's colors
multistate = g.numstates() > 2
colors = g.getcolors() # [0,r0,g0,b0, ... N,rN,gN,bN]
# new working layer (deleted at the end of script).
initfile = g.getname().split('.')[0] + ".gif" # remove any existing extension from layer name and append .gif
g.copy()
gif_layer = g.addlayer()
g.setname(initfile)
g.paste(x, y, "or")
g.update()
#set initial directory for the save dialog
initdir = ""
savename = g.getdir("data") + initfile
try:
# try to get the directory saved by an earlier run
f = open(savename, 'r')
initdir = f.readline()
f.close()
except:
# this should only happen the very 1st time
initdir = g.getdir("data")
# Multientry window
end_script= False
def button_exit_clicked():
global end_script
in_win.destroy()
end_script = True
def button_OK_clicked():
global duration, n_im, step, start_delay, end_delay
n_im = n_imSV.get()
duration = durationSV.get()
step = stepSV.get()
start_delay = start_delaySV.get()
end_delay = end_delaySV.get()
in_win.destroy()
def OnValidate(S):
if S.isdigit():
return True
return False
in_win = tk.Tk()
in_win.title("Make a GIF")
in_win.geometry('520x320')
in_win.eval('tk::PlaceWindow . center')
valid_inputs = (in_win.register(OnValidate), '%S')
intro_lbl = ttk.Label(in_win, underline=80, text="Make an animated GIF file from the selected pattern")
intro_f = font.Font(intro_lbl, intro_lbl.cget("font"))
intro_f.configure(underline=True, weight=font.BOLD)
intro_lbl.configure(font=intro_f)
duration_lbl = tk.Label(in_win, text="Duration of GIF (x0.1s) : ")
durationSV = tk.StringVar()
duration_ask = tk.Entry(in_win, textvariable=durationSV, width=6, justify=tk.RIGHT, validate="key", vcmd=valid_inputs)
n_im_lbl = tk.Label(in_win, text="Number of captures to take from pattern : ")
n_imSV = tk.StringVar()
n_im_ask = tk.Entry(in_win, textvariable=n_imSV, width=6, justify=tk.RIGHT, validate="key", vcmd=valid_inputs)
step_lbl = tk.Label(in_win, text="Generation Step (integer) : ")
stepSV = tk.StringVar()
step_ask = tk.Entry(in_win, textvariable=stepSV, width=6, justify=tk.RIGHT, validate="key", vcmd=valid_inputs)
step_ask.insert(0, "1")
start_delay_lbl = tk.Label(in_win, text="Number of first same frames (starting delay) : ")
start_delaySV = tk.StringVar()
start_delay_ask = tk.Entry(in_win, textvariable=start_delaySV, width=6, justify=tk.RIGHT, validate="key", vcmd=valid_inputs)
start_delay_ask.insert(0, "0")
end_delay_lbl = tk.Label(in_win, text="Number of last same frames (ending delay) : ")
end_delaySV = tk.StringVar()
end_delay_ask = tk.Entry(in_win, textvariable=end_delaySV, width=6, justify=tk.RIGHT, validate="key", vcmd=valid_inputs)
end_delay_ask.insert(0, "0")
button_exit = tk.Button(in_win, text="Exit", width=8, command=button_exit_clicked)
button_OK = tk.Button(in_win, text='Make GIF', width=8, command=button_OK_clicked)
in_win.columnconfigure(0, weight=1)
in_win.columnconfigure(1, weight=15)
in_win.columnconfigure(2, weight=15)
in_win.columnconfigure(3, weight=15)
in_win.columnconfigure(4, weight=1)
in_win.rowconfigure(0, weight=20)
in_win.rowconfigure(1, weight=2)
in_win.rowconfigure(2, weight=2)
in_win.rowconfigure(3, weight=2)
in_win.rowconfigure(4, weight=2)
in_win.rowconfigure(5, weight=2)
in_win.rowconfigure(6, weight=15)
intro_lbl.grid(column=0, row=0, columnspan=4)
duration_lbl.grid(column=1, row=1, columnspan=2, stick=tk.E)
duration_ask.grid(column=3, row=1, stick=tk.W)
n_im_lbl.grid(column=1, row=2, columnspan=2, stick=tk.E)
n_im_ask.grid(column=3, row=2, stick=tk.W)
step_lbl.grid(column=1, row=3, columnspan=2, stick=tk.E)
step_ask.grid(column=3, row=3, stick=tk.W)
start_delay_lbl.grid(column=1, row=4, columnspan=2, stick=tk.E)
start_delay_ask.grid(column=3, row=4, stick=tk.W)
end_delay_lbl.grid(column=1, row=5, columnspan=2, stick=tk.E)
end_delay_ask.grid(column=3, row=5, stick=tk.W)
button_OK.grid(column=3, row=6, sticky=tk.W)
button_exit.grid(column=1, row=6, sticky=tk.W, padx=50)
duration_ask.focus()
in_win.mainloop()
if end_script: # exit if exit_button is clicked
clean_exit('Exited')
# then prompt user for output GIF file.
outfile = g.savedialog("Make a GIF  Save image file",
"GIF (*.gif)*.gif" ,
initdir, initfile)
if len(outfile) < 1 : # exit if empty string or cancel choice
clean_exit('Exited')
# create images list
g.show("Please wait while creating GIF file ...")
list_im = []
for k in range(int(n_im)):
# create RGB image filled initially with state 0 color
im = Image.new("RGB", (wd,ht), (colors[1],colors[2],colors[3]))
# get a row of cells at a time to minimize use of Python memory
cellcount = 0
for row in range(ht):
cells = g.getcells( [ x, y + row, wd, 1 ] )
clen = len(cells)
if clen > 0:
inc = 2
if multistate:
# cells is multistate list (clen is odd)
inc = 3
if clen % 3 > 0: clen = 1 # ignore last 0
for i in range(0, clen, inc):
if multistate:
n = cells[i+2] * 4 + 1
im.putpixel((cells[i]x,row), (colors[n],colors[n+1],colors[n+2]))
else:
im.putpixel((cells[i]x,row), (colors[5],colors[6],colors[7]))
cellcount += 1
if cellcount % 1000 == 0:
# allow user to abort huge pattern/selection
g.dokey( g.getkey() )
# stop to capture if pattern dies
if cellcount == 0:
g.show("Pattern died too early  Only get " + str(k) + " images.")
break
if k == 0: # insert the frames for starting delay
for j in range(int(start_delay)):
list_im.append(im)
else:
list_im.append(im)
g.run(int(step))
if int(end_delay) > 0: # append the frames for ending delay
for i in range(int(end_delay)):
list_im.append(im)
# convert the images list in a GIF file
list_im[0].save(outfile,
save_all=True, append_images=list_im[1:], optimize=True, duration=int(duration), loop=0)
# remember file's directory for next time
try:
f = open(savename, 'w')
f.write(os.path.dirname(outfile))
f.close()
except:
g.warn("Unable to remember save location and last used filename for next run !")
# clean and exit
clean_exit('Animated GIF created here : '+ outfile)
Edit:
Clean version of script (not a draft )
And smaller image.
Alone we go faster … Together we go further …
Avatar's pattern
Possible uses found by Dave Green
Jormungant's explanation and uses
Currently investigating signal collisions … (stand by)
Avatar's pattern
Possible uses found by Dave Green
Jormungant's explanation and uses
Currently investigating signal collisions … (stand by)
Re: Golly scripts
ThankYou Tawal for Sharing !
(also want to note that we have giffer.lua)
(also want to note that we have giffer.lua)
"One picture is worth 1000 words; but one thousand words, carefully crafted, can paint an infinite number of pictures."
 autonomic writing
forFUN : http://viropet.com
Art Gallery : http://cgol.art
Video WebSite : http://conway.life
 autonomic writing
forFUN : http://viropet.com
Art Gallery : http://cgol.art
Video WebSite : http://conway.life
Re: Golly scripts
Version 0.3 of collector.py
New important feature: collector.py v0.3 can scan oscillators from pattern and add them to the database. Example:
Version 0.2: viewtopic.php?p=159028#p159028
To do:
Code: Select all
# collector.py
# Version 0.3
# Written by May13, December 2022  February 2024
# This script contains modified part of script written by Nathaniel Johnston, June 2009.
# Source: https://conwaylife.com/forums/viewtopic.php?p=465#p465
import golly as g
from math import ceil
fontNumber = 0
space = 2
scale = 10
count = 100
exponential = False
mx = 30
my = 30
filename = g.getstring("Enter file name:","oscillators.txt")
# 
def chunks(l, n):
for i in range(0, len(l), n):
yield l[i:i+n]
# 
def giveRLE(rl_list):
rle_res = ""
rle_len = 1
rl_y = rl_list[0][1]  1
rl_x = 0
for rl_i in rl_list:
if rl_i[1] == rl_y:
if rl_i[0] == rl_x + 1:
rle_len += 1
else:
if rle_len == 1: rle_strA = ""
else: rle_strA = str (rle_len)
if rl_i[0]  rl_x  1 == 1: rle_strB = ""
else: rle_strB = str (rl_i[0]  rl_x  1)
rle_res = rle_res + rle_strA + "o" + rle_strB + "b"
rle_len = 1
else:
if rle_len == 1: rle_strA = ""
else: rle_strA = str (rle_len)
if rl_i[1]  rl_y == 1: rle_strB = ""
else: rle_strB = str (rl_i[1]  rl_y)
if rl_i[0] == 1: rle_strC = "b"
elif rl_i[0] == 0: rle_strC = ""
else: rle_strC = str (rl_i[0]) + "b"
rle_res = rle_res + rle_strA + "o" + rle_strB + "$" + rle_strC
rle_len = 1
rl_x = rl_i[0]
rl_y = rl_i[1]
if rle_len == 1: rle_strA = ""
else: rle_strA = str (rle_len)
rle_res = rle_res[2:] + rle_strA + "o"
return rle_res
# 
def get_RLE(rect):
clist = list(chunks(g.getcells(rect), 2))
mcc = [rect[0], rect[1]]
n = g.getselrect()[1]rect[1]
clist = [[x[0]mcc[0],x[1]mcc[1]] for x in clist]
if n>1: return str(n)+'$'+giveRLE(clist)
if n==1: return '$'+giveRLE(clist)
return giveRLE(clist)
rule = g.getrule()
ruleHistory = rule + 'History'
font0 = {
'0': 'obobo2$o3bo2$o3bo2$o3bo2$obobo!',
'1': '2bo2$obo2$2bo2$2bo2$obobo!',
'2': 'obobo2$4bo2$obobo2$o2$obobo!',
'3': 'obobo2$4bo2$obobo2$4bo2$obobo!',
'4': 'o3bo2$o3bo2$obobo2$4bo2$4bo!',
'5': 'obobo2$o2$obobo2$4bo2$obobo!',
'6': 'obobo2$o2$obobo2$o3bo2$obobo!',
'7': 'obobo2$4bo2$4bo2$4bo2$4bo!',
'8': 'obobo2$o3bo2$obobo2$o3bo2$obobo!',
'9': 'obobo2$o3bo2$obobo2$4bo2$obobo!'
}
font = dict()
for i in font0.keys():
font[i] = g.parse(font0[i])
def scan_number(u, v):
cells = g.getcells([u, v, 5, 9])
if cells == []: return ''
for i in font.keys():
if len(font[i]) != len(cells): continue
p = font[i][0]  cells[0]
q = font[i][1]  cells[1]
for j in range(2, len(font[i]), 2):
if font[i][j]  cells[j] != p: break
if font[i][j+1]  cells[j+1] != q: break
else:
return i
return ''
rect = g.getrect()
upos = set()
text = []
if rect==[]: rect=[0,0,0,0]
for u in range(rect[0], rect[0]+rect[2], scale):
for v in range(rect[1], rect[1]+rect[3], scale):
cells = g.getcells([u, v, 5, 9])
n = []
U = u
while True:
c = scan_number(U, v)
if c == '': break
n.append(c)
U += 8
if len(n) > 0:
n = ''.join(n)
text.append((n, u, v))
upos.add(u)
upos = sorted(upos)
patterns = []
for i in range(len(text)):
T = text[i][0]
u1 = text[i][1]
v1 = text[i][2]
if upos.index(u1) == len(upos)1: u2 = rect[0]+rect[2]+int(T)
else: u2 = upos[upos.index(u1)+1]
if i == len(text)1 or text[i+1][1] > u1: v2 = rect[1]+rect[3]+int(T)
else: v2 = text[i+1][2]
u1 += len(T)*83
#u1 += len(T)*6+2
g.select([u1, v1, u2u1, v2v1])
g.update()
gen0 = g.getcells(g.getselrect())
g.setrule(ruleHistory)
g.run(int(T))
g.shrink(True)
rectT = g.getselrect()
g.reset()
g.setrule(rule)
g.run(int(T))
genT = g.getcells(rectT)
g.reset()
g.select(rectT)
g.update()
if gen0 != genT or rectT == []: g.warn('Invalid period' + T + ' oscillator!')
else:
g.shrink()
rle = get_RLE(rectT)
rle = f'#{T} {rectT[2]} {rectT[3]}:\n' + rle + '!\n'
patterns.append((int(T),rle))
if patterns!=[]:
try:
with open(filename) as f: l = f.read().split('!\n')
if l != ['']:
if l[1] == '': del l[1]
while l[1].endswith('!') or l[1].endswith('\n'): l[1] = l[1][:1]
for i in l: patterns.append((int(i[1:i.index(' ')]) , i+'!\n'))
except: pass
e0 = lambda e: e[0]
patterns.sort(key=e0)
duplicates = set()
for i in range(len(patterns)1):
if patterns[i][0] == patterns[i+1][0]: duplicates.add(patterns[i][0])
if len(duplicates) > 0: g.warn("Duplicate entries: "+str(sorted(duplicates)))
with open(filename, 'w') as f:
for i in patterns: f.write(i[1])
g.setrule(rule)
fonts0 = [
[{
"0": "*.*.*$.....$*...*$.....$*...*$.....$*...*$.....$*.*.*!",
"1": "..*..$.....$*.*..$.....$..*..$.....$..*..$.....$*.*.*!",
"2": "*.*.*$.....$....*$.....$*.*.*$.....$*....$.....$*.*.*!",
"3": "*.*.*$.....$....*$.....$*.*.*$.....$....*$.....$*.*.*!",
"4": "*...*$.....$*...*$.....$*.*.*$.....$....*$.....$....*!",
"5": "*.*.*$.....$*....$.....$*.*.*$.....$....*$.....$*.*.*!",
"6": "*.*.*$.....$*....$.....$*.*.*$.....$*...*$.....$*.*.*!",
"7": "*.*.*$.....$....*$.....$....*$.....$....*$.....$....*!",
"8": "*.*.*$.....$*...*$.....$*.*.*$.....$*...*$.....$*.*.*!",
"9": "*.*.*$.....$*...*$.....$*.*.*$.....$....*$.....$*.*.*!",
"M": "*...*$.....$*.*.*$.....$*.*.*$.....$*...*$.....$*...*!",
"N": "*.*..$.....$*...*$.....$*...*$.....$*...*$.....$*...*!",
"c": ".....$.....$.....$.....$..*.*$.....$*....$.....$..*.*!",
"d": "....*$.....$....*$.....$..*.*$.....$*...*$.....$..*.*!",
"o": ".....$.....$.....$.....$..*..$.....$*...*$.....$..*..!",
"+": ".....$.....$..*..$.....$*.*.*$.....$..*..$.....$.....!",
"/": "....*$.....$....*$.....$..*..$.....$*....$.....$*....!",
"(": "....*$.....$..*..$.....$..*..$.....$..*..$.....$....*!",
")": "*....$.....$..*..$.....$..*..$.....$..*..$.....$*....!",
",": ".....$.....$.....$.....$.....$.....$..*..$.....$..*..!",
},5,8,9],
[{
"0": "*..*..*$.......$.......$*.....*$.......$.......$*.....*$.......$.......$*..*..*",
"1": "...*...$.......$*......$...*...$.......$.......$...*...$.......$.......$*..*..*",
"2": "*..*..*$.......$.......$......*$...*...$.......$*......$.......$.......$*..*..*",
"3": "*..*..*$.......$.......$......*$...*...$.......$......*$.......$.......$*..*..*",
"4": "......*$.......$.......$...*..*$.......$.......$*..*..*$.......$.......$......*",
"5": "*..*..*$.......$.......$*......$...*...$.......$......*$.......$.......$*..*..*",
"6": "*..*..*$.......$.......$*......$...*...$.......$*.....*$.......$.......$*..*..*",
"7": "*..*..*$.......$.......$.....*.$.......$.......$....*..$.......$.......$...*...",
"8": "*..*..*$.......$.......$*.....*$...*...$.......$*.....*$.......$.......$*..*..*",
"9": "*..*..*$.......$.......$*.....*$...*...$.......$......*$.......$.......$*..*..*",
"M": "*..*..*$.......$...*...$*.....*$.......$.......$*.....*$.......$.......$*.....*",
"N": "*..*...$.......$.......$*.....*$.......$.......$*.....*$.......$.......$*.....*",
"c": ".......$.......$.......$...*..*$.......$.......$*......$.......$.......$...*..*",
"d": "......*$.......$.......$...*..*$.......$.......$*.....*$.......$.......$...*..*",
"o": ".......$.......$.......$...*...$.......$.......$*.....*$.......$.......$...*...",
"+": ".......$...*...$.......$.......$*..*..*$.......$.......$...*...$.......$.......",
"/": "......*$.......$.......$....*..$.......$.......$..*....$.......$.......$*......",
"(": "....*..$.......$.......$..*....$.......$.......$..*....$.......$.......$....*..",
")": "..*....$.......$.......$....*..$.......$.......$....*..$.......$.......$..*....",
",": ".......$.......$.......$.......$.......$.......$...*...$.......$.......$..*....",
},7,10,10],
]
fonts = fonts0.copy()
for i in range(len(fonts0)):
for j in fonts0[i][0].keys():
fonts[i][0][j] = fonts0[i][0][j].replace('*','o').replace('.','b')
font = fonts[fontNumber]
fw = font[1]
ft = font[2]
my = max(my,font[3])
font = font[0]
snap = lambda x: ceil(x/scale)*scale
f = open(filename)
l = [i.split(":\n") for i in f.read().split("#")[1:]]
f.close()
l = [i[0].split(" ") + [i[1]] if i != ["\n"] else [] for i in l]
g.new("Collection")
dx = 0
dy = 0
tx = 0
j = 1
textState = 0
patternState = 0
states=[".","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","pA"]
for i in range(len(l)):
if l[i]==[]:
dx += snap(tx+space)
dy = 0
tx = 0
if exponential: count *= 2
continue
if len(l[i])==5: patternState = int(l[i][3])
elif len(l[i])==6:
textState = int(l[i][3])
patternState = int(l[i][4])
p = l[i][0]
i00 = ""
i0 = "0"
if "/" in p: i00=p.split("/")[1]
else: i00 = p
for ch in i00:
if ch in "0123456789": i0 += ch
i0 = int(i0)
if count>0 and (ceil(i0/count)!=ceil(j/count) or i0<j):
dx += snap(tx+space)
dy = 0
tx = 0
if exponential: count *= 2
fx = 0
for k in range(len(p)):
char = font[p[k]]
if textState > 0: char = char.replace("*",states[textState])
g.putcells(g.parse(char), dx+fx, dy)
fx += ft
fx = snap(max(fx+fwft+space, mx))
if patternState > 0: l[i][1] = l[i][1].replace("b",".").replace("o",states[patternState]).replace("*",states[patternState])
g.putcells(g.parse(l[i][1]), dx+fx, dy)
tx = max(tx, fx+int(l[i][1]))
dy += snap(max(int(l[i][2])+space, my))
j = i0
g.fit()
 Open Golly, then make this pattern:
Code: Select all
x = 193, y = 61, rule = B3/S23 2bo7b2o18bobobo3bobobo57bo3bo5bo43bo$10b2o41b3o30b3o63b3o$obo31bo3bo3b o57bo3bo3bobo40bo$51bo5bo2b2o18b2o2bo5bo45b2o13b2o$2bo27bobobo3bobobo 8bo4b2o4bo16bo4b2o4bo9bobobo5bo26bo$51bo11bo14bo11bo46bobo$2bo31bo3bo 3bo19b2o14b2o24bo5bo27b2o$148bo$obobo25bobobo3bobobo61bo3bobobo34bo$ 56b2o26b2o63bo$56bo28bo61b3o$57b3o22b3o$59bo22bo2$160bo$125b2o24b2o5bo bo$126bo24bo7b2o$124bo13b2o12b3o$122b4o15b2o11bo$121bo14b2obo$obobo13b 2o100bo2b3o10b2o3bob2o$10b3o5b2o101b2o2bo10b2obo3b2o$4bo11b2o105b2o16b ob2o$16b2o105bo14b2o$obobo119bo6b3o7b2o26bo$121b3o7bo38b2o$o120bo5b2o 3bo11bo24b2o$128bo14bobo$obobo120b3o15b2o$125bo2$187bo$168b2o15b3o$ 167bobo14bo$142b2o24bo11bo3b2o5bo$141b2o38bo7b3o$143bo26b2o7b3o6bo$ 173b2o14bo$168b2obo16b2o$168b2o3bob2o10bo2b2o$168b2obo3b2o10b3o2bo$ 173bob2o14bo$158bo11b2o15b4o$158b3o12b2o13bo$152b2o7bo24bo$152bobo5b2o 24b2o$152bo4$163b3o$163bo$165bo$164bo$173b2o$173bobo$175bo$160b2o13b2o $161bo$158b3o$158bo!
 Run collector.py, then enter filename;
 Then you will see an oscillator collection like this one:
Code: Select all
x = 103, y = 151, rule = B3/S23 2bo27b2o$30b2o$obo2$2bo2$2bo2$obobo22$obobo33b2o$30b3o5b2o$4bo31b2o$ 36b2o$obobo2$o2$obobo22$obobo3bobobo$33b3o30b3o$4bo3bo3bo$31bo5bo2b2o 18b2o2bo5bo$obobo3bobobo18bo4b2o4bo16bo4b2o4bo$31bo11bo14bo11bo$4bo3bo 3bo29b2o14b2o2$obobo3bobobo$36b2o26b2o$36bo28bo$37b3o22b3o$39bo22bo18$ o3bo5bo53bo$62b3o$o3bo3bobo50bo$46b2o13b2o$obobo5bo36bo$47bobo$4bo5bo 37b2o$58bo$4bo3bobobo44bo$59bo$57b3o4$70bo$35b2o24b2o5bobo$36bo24bo7b 2o$34bo13b2o12b3o$32b4o15b2o11bo$31bo14b2obo$30bo2b3o10b2o3bob2o$31b2o 2bo10b2obo3b2o$33b2o16bob2o$33bo14b2o$34bo6b3o7b2o26bo$31b3o7bo38b2o$ 31bo5b2o3bo11bo24b2o$38bo14bobo$35b3o15b2o$35bo2$97bo$78b2o15b3o$77bob o14bo$52b2o24bo11bo3b2o5bo$51b2o38bo7b3o$53bo26b2o7b3o6bo$83b2o14bo$ 78b2obo16b2o$78b2o3bob2o10bo2b2o$78b2obo3b2o10b3o2bo$83bob2o14bo$68bo 11b2o15b4o$68b3o12b2o13bo$62b2o7bo24bo$62bobo5b2o24b2o$62bo4$73b3o$73b o$75bo$74bo$83b2o$83bobo$85bo$70b2o13b2o$71bo$68b3o$68bo!
Code: Select all
x = 103, y = 181, rule = B3/S23
2bo27b2o$30b2o$obo2$2bo2$2bo2$obobo22$obobo33b2o$30b3o5b2o$4bo31b2o$
36b2o$obobo2$o2$obobo22$obobo$33b3o3b3o$4bo$31bo4bobo4bo$obobo26bo4bob
o4bo$31bo4bobo4bo$4bo28b3o3b3o2$obobo28b3o3b3o$31bo4bobo4bo$31bo4bobo
4bo$31bo4bobo4bo2$33b3o3b3o17$obobo3bobobo$33b3o30b3o$4bo3bo3bo$31bo5b
o2b2o18b2o2bo5bo$obobo3bobobo18bo4b2o4bo16bo4b2o4bo$31bo11bo14bo11bo$
4bo3bo3bo29b2o14b2o2$obobo3bobobo$36b2o26b2o$36bo28bo$37b3o22b3o$39bo
22bo18$o3bo5bo53bo$62b3o$o3bo3bobo50bo$46b2o13b2o$obobo5bo36bo$47bobo$
4bo5bo37b2o$58bo$4bo3bobobo44bo$59bo$57b3o4$70bo$35b2o24b2o5bobo$36bo
24bo7b2o$34bo13b2o12b3o$32b4o15b2o11bo$31bo14b2obo$30bo2b3o10b2o3bob2o
$31b2o2bo10b2obo3b2o$33b2o16bob2o$33bo14b2o$34bo6b3o7b2o26bo$31b3o7bo
38b2o$31bo5b2o3bo11bo24b2o$38bo14bobo$35b3o15b2o$35bo2$97bo$78b2o15b3o
$77bobo14bo$52b2o24bo11bo3b2o5bo$51b2o38bo7b3o$53bo26b2o7b3o6bo$83b2o
14bo$78b2obo16b2o$78b2o3bob2o10bo2b2o$78b2obo3b2o10b3o2bo$83bob2o14bo$
68bo11b2o15b4o$68b3o12b2o13bo$62b2o7bo24bo$62bobo5b2o24b2o$62bo4$73b3o
$73bo$75bo$74bo$83b2o$83bobo$85bo$70b2o13b2o$71bo$68b3o$68bo!
To do:
 Support more fonts
 Implement faster scanning algorithm
The latest version of hexgliders.db have 668 gliders from OT hexagonal rules. Let's find more!
My CA (13 rules)
My scripts: newglider.py v0.2, nbsearch2a.py, collector.py v0.3
My CA (13 rules)
My scripts: newglider.py v0.2, nbsearch2a.py, collector.py v0.3
Re: Golly scripts
There's been some work recently on a project to clean up some of the overuse of the LifeWiki userspace for miscellaneous data storage.
For a set of several hundred "datadump" userspace pages related to photon partials, wwei47 mentioned that it would be okay to remove them from the LifeWiki if there was a way to do a bulk download.
Bulk downloads are not particularly difficult to do with a Python script, so I've written one that works for this specific problem:
The details that are unique to this specific problem are
1) the list of articles at the top of the script,
2) the fact that each automaticallygenerated article started with "<pre>" and ended with "</pre>", so there's a little bit of code at the end that extracts just the text between "<pre>" and "</pre>" and sends that to a file.
Something very similar could be done for other LifeWiki data extraction problems, with minor changes to the code.
Not as big as I thought...
It turns out that when you compress the script's output files, they only come to 1.2 megabytes. Here's the archive:
For a set of several hundred "datadump" userspace pages related to photon partials, wwei47 mentioned that it would be okay to remove them from the LifeWiki if there was a way to do a bulk download.
Bulk downloads are not particularly difficult to do with a Python script, so I've written one that works for this specific problem:
Code: Select all
import golly as g
import urllib.request
from urllib.request import urlopen, Request
import os
outpath = g.getstring("Enter base path for output files, using '/' as folder delimiter","C:/users/{username}/Desktop/out/")
if outpath == "C:/users/{username}/Desktop/out/":
g.note("Please run this script again and change the sample path to something that works on your system.")
g.exit()
if not outpath.endswith("/"):
outpath += "/"
pages = """User:Prime Raptor21/Photon partials for 5S/P31
User:Prime Raptor21/Photon partials for 5S/P37
User:Prime Raptor21/Photon partials for 5S/P38
User:Prime Raptor21/Photon partials for 5S/P39
User:Prime Raptor21/Photon partials for 5S/P41
User:Prime Raptor21/Photon partials for 5S/P43
User:Prime Raptor21/Photon partials for 5S/P44
User:Prime Raptor21/Photon partials for 5S/P45
User:Prime Raptor21/Photon partials for 5S/P46
User:Prime Raptor21/Photon partials for 5S/P47
User:Prime Raptor21/Photon partials for 5S/P48
User:Prime Raptor21/Photon partials for 5S/P49
User:Prime Raptor21/Photon partials for 5S/P50
User:Prime Raptor21/Photon partials for 5S/P51
User:Prime Raptor21/Photon partials for 5S/P52
User:Prime Raptor21/Photon partials for 5S/P53
User:Prime Raptor21/Photon partials for 5S/P54
User:Prime Raptor21/Photon partials for 5S/P55
User:Prime Raptor21/Photon partials for 5S/P56
User:Prime Raptor21/Photon partials for 5S/P57
User:Prime Raptor21/Photon partials for 5S/P58
User:Prime Raptor21/Photon partials for 5S/P59
User:Prime Raptor21/Photon partials for 5S/P61
User:Prime Raptor21/Photon partials for 5S/P62
User:Prime Raptor21/Photon partials for 5S/P63
User:Prime Raptor21/Photon partials for 5S/P64
User:Prime Raptor21/Photon partials for 5S/P65
User:Prime Raptor21/Photon partials for 5S/P66
User:Prime Raptor21/Photon partials for 5S/P67
User:Prime Raptor21/Photon partials for 5S/P68
User:Prime Raptor21/Photon partials for 5S/P69
User:Prime Raptor21/Photon partials for 5S/P70
User:Prime Raptor21/Photon partials for 5S/P71
User:Prime Raptor21/Photon partials for 5S/P72
User:Prime Raptor21/Photon partials for 5S/P73
User:Prime Raptor21/Photon partials for 5S/P74
User:Prime Raptor21/Photon partials for 5S/P75
User:Prime Raptor21/Photon partials for 5S/P76
User:Prime Raptor21/Photon partials for 5S/P77
User:Prime Raptor21/Photon partials for 5S/P78
User:Prime Raptor21/Photon partials for 5S/P79
User:Prime Raptor21/Photon partials for 5S/P80
User:Prime Raptor21/Photon partials for 5S/P81
User:Prime Raptor21/Photon partials for 5S/P82
User:Prime Raptor21/Photon partials for 5S/P83
User:Prime Raptor21/Photon partials for 5S/P84
User:Prime Raptor21/Photon partials for 5S/P85
User:Prime Raptor21/Photon partials for 5S/P86
User:Prime Raptor21/Photon partials for 5S/P87
User:Prime Raptor21/Photon partials for 5S/P88
User:Prime Raptor21/Photon partials for 5S/P89
User:Prime Raptor21/Photon partials for 5S/P90
User:Prime Raptor21/Photon partials for 5S/P91
User:Prime Raptor21/Photon partials for 5S/P92
User:Prime Raptor21/Photon partials for 5S/P93
User:Prime Raptor21/Photon partials for 5S/P94
User:Prime Raptor21/Photon partials for 5S/P95
User:Prime Raptor21/Photon partials for 5S/P96
User:Prime Raptor21/Photon partials for 5S/P97
User:Prime Raptor21/Photon partials for 5S/P98
User:Prime Raptor21/Photon partials for 5S/P99
User:Prime Raptor21/Photon partials for 5S/P100
User:Prime Raptor21/Photon partials for 5S/P101
User:Prime Raptor21/Photon partials for 5S/P102
User:Prime Raptor21/Photon partials for 5S/P103
User:Prime Raptor21/Photon partials for 5S/P104
User:Prime Raptor21/Photon partials for 5S/P105
User:Prime Raptor21/Photon partials for 5S/P106
User:Prime Raptor21/Photon partials for 5S/P107
User:Prime Raptor21/Photon partials for 5S/P108
User:Prime Raptor21/Photon partials for 5S/P109
User:Prime Raptor21/Photon partials for 5S/P110
User:Prime Raptor21/Photon partials for 5S/P111
User:Prime Raptor21/Photon partials for 5S/P112
User:Prime Raptor21/Photon partials for 5S/P113
User:Prime Raptor21/Photon partials for 5S/P114
User:Prime Raptor21/Photon partials for 5S/P115
User:Prime Raptor21/Photon partials for 5S/P116
User:Prime Raptor21/Photon partials for 5S/P117
User:Prime Raptor21/Photon partials for 5S/P118
User:Prime Raptor21/Photon partials for 5S/P119
User:Prime Raptor21/Photon partials for 5S/P120
User:Prime Raptor21/Photon partials for 5S/P122
User:Prime Raptor21/Photon partials for 5S/P123
User:Prime Raptor21/Photon partials for 5S/P124
User:Prime Raptor21/Photon partials for 5S/P125
User:Prime Raptor21/Photon partials for 5S/P126
User:Prime Raptor21/Photon partials for 5S/P127
User:Prime Raptor21/Photon partials for 5S/P128
User:Prime Raptor21/Photon partials for 5S/P129
User:Prime Raptor21/Photon partials for 5S/P130
User:Prime Raptor21/Photon partials for 5S/P131
User:Prime Raptor21/Photon partials for 5S/P132
User:Prime Raptor21/Photon partials for 5S/P133
User:Prime Raptor21/Photon partials for 5S/P134
User:Prime Raptor21/Photon partials for 5S/P135
User:Prime Raptor21/Photon partials for 5S/P136
User:Prime Raptor21/Photon partials for 5S/P137
User:Prime Raptor21/Photon partials for 5S/P138
User:Prime Raptor21/Photon partials for 5S/P139
User:Prime Raptor21/Photon partials for 5S/P140
User:Prime Raptor21/Photon partials for 5S/P141
User:Prime Raptor21/Photon partials for 5S/P142
User:Prime Raptor21/Photon partials for 5S/P143
User:Prime Raptor21/Photon partials for 5S/P144
User:Prime Raptor21/Photon partials for 5S/P145
User:Prime Raptor21/Photon partials for 5S/P146
User:Prime Raptor21/Photon partials for 5S/P147
User:Prime Raptor21/Photon partials for 5S/P148
User:Prime Raptor21/Photon partials for 5S/P149
User:Prime Raptor21/Photon partials for 5S/P150
User:Prime Raptor21/Photon partials for 5S/P151
User:Prime Raptor21/Photon partials for 5S/P152
User:Prime Raptor21/Photon partials for 5S/P153
User:Prime Raptor21/Photon partials for 5S/P154
User:Prime Raptor21/Photon partials for 5S/P155
User:Prime Raptor21/Photon partials for 5S/P156
User:Prime Raptor21/Photon partials for 5S/P157
User:Prime Raptor21/Photon partials for 5S/P158
User:Prime Raptor21/Photon partials for 5S/P160
User:Prime Raptor21/Photon partials for 5S/P161
User:Prime Raptor21/Photon partials for 5S/P162
User:Prime Raptor21/Photon partials for 5S/P163
User:Prime Raptor21/Photon partials for 5S/P164
User:Prime Raptor21/Photon partials for 5S/P165
User:Prime Raptor21/Photon partials for 5S/P166
User:Prime Raptor21/Photon partials for 5S/P168
User:Prime Raptor21/Photon partials for 5S/P169
User:Prime Raptor21/Photon partials for 5S/P170
User:Prime Raptor21/Photon partials for 5S/P171
User:Prime Raptor21/Photon partials for 5S/P172
User:Prime Raptor21/Photon partials for 5S/P174
User:Prime Raptor21/Photon partials for 5S/P175
User:Prime Raptor21/Photon partials for 5S/P176
User:Prime Raptor21/Photon partials for 5S/P177
User:Prime Raptor21/Photon partials for 5S/P180
User:Prime Raptor21/Photon partials for 5S/P181
User:Prime Raptor21/Photon partials for 5S/P182
User:Prime Raptor21/Photon partials for 5S/P184
User:Prime Raptor21/Photon partials for 5S/P186
User:Prime Raptor21/Photon partials for 5S/P187
User:Prime Raptor21/Photon partials for 5S/P188
User:Prime Raptor21/Photon partials for 5S/P189
User:Prime Raptor21/Photon partials for 5S/P190
User:Prime Raptor21/Photon partials for 5S/P194
User:Prime Raptor21/Photon partials for 5S/P195
User:Prime Raptor21/Photon partials for 5S/P197
User:Prime Raptor21/Photon partials for 5S/P198
User:Prime Raptor21/Photon partials for 5S/P200
User:Prime Raptor21/Photon partials for 5S/P202
User:Prime Raptor21/Photon partials for 5S/P203
User:Prime Raptor21/Photon partials for 5S/P204
User:Prime Raptor21/Photon partials for 5S/P205
User:Prime Raptor21/Photon partials for 5S/P206
User:Prime Raptor21/Photon partials for 5S/P208
User:Prime Raptor21/Photon partials for 5S/P209
User:Prime Raptor21/Photon partials for 5S/P210
User:Prime Raptor21/Photon partials for 5S/P217
User:Prime Raptor21/Photon partials for 5S/P220
User:Prime Raptor21/Photon partials for 5S/P224
User:Prime Raptor21/Photon partials for 5S/P226
User:Prime Raptor21/Photon partials for 5S/P228
User:Prime Raptor21/Photon partials for 5S/P230
User:Prime Raptor21/Photon partials for 5S/P232
User:Prime Raptor21/Photon partials for 5S/P236
User:Prime Raptor21/Photon partials for 5S/P238
User:Prime Raptor21/Photon partials for 5S/P249
User:Prime Raptor21/Photon partials for 5S/P252
User:Prime Raptor21/Photon partials for 5S/P254
User:Prime Raptor21/Photon partials for 5S/P255
User:Prime Raptor21/Photon partials for 5S/P258
User:Prime Raptor21/Photon partials for 5S/P260
User:Prime Raptor21/Photon partials for 5S/P271
User:Prime Raptor21/Photon partials for 5S/P282
User:Prime Raptor21/Photon partials for 5S/P284
User:Prime Raptor21/Photon partials for 5S/P296
User:Prime Raptor21/Photon partials for 5S/P309
User:Prime Raptor21/Photon partials for 5S/P335
User:Prime Raptor21/Photon partials for 5S/P376
User:Prime Raptor21/Photon partials for 5S/P378
User:Prime Raptor21/Photon partials for 5S/P383
User:Prime Raptor21/Photon partials for 5S/P392
User:Prime Raptor21/Photon partials for 5S/P213
User:Prime Raptor21/Photon partials for 5S/P215
User:Prime Raptor21/Photon partials for 5S/P216
User:Prime Raptor21/Photon partials for 5S/P218
User:Prime Raptor21/Photon partials for 5S/P225
User:Prime Raptor21/Photon partials for 5S/P231
User:Prime Raptor21/Photon partials for 5S/P234
User:Prime Raptor21/Photon partials for 5S/P240
User:Prime Raptor21/Photon partials for 5S/P242
User:Prime Raptor21/Photon partials for 5S/P250
User:Prime Raptor21/Photon partials for 5S/P251
User:Prime Raptor21/Photon partials for 5S/P264
User:Prime Raptor21/Photon partials for 5S/P265
User:Prime Raptor21/Photon partials for 5S/P270
User:Prime Raptor21/Photon partials for 5S/P273
User:Prime Raptor21/Photon partials for 5S/P278
User:Prime Raptor21/Photon partials for 5S/P280
User:Prime Raptor21/Photon partials for 5S/P283
User:Prime Raptor21/Photon partials for 5S/P286
User:Prime Raptor21/Photon partials for 5S/P287
User:Prime Raptor21/Photon partials for 5S/P290
User:Prime Raptor21/Photon partials for 5S/P298
User:Prime Raptor21/Photon partials for 5S/P300
User:Prime Raptor21/Photon partials for 5S/P308
User:Prime Raptor21/Photon partials for 5S/P312
User:Prime Raptor21/Photon partials for 5S/P314
User:Prime Raptor21/Photon partials for 5S/P315
User:Prime Raptor21/Photon partials for 5S/P322
User:Prime Raptor21/Photon partials for 5S/P324
User:Prime Raptor21/Photon partials for 5S/P329
User:Prime Raptor21/Photon partials for 5S/P338
User:Prime Raptor21/Photon partials for 5S/P339
User:Prime Raptor21/Photon partials for 5S/P344
User:Prime Raptor21/Photon partials for 5S/P348
User:Prime Raptor21/Photon partials for 5S/P354
User:Prime Raptor21/Photon partials for 5S/P360
User:Prime Raptor21/Photon partials for 5S/P366
User:Prime Raptor21/Photon partials for 5S/P370
User:Prime Raptor21/Photon partials for 5S/P372
User:Prime Raptor21/Photon partials for 5S/P385
User:Prime Raptor21/Photon partials for 5S/P407
User:Prime Raptor21/Photon partials for 5S/P411
User:Prime Raptor21/Photon partials for 5S/P412
User:Prime Raptor21/Photon partials for 5S/P414
User:Prime Raptor21/Photon partials for 5S/P415
User:Prime Raptor21/Photon partials for 5S/P417
User:Prime Raptor21/Photon partials for 5S/P420
User:Prime Raptor21/Photon partials for 5S/P434
User:Prime Raptor21/Photon partials for 5S/P441
User:Prime Raptor21/Photon partials for 5S/P446
User:Prime Raptor21/Photon partials for 5S/P447
User:Prime Raptor21/Photon partials for 5S/P462
User:Prime Raptor21/Photon partials for 5S/P465
User:Prime Raptor21/Photon partials for 5S/P479
User:Prime Raptor21/Photon partials for 5S/P487
User:Prime Raptor21/Photon partials for 5S/P492
User:Prime Raptor21/Photon partials for 5S/P502
User:Prime Raptor21/Photon partials for 5S/P504
User:Prime Raptor21/Photon partials for 5S/P508
User:Prime Raptor21/Photon partials for 5S/P510
User:Prime Raptor21/Photon partials for 5S/P511
User:Prime Raptor21/Photon partials for 5S/P538
User:Prime Raptor21/Photon partials for 5S/P540
User:Prime Raptor21/Photon partials for 5S/P616
User:Prime Raptor21/Photon partials for 5S/P623
User:Prime Raptor21/Photon partials for 5S/P658
User:Prime Raptor21/Photon partials for 5S/P679
User:Prime Raptor21/Photon partials for 5S/P717
User:Prime Raptor21/Photon partials for 5S/P732
User:Prime Raptor21/Photon partials for 5S/P734
User:Prime Raptor21/Photon partials for 5S/P757
User:Prime Raptor21/Photon partials for 5S/P778
User:Prime Raptor21/Photon partials for 5S/P788
User:Prime Raptor21/Photon partials for 5S/P889
User:Prime Raptor21/Photon partials for 5S/P982
User:Prime Raptor21/Photon partials for 5S/P1006
User:Prime Raptor21/Photon partials for 5S/P1018
User:Prime Raptor21/Photon partials for 5S/P1022
User:Prime Raptor21/Photon partials for 5S/P1436
User:Prime Raptor21/Photon partials for 5S/P1636
User:Prime Raptor21/Photon partials for 5S/The Vault/P31
User:Prime Raptor21/Photon partials for 5S/The Vault/P37
User:Prime Raptor21/Photon partials for 5S/The Vault/P38
User:Prime Raptor21/Photon partials for 5S/The Vault/P39
User:Prime Raptor21/Photon partials for 5S/The Vault/P41
User:Prime Raptor21/Photon partials for 5S/The Vault/P43
User:Prime Raptor21/Photon partials for 5S/The Vault/P44
User:Prime Raptor21/Photon partials for 5S/The Vault/P45
User:Prime Raptor21/Photon partials for 5S/The Vault/P46
User:Prime Raptor21/Photon partials for 5S/The Vault/P47
User:Prime Raptor21/Photon partials for 5S/The Vault/P48
User:Prime Raptor21/Photon partials for 5S/The Vault/P49
User:Prime Raptor21/Photon partials for 5S/The Vault/P50
User:Prime Raptor21/Photon partials for 5S/The Vault/P51
User:Prime Raptor21/Photon partials for 5S/The Vault/P52
User:Prime Raptor21/Photon partials for 5S/The Vault/P53
User:Prime Raptor21/Photon partials for 5S/The Vault/P54
User:Prime Raptor21/Photon partials for 5S/The Vault/P55
User:Prime Raptor21/Photon partials for 5S/The Vault/P56
User:Prime Raptor21/Photon partials for 5S/The Vault/P57
User:Prime Raptor21/Photon partials for 5S/The Vault/P58
User:Prime Raptor21/Photon partials for 5S/The Vault/P59
User:Prime Raptor21/Photon partials for 5S/The Vault/P61
User:Prime Raptor21/Photon partials for 5S/The Vault/P62
User:Prime Raptor21/Photon partials for 5S/The Vault/P63
User:Prime Raptor21/Photon partials for 5S/The Vault/P64
User:Prime Raptor21/Photon partials for 5S/The Vault/P65
User:Prime Raptor21/Photon partials for 5S/The Vault/P66
User:Prime Raptor21/Photon partials for 5S/The Vault/P67
User:Prime Raptor21/Photon partials for 5S/The Vault/P68
User:Prime Raptor21/Photon partials for 5S/The Vault/P69
User:Prime Raptor21/Photon partials for 5S/The Vault/P70
User:Prime Raptor21/Photon partials for 5S/The Vault/P71
User:Prime Raptor21/Photon partials for 5S/The Vault/P72
User:Prime Raptor21/Photon partials for 5S/The Vault/P73
User:Prime Raptor21/Photon partials for 5S/The Vault/P74
User:Prime Raptor21/Photon partials for 5S/The Vault/P75
User:Prime Raptor21/Photon partials for 5S/The Vault/P76
User:Prime Raptor21/Photon partials for 5S/The Vault/P77
User:Prime Raptor21/Photon partials for 5S/The Vault/P78
User:Prime Raptor21/Photon partials for 5S/The Vault/P79
User:Prime Raptor21/Photon partials for 5S/The Vault/P80
User:Prime Raptor21/Photon partials for 5S/The Vault/P81
User:Prime Raptor21/Photon partials for 5S/The Vault/P82
User:Prime Raptor21/Photon partials for 5S/The Vault/P83
User:Prime Raptor21/Photon partials for 5S/The Vault/P84
User:Prime Raptor21/Photon partials for 5S/The Vault/P85
User:Prime Raptor21/Photon partials for 5S/The Vault/P86
User:Prime Raptor21/Photon partials for 5S/The Vault/P87
User:Prime Raptor21/Photon partials for 5S/The Vault/P88
User:Prime Raptor21/Photon partials for 5S/The Vault/P89
User:Prime Raptor21/Photon partials for 5S/The Vault/P90
User:Prime Raptor21/Photon partials for 5S/The Vault/P91
User:Prime Raptor21/Photon partials for 5S/The Vault/P92
User:Prime Raptor21/Photon partials for 5S/The Vault/P93
User:Prime Raptor21/Photon partials for 5S/The Vault/P94
User:Prime Raptor21/Photon partials for 5S/The Vault/P95
User:Prime Raptor21/Photon partials for 5S/The Vault/P96
User:Prime Raptor21/Photon partials for 5S/The Vault/P97
User:Prime Raptor21/Photon partials for 5S/The Vault/P98
User:Prime Raptor21/Photon partials for 5S/The Vault/P99
User:Prime Raptor21/Photon partials for 5S/The Vault/P100
User:Prime Raptor21/Photon partials for 5S/The Vault/P101
User:Prime Raptor21/Photon partials for 5S/The Vault/P102
User:Prime Raptor21/Photon partials for 5S/The Vault/P103
User:Prime Raptor21/Photon partials for 5S/The Vault/P104
User:Prime Raptor21/Photon partials for 5S/The Vault/P105
User:Prime Raptor21/Photon partials for 5S/The Vault/P106
User:Prime Raptor21/Photon partials for 5S/The Vault/P107
User:Prime Raptor21/Photon partials for 5S/The Vault/P108
User:Prime Raptor21/Photon partials for 5S/The Vault/P109
User:Prime Raptor21/Photon partials for 5S/The Vault/P110
User:Prime Raptor21/Photon partials for 5S/The Vault/P111
User:Prime Raptor21/Photon partials for 5S/The Vault/P112
User:Prime Raptor21/Photon partials for 5S/The Vault/P113
User:Prime Raptor21/Photon partials for 5S/The Vault/P114
User:Prime Raptor21/Photon partials for 5S/The Vault/P115
User:Prime Raptor21/Photon partials for 5S/The Vault/P116
User:Prime Raptor21/Photon partials for 5S/The Vault/P117
User:Prime Raptor21/Photon partials for 5S/The Vault/P118
User:Prime Raptor21/Photon partials for 5S/The Vault/P119
User:Prime Raptor21/Photon partials for 5S/The Vault/P120
User:Prime Raptor21/Photon partials for 5S/The Vault/P121
User:Prime Raptor21/Photon partials for 5S/The Vault/P122
User:Prime Raptor21/Photon partials for 5S/The Vault/P123
User:Prime Raptor21/Photon partials for 5S/The Vault/P124
User:Prime Raptor21/Photon partials for 5S/The Vault/P125
User:Prime Raptor21/Photon partials for 5S/The Vault/P126
User:Prime Raptor21/Photon partials for 5S/The Vault/P127
User:Prime Raptor21/Photon partials for 5S/The Vault/P128
User:Prime Raptor21/Photon partials for 5S/The Vault/P129
User:Prime Raptor21/Photon partials for 5S/The Vault/P130
User:Prime Raptor21/Photon partials for 5S/The Vault/P131
User:Prime Raptor21/Photon partials for 5S/The Vault/P132
User:Prime Raptor21/Photon partials for 5S/The Vault/P133
User:Prime Raptor21/Photon partials for 5S/The Vault/P134
User:Prime Raptor21/Photon partials for 5S/The Vault/P135
User:Prime Raptor21/Photon partials for 5S/The Vault/P136
User:Prime Raptor21/Photon partials for 5S/The Vault/P137
User:Prime Raptor21/Photon partials for 5S/The Vault/P138
User:Prime Raptor21/Photon partials for 5S/The Vault/P139
User:Prime Raptor21/Photon partials for 5S/The Vault/P140
User:Prime Raptor21/Photon partials for 5S/The Vault/P141
User:Prime Raptor21/Photon partials for 5S/The Vault/P142
User:Prime Raptor21/Photon partials for 5S/The Vault/P143
User:Prime Raptor21/Photon partials for 5S/The Vault/P144
User:Prime Raptor21/Photon partials for 5S/The Vault/P145
User:Prime Raptor21/Photon partials for 5S/The Vault/P146
User:Prime Raptor21/Photon partials for 5S/The Vault/P147
User:Prime Raptor21/Photon partials for 5S/The Vault/P148
User:Prime Raptor21/Photon partials for 5S/The Vault/P149
User:Prime Raptor21/Photon partials for 5S/The Vault/P150
User:Prime Raptor21/Photon partials for 5S/The Vault/P151
User:Prime Raptor21/Photon partials for 5S/The Vault/P152
User:Prime Raptor21/Photon partials for 5S/The Vault/P153
User:Prime Raptor21/Photon partials for 5S/The Vault/P154
User:Prime Raptor21/Photon partials for 5S/The Vault/P155
User:Prime Raptor21/Photon partials for 5S/The Vault/P156
User:Prime Raptor21/Photon partials for 5S/The Vault/P157
User:Prime Raptor21/Photon partials for 5S/The Vault/P158
User:Prime Raptor21/Photon partials for 5S/The Vault/P159
User:Prime Raptor21/Photon partials for 5S/The Vault/P160
User:Prime Raptor21/Photon partials for 5S/The Vault/P161
User:Prime Raptor21/Photon partials for 5S/The Vault/P162
User:Prime Raptor21/Photon partials for 5S/The Vault/P163
User:Prime Raptor21/Photon partials for 5S/The Vault/P164
User:Prime Raptor21/Photon partials for 5S/The Vault/P165
User:Prime Raptor21/Photon partials for 5S/The Vault/P166
User:Prime Raptor21/Photon partials for 5S/The Vault/P167
User:Prime Raptor21/Photon partials for 5S/The Vault/P168
User:Prime Raptor21/Photon partials for 5S/The Vault/P169
User:Prime Raptor21/Photon partials for 5S/The Vault/P170
User:Prime Raptor21/Photon partials for 5S/The Vault/P171
User:Prime Raptor21/Photon partials for 5S/The Vault/P172
User:Prime Raptor21/Photon partials for 5S/The Vault/P173
User:Prime Raptor21/Photon partials for 5S/The Vault/P174
User:Prime Raptor21/Photon partials for 5S/The Vault/P175
User:Prime Raptor21/Photon partials for 5S/The Vault/P176
User:Prime Raptor21/Photon partials for 5S/The Vault/P177
User:Prime Raptor21/Photon partials for 5S/The Vault/P178
User:Prime Raptor21/Photon partials for 5S/The Vault/P179
User:Prime Raptor21/Photon partials for 5S/The Vault/P180
User:Prime Raptor21/Photon partials for 5S/The Vault/P181
User:Prime Raptor21/Photon partials for 5S/The Vault/P182
User:Prime Raptor21/Photon partials for 5S/The Vault/P183
User:Prime Raptor21/Photon partials for 5S/The Vault/P184
User:Prime Raptor21/Photon partials for 5S/The Vault/P185
User:Prime Raptor21/Photon partials for 5S/The Vault/P186
User:Prime Raptor21/Photon partials for 5S/The Vault/P187
User:Prime Raptor21/Photon partials for 5S/The Vault/P188
User:Prime Raptor21/Photon partials for 5S/The Vault/P189
User:Prime Raptor21/Photon partials for 5S/The Vault/P190
User:Prime Raptor21/Photon partials for 5S/The Vault/P191
User:Prime Raptor21/Photon partials for 5S/The Vault/P192
User:Prime Raptor21/Photon partials for 5S/The Vault/P193
User:Prime Raptor21/Photon partials for 5S/The Vault/P194
User:Prime Raptor21/Photon partials for 5S/The Vault/P196
User:Prime Raptor21/Photon partials for 5S/The Vault/P197
User:Prime Raptor21/Photon partials for 5S/The Vault/P198
User:Prime Raptor21/Photon partials for 5S/The Vault/P199
User:Prime Raptor21/Photon partials for 5S/The Vault/P200
User:Prime Raptor21/Photon partials for 5S/The Vault/P201
User:Prime Raptor21/Photon partials for 5S/The Vault/P202
User:Prime Raptor21/Photon partials for 5S/The Vault/P203
User:Prime Raptor21/Photon partials for 5S/The Vault/P204
User:Prime Raptor21/Photon partials for 5S/The Vault/P205
User:Prime Raptor21/Photon partials for 5S/The Vault/P206
User:Prime Raptor21/Photon partials for 5S/The Vault/P207
User:Prime Raptor21/Photon partials for 5S/The Vault/P208
User:Prime Raptor21/Photon partials for 5S/The Vault/P209
User:Prime Raptor21/Photon partials for 5S/The Vault/P210
User:Prime Raptor21/Photon partials for 5S/The Vault/P212
User:Prime Raptor21/Photon partials for 5S/The Vault/P213
User:Prime Raptor21/Photon partials for 5S/The Vault/P214
User:Prime Raptor21/Photon partials for 5S/The Vault/P215
User:Prime Raptor21/Photon partials for 5S/The Vault/P216
User:Prime Raptor21/Photon partials for 5S/The Vault/P217
User:Prime Raptor21/Photon partials for 5S/The Vault/P218
User:Prime Raptor21/Photon partials for 5S/The Vault/P219
User:Prime Raptor21/Photon partials for 5S/The Vault/P220
User:Prime Raptor21/Photon partials for 5S/The Vault/P221
User:Prime Raptor21/Photon partials for 5S/The Vault/P222
User:Prime Raptor21/Photon partials for 5S/The Vault/P223
User:Prime Raptor21/Photon partials for 5S/The Vault/P225
User:Prime Raptor21/Photon partials for 5S/The Vault/P228
User:Prime Raptor21/Photon partials for 5S/The Vault/P230
User:Prime Raptor21/Photon partials for 5S/The Vault/P231
User:Prime Raptor21/Photon partials for 5S/The Vault/P233
User:Prime Raptor21/Photon partials for 5S/The Vault/P234
User:Prime Raptor21/Photon partials for 5S/The Vault/P236
User:Prime Raptor21/Photon partials for 5S/The Vault/P238
User:Prime Raptor21/Photon partials for 5S/The Vault/P239
User:Prime Raptor21/Photon partials for 5S/The Vault/P240
User:Prime Raptor21/Photon partials for 5S/The Vault/P241
User:Prime Raptor21/Photon partials for 5S/The Vault/P247
User:Prime Raptor21/Photon partials for 5S/The Vault/P248
User:Prime Raptor21/Photon partials for 5S/The Vault/P252
User:Prime Raptor21/Photon partials for 5S/The Vault/P254
User:Prime Raptor21/Photon partials for 5S/The Vault/P255
User:Prime Raptor21/Photon partials for 5S/The Vault/P259
User:Prime Raptor21/Photon partials for 5S/The Vault/P260
User:Prime Raptor21/Photon partials for 5S/The Vault/P262
User:Prime Raptor21/Photon partials for 5S/The Vault/P264
User:Prime Raptor21/Photon partials for 5S/The Vault/P266
User:Prime Raptor21/Photon partials for 5S/The Vault/P268
User:Prime Raptor21/Photon partials for 5S/The Vault/P270
User:Prime Raptor21/Photon partials for 5S/The Vault/P272
User:Prime Raptor21/Photon partials for 5S/The Vault/P273
User:Prime Raptor21/Photon partials for 5S/The Vault/P274
User:Prime Raptor21/Photon partials for 5S/The Vault/P275
User:Prime Raptor21/Photon partials for 5S/The Vault/P276
User:Prime Raptor21/Photon partials for 5S/The Vault/P278
User:Prime Raptor21/Photon partials for 5S/The Vault/P279
User:Prime Raptor21/Photon partials for 5S/The Vault/P280
User:Prime Raptor21/Photon partials for 5S/The Vault/P282
User:Prime Raptor21/Photon partials for 5S/The Vault/P283
User:Prime Raptor21/Photon partials for 5S/The Vault/P285
User:Prime Raptor21/Photon partials for 5S/The Vault/P286
User:Prime Raptor21/Photon partials for 5S/The Vault/P287
User:Prime Raptor21/Photon partials for 5S/The Vault/P288
User:Prime Raptor21/Photon partials for 5S/The Vault/P294
User:Prime Raptor21/Photon partials for 5S/The Vault/P295
User:Prime Raptor21/Photon partials for 5S/The Vault/P296
User:Prime Raptor21/Photon partials for 5S/The Vault/P297
User:Prime Raptor21/Photon partials for 5S/The Vault/P300
User:Prime Raptor21/Photon partials for 5S/The Vault/P304
User:Prime Raptor21/Photon partials for 5S/The Vault/P308
User:Prime Raptor21/Photon partials for 5S/The Vault/P310
User:Prime Raptor21/Photon partials for 5S/The Vault/P312
User:Prime Raptor21/Photon partials for 5S/The Vault/P315
User:Prime Raptor21/Photon partials for 5S/The Vault/P318
User:Prime Raptor21/Photon partials for 5S/The Vault/P320
User:Prime Raptor21/Photon partials for 5S/The Vault/P322
User:Prime Raptor21/Photon partials for 5S/The Vault/P330
User:Prime Raptor21/Photon partials for 5S/The Vault/P339
User:Prime Raptor21/Photon partials for 5S/The Vault/P341
User:Prime Raptor21/Photon partials for 5S/The Vault/P346
User:Prime Raptor21/Photon partials for 5S/The Vault/P352
User:Prime Raptor21/Photon partials for 5S/The Vault/P360
User:Prime Raptor21/Photon partials for 5S/The Vault/P363
User:Prime Raptor21/Photon partials for 5S/The Vault/P364
User:Prime Raptor21/Photon partials for 5S/The Vault/P369
User:Prime Raptor21/Photon partials for 5S/The Vault/P372
User:Prime Raptor21/Photon partials for 5S/The Vault/P376
User:Prime Raptor21/Photon partials for 5S/The Vault/P381
User:Prime Raptor21/Photon partials for 5S/The Vault/P382
User:Prime Raptor21/Photon partials for 5S/The Vault/P383
User:Prime Raptor21/Photon partials for 5S/The Vault/P392
User:Prime Raptor21/Photon partials for 5S/The Vault/P394
User:Prime Raptor21/Photon partials for 5S/The Vault/P399
User:Prime Raptor21/Photon partials for 5S/The Vault/P403
User:Prime Raptor21/Photon partials for 5S/The Vault/P413
User:Prime Raptor21/Photon partials for 5S/The Vault/P414
User:Prime Raptor21/Photon partials for 5S/The Vault/P420
User:Prime Raptor21/Photon partials for 5S/The Vault/P426
User:Prime Raptor21/Photon partials for 5S/The Vault/P428
User:Prime Raptor21/Photon partials for 5S/The Vault/P434
User:Prime Raptor21/Photon partials for 5S/The Vault/P435
User:Prime Raptor21/Photon partials for 5S/The Vault/P447
User:Prime Raptor21/Photon partials for 5S/The Vault/P448
User:Prime Raptor21/Photon partials for 5S/The Vault/P456
User:Prime Raptor21/Photon partials for 5S/The Vault/P459
User:Prime Raptor21/Photon partials for 5S/The Vault/P462
User:Prime Raptor21/Photon partials for 5S/The Vault/P464
User:Prime Raptor21/Photon partials for 5S/The Vault/P465
User:Prime Raptor21/Photon partials for 5S/The Vault/P467
User:Prime Raptor21/Photon partials for 5S/The Vault/P476
User:Prime Raptor21/Photon partials for 5S/The Vault/P480
User:Prime Raptor21/Photon partials for 5S/The Vault/P482
User:Prime Raptor21/Photon partials for 5S/The Vault/P483
User:Prime Raptor21/Photon partials for 5S/The Vault/P485
User:Prime Raptor21/Photon partials for 5S/The Vault/P489
User:Prime Raptor21/Photon partials for 5S/The Vault/P501
User:Prime Raptor21/Photon partials for 5S/The Vault/P504
User:Prime Raptor21/Photon partials for 5S/The Vault/P506
User:Prime Raptor21/Photon partials for 5S/The Vault/P508
User:Prime Raptor21/Photon partials for 5S/The Vault/P510
User:Prime Raptor21/Photon partials for 5S/The Vault/P511
User:Prime Raptor21/Photon partials for 5S/The Vault/P514
User:Prime Raptor21/Photon partials for 5S/The Vault/P536
User:Prime Raptor21/Photon partials for 5S/The Vault/P543
User:Prime Raptor21/Photon partials for 5S/The Vault/P546
User:Prime Raptor21/Photon partials for 5S/The Vault/P549
User:Prime Raptor21/Photon partials for 5S/The Vault/P558
User:Prime Raptor21/Photon partials for 5S/The Vault/P570
User:Prime Raptor21/Photon partials for 5S/The Vault/P572
User:Prime Raptor21/Photon partials for 5S/The Vault/P574
User:Prime Raptor21/Photon partials for 5S/The Vault/P583
User:Prime Raptor21/Photon partials for 5S/The Vault/P585
User:Prime Raptor21/Photon partials for 5S/The Vault/P608
User:Prime Raptor21/Photon partials for 5S/The Vault/P619
User:Prime Raptor21/Photon partials for 5S/The Vault/P620
User:Prime Raptor21/Photon partials for 5S/The Vault/P630
User:Prime Raptor21/Photon partials for 5S/The Vault/P635
User:Prime Raptor21/Photon partials for 5S/The Vault/P646
User:Prime Raptor21/Photon partials for 5S/The Vault/P651
User:Prime Raptor21/Photon partials for 5S/The Vault/P682
User:Prime Raptor21/Photon partials for 5S/The Vault/P684
User:Prime Raptor21/Photon partials for 5S/The Vault/P694
User:Prime Raptor21/Photon partials for 5S/The Vault/P699
User:Prime Raptor21/Photon partials for 5S/The Vault/P708
User:Prime Raptor21/Photon partials for 5S/The Vault/P732
User:Prime Raptor21/Photon partials for 5S/The Vault/P762
User:Prime Raptor21/Photon partials for 5S/The Vault/P780
User:Prime Raptor21/Photon partials for 5S/The Vault/P819
User:Prime Raptor21/Photon partials for 5S/The Vault/P826
User:Prime Raptor21/Photon partials for 5S/The Vault/P840
User:Prime Raptor21/Photon partials for 5S/The Vault/P868
User:Prime Raptor21/Photon partials for 5S/The Vault/P889
User:Prime Raptor21/Photon partials for 5S/The Vault/P930
User:Prime Raptor21/Photon partials for 5S/The Vault/P961
User:Prime Raptor21/Photon partials for 5S/The Vault/P990
User:Prime Raptor21/Photon partials for 5S/The Vault/P1013
User:Prime Raptor21/Photon partials for 5S/The Vault/P1016
User:Prime Raptor21/Photon partials for 5S/The Vault/P1020
User:Prime Raptor21/Photon partials for 5S/The Vault/P1022
User:Prime Raptor21/Photon partials for 5S/The Vault/P1023
User:Prime Raptor21/Photon partials for 5S/The Vault/P1073
User:Prime Raptor21/Photon partials for 5S/The Vault/P1085
User:Prime Raptor21/Photon partials for 5S/The Vault/P1094
User:Prime Raptor21/Photon partials for 5S/The Vault/P1113
User:Prime Raptor21/Photon partials for 5S/The Vault/P1146
User:Prime Raptor21/Photon partials for 5S/The Vault/P1190
User:Prime Raptor21/Photon partials for 5S/The Vault/P1207
User:Prime Raptor21/Photon partials for 5S/The Vault/P1250
User:Prime Raptor21/Photon partials for 5S/The Vault/P1365
User:Prime Raptor21/Photon partials for 5S/The Vault/P1454
User:Prime Raptor21/Photon partials for 5S/The Vault/P1524
User:Prime Raptor21/Photon partials for 5S/The Vault/P1533
User:Prime Raptor21/Photon partials for 5S/The Vault/P1663
User:Prime Raptor21/Photon partials for 5S/The Vault/P1676
User:Prime Raptor21/Photon partials for 5S/The Vault/P1714
User:Prime Raptor21/Photon partials for 5S/The Vault/P1771
User:Prime Raptor21/Photon partials for 5S/The Vault/P1778
User:Prime Raptor21/Photon partials for 5S/The Vault/P1785
User:Prime Raptor21/Photon partials for 5S/The Vault/P1860
User:Prime Raptor21/Photon partials for 5S/The Vault/P1880
User:Prime Raptor21/Photon partials for 5S/The Vault/P1905
User:Prime Raptor21/Photon partials for 5S/The Vault/P1953
User:Prime Raptor21/Photon partials for 5S/The Vault/P2044
User:Prime Raptor21/Photon partials for 5S/The Vault/P2046
User:Prime Raptor21/Photon partials for 5S/The Vault/P2047
User:Prime Raptor21/Photon partials for 5S/The Vault/P2239
User:Prime Raptor21/Photon partials for 5S/The Vault/P2467
User:Prime Raptor21/Photon partials for 5S/The Vault/P2504
User:Prime Raptor21/Photon partials for 5S/The Vault/P2643
User:Prime Raptor21/Photon partials for 5S/The Vault/P2644
User:Prime Raptor21/Photon partials for 5S/The Vault/P3298
User:Prime Raptor21/Photon partials for 5S/The Vault/P3810
User:Prime Raptor21/Photon partials for 5S/The Vault/P3937
User:Prime Raptor21/Photon partials for 5S/The Vault/P4094
User:Prime Raptor21/Photon partials for 5S/The Vault/P4095"""
pageslist = pages.split("\n")
count = len(pageslist)
for article in pageslist:
url = ("https://conwaylife.com/wiki/" + article).replace(" ","_")
outfname = article.replace("User:Prime Raptor21/Photon partials for 5S/","").replace("/","_") + ".txt"
response = urllib.request.urlopen(url)
html = str(response.read())
i1 = html.index("<pre>")
i2 = html.index("</pre>")
with open(outpath + outfname,"w") as f:
output = html[i1+5:i2].replace("\\n","\n").strip()
f.write(output)
g.show(str(count) + " : " + str(len(output)))
count = 1
g.show("Done.")
1) the list of articles at the top of the script,
2) the fact that each automaticallygenerated article started with "<pre>" and ended with "</pre>", so there's a little bit of code at the end that extracts just the text between "<pre>" and "</pre>" and sends that to a file.
Something very similar could be done for other LifeWiki data extraction problems, with minor changes to the code.
Not as big as I thought...
It turns out that when you compress the script's output files, they only come to 1.2 megabytes. Here's the archive:
Re: Golly scripts
Couldn't find such a script using forum search (seriously? it's so simple!), so i'm posting my random MAP rule generator here:
It can also be run in Shell.
Some interesting outputs:
Code: Select all
import random
li = [chr(n) for n in range(65, 91)] + [chr(n) for n in range(97, 123)] + [chr(n) for n in range(48, 58)] + ['+', '/']
def randomap():
mapstr = 'MAP'
for n in range(86):
mapstr += li[random.randrange(random.randrange(random.randrange(64)+1)+1)]
return mapstr
if __name__ == "__main__":
print(randomap())
else:
import golly
golly.setrule(randomap())
Some interesting outputs:
Code: Select all
x = 2, y = 4, rule = MAPAFVBDLCEASEEDEBAeEIDUAABSNNCHALALPACLMAHCGSDHFBAGAJZMKAKbCDXBDIHMVFJCAwGACOKCBAEBDGFDA
o2$bo$o!
Code: Select all
x = 89, y = 12, rule = MAPAcABBaGeAMAKABBPFNCDAAITEBEAPAAMCYFCsLPFS9EMBYCEDCeCDBNXSAgAHJAABHTAABRIACBGZBAFdAABEA
2$4bo$3bobo$71bo$3bo55b29o$3bo51b4o12bo$3bo43b8o16bo$3bo41b2o24bo$3bo
67bo$3bo67bo$3bo!
Code: Select all
x = 5, y = 4, rule = MAPHCMAKDSDRGbLJAAABfMBBBHPBMSgCRACTEECABICCQERTBZqQDGACLDAlCBDIFRNALNBHAGACfAQVAFCBjBJHA
$4bo$2bo$bo!
Code: Select all
x = 19, y = 5, rule = MAPNAJAFBGOABEAHEAFSAUmMgCAeaCJXGCOlEoGFRMAJEKDEZCHEAFDBACAFFLYOiGIFPUFAUBXTQOOEJesKIAOBA
2o14b2o$2o14bo$2o14bo$2o14b2o$bo12bo2bo!
Code: Select all
x = 5, y = 36, rule = MAPBCSABBtAHCEIATFERACAPQCDAWCIBMDEARFGAIABGACQdEEKCPCAACBACEAGODCEEAcACBAPHfnBAAkiLDKACQ
5o$5o$5o$5o$5o$5o$5o$5o$5o$5o$5o$5o$5o$5o$5o$5o$5o$5o$5o$5o$5o$5o$5o$
5o$5o$5o$5o$5o$5o$5o$5o$5o$5o$5o$5o$5o!
Wiki: User:iddi01
I'm making a poll. please contribute.
First gun i constructed:
I'm making a poll. please contribute.
First gun i constructed:
Code: Select all
x = 69, y = 69, rule = B3n/S1e2a3e4e
2$32b3o$32bobo$32bobo$32b3o27$63b4o$b4o58bo2bo$bo2bo23bo4b2o28b4o$b4o
21bobo$28bo21$35bo$34b3o6$33b3o$33bobo$33bobo$33b3o!
Re: Golly scripts
I've moved a response by bengine out to the "Miscellaneous Discoveries in Other Cellular Automata" thread, just because this "Golly scripts" thread needs to be about Golly scripts, not extended reports of things that a particular script produces.
However, one part of that post was really more relevant to this thread:
Re: Golly scripts
After i finally figured out how to toggle individual transitions in MAP rules, i made this:
Code: Select all
import random,base64
def randomap():
bits = bytearray(64)
for n in range(512):
if (not n in [1,2,4,8,32,64,128,256]) and random.randrange(3) == 0:
bits[n // 8] = (0x80 >> (n % 8))
return "MAP" + base64.b64encode(bits).decode('ascii').strip("=")
if __name__ == "__main__":
print(randomap())
else:
import golly
golly.setrule(randomap())
Example output:
Code: Select all
x = 25, y = 18, rule = MAPAgFqoA2HKpoWxCggISgoOB48gW5KhE25JJJskOJRAC8QJPjghpkELA4MSiR3bAUGgPQxEGXAcMiCBX1+IOJg+A
$11bo$11bo$11bo$2bo8bo$2b5o4bo$7b8o$11bo$11bo$11bo$11bo11bo$11bo$11bo$
11bo$11bo$12bo$12bo!
Code: Select all
import random,base64
def randomap():
bits = bytearray(64)
for n in range(512):
if (not n in [0,1,2,4,8,32,64,128,256,3,6,9,36,72,192,288,384]) and random.randrange(2) == 0:
bits[n // 8] = (0x80 >> (n % 8))
return "MAP" + base64.b64encode(bits).decode('ascii').strip("=")
if __name__ == "__main__":
print(randomap())
else:
import golly
golly.setrule(randomap())
Code: Select all
x = 25, y = 30, rule = MAPADXh4ANyV1U3d7FJ5Vq1ITlqxjGmqPA0WOez8kU5i2MXpd6IVq2P7X5ymu7X7wJsRKYer8LonpouLE6d2+Fo3g
2$12bo$11bo7bo$11bo7bo$10bo8bo$10bo8bobo$9bo9bo$9bo9bo$8bo10bo$8bo10bo
$7bo11bo$7bo11bo$6bo12bo$6bo12bo$5bo13bo$5bo13bo$20bo$21bo$22bo6$2bo$
3bo$b3o!
Code: Select all
x = 67, y = 52, rule = MAPBALlxwV5TgUrFlPhJl3EXyGXwtb6euRbQ1YRoZtQLWp/DlEpTfDYupbir8dtJZdsHnhnnhNksAfSfOZLVblmCA
2$10b3o$11bo21$50b2o$50bo$47bo2bo$47bobo$46bo2bo$46bo2bo$46bobo$12bo
33bobo$12b2o32bobo$45bo2b7o$3bo41b4o5bo$2b3o6bobo30bo2bo$12bo30b2o2bo$
46bo15b3o$46bo4b11o$36b15o$26b10o10bo$46bo$45bo$45bo$45bo$45bo$45bo$
45bo$44b2o!
Wiki: User:iddi01
I'm making a poll. please contribute.
First gun i constructed:
I'm making a poll. please contribute.
First gun i constructed:
Code: Select all
x = 69, y = 69, rule = B3n/S1e2a3e4e
2$32b3o$32bobo$32bobo$32b3o27$63b4o$b4o58bo2bo$bo2bo23bo4b2o28b4o$b4o
21bobo$28bo21$35bo$34b3o6$33b3o$33bobo$33bobo$33b3o!
Re: Golly scripts
I invented a notation for MAP rules, which is used in the following script for defining custom MAP rules:
Code: Select all
import base64
letter_to_number = {
'z': 0,
'u': 128,
'd': 2,
'l': 32,
'r': 8,
'h': 40,
'v': 130,
'w': 42,
'c': 162,
'q': 138,
'n': 168,
'f': 160,
'g': 136,
'i': 10,
'j': 34,
'a': 170,
'Z': 0,
'U': 256,
'D': 1,
'L': 4,
'R': 64,
'H': 68,
'V': 257,
'W': 69,
'C': 261,
'Q': 321,
'N': 324,
'F': 260,
'G': 320,
'I': 65,
'J': 5,
'A': 325}
def customap(rulestring):
bits = bytearray(64)
n = 0
n_base = 0
for char in rulestring:
if char in ['b', 'B']:
n = n_base = 0
char_ = False
elif char in ['/', ',']:
if char_:
bits[n // 8] = (0x80 >> (n % 8))
n = n_base
char_ = False
elif char in ['/', 's', 'S']:
n = n_base = 16
else:
char_ = True
n += letter_to_number[char]
if char_:
bits[n // 8] = (0x80 >> (n % 8))
n = n_base
return "MAP" + base64.b64encode(bits).decode('ascii').strip("=")
if __name__ == "__main__":
rstr = input('Type a rulestring: ')
print(customap(rstr))
else:
import golly
rstr = golly.getstring("Type a rulestring, using the notation documented at conwaylife.com/wiki/User:iddi01/Anisotropic_rule_notation: ")
golly.setrule(customap(rstr))
try:
f = open(golly.getdir('rules') + "mapstrings.txt", 'r+')
f.read()
except FileNotFoundError:
f = open(golly.getdir('rules') + "mapstrings.txt", 'w')
f.write(rstr + " = " + customap(rstr) + '\n')
f.close()
Whenever you set a rule using the script, the rulestring you typed and the corresponding MAP string is saved in mapstrings.txt in Golly's rule folder. That way, you can reuse a rule without having to type the rulestring again.
Example of what it generates:
A rule which emulates W110 at the upper and lower edge of a pattern and is chaotic within it (BzR,uZ,uU,uR,G,zL,dZ,dL,dD,J/S):
Code: Select all
x = 1, y = 1, rule = MAPPgAAAAAAAACAAAAAAAAAAIAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAA
o!
Wiki: User:iddi01
I'm making a poll. please contribute.
First gun i constructed:
I'm making a poll. please contribute.
First gun i constructed:
Code: Select all
x = 69, y = 69, rule = B3n/S1e2a3e4e
2$32b3o$32bobo$32bobo$32b3o27$63b4o$b4o58bo2bo$bo2bo23bo4b2o28b4o$b4o
21bobo$28bo21$35bo$34b3o6$33b3o$33bobo$33bobo$33b3o!
 confocaloid
 Posts: 3138
 Joined: February 8th, 2022, 3:15 pm
Re: Golly scripts
Prior art overview: viewtopic.php?f=11&t=6470
iddi01 wrote: ↑April 21st, 2024, 6:49 amI invented a notation for MAP rules, which is used in the following script for defining custom MAP rules:
127:1 B3/S234c User:Confocal/R (isotropic CA, incomplete)
Unlikely events happen.
My silence does not imply agreement, nor indifference. If I disagreed with something in the past, then please do not construe my silence as something that could change that.
Unlikely events happen.
My silence does not imply agreement, nor indifference. If I disagreed with something in the past, then please do not construe my silence as something that could change that.