From now, Golly is really capable to do limited 3D CA simulation.
Code: Select all
#!/usr/bin/env python
#
# NASZVADI P.: 3D-binary to 2D rule generator for Golly
# Do not violate the laws of the author's (NASZVADI P.) country!
#
# This is an alpha/prepre(pre)+beta version!
#
# Usage:
# run with the following parameters:
# APPLICATION <3D Neumann rulestring>
# (6 neighbours, (outer-)totalistic on Z^3 grid)
#
# Save the generated rule from the standard output:
# with redirection to a file, for example
#
# Remarks: unfortunately, 3D-Moore neighbourhood or layer>3 seems
# to be too big to handle with Golly :(
import sys
dict = {
"0":0,
"1":1,
"2":2,
"3":3,
"4":4,
"5":5,
"6":6
}
myarglist = sys.argv[1:]
for rule in myarglist:
if rule[0] != '-':
break
isbirth=0
birth = [0]*7
survive = [0]*7
for char in rule:
if char == "B":
isbirth = 1
elif char == "S":
isbirth = 0
elif char == "z":
isbirth += 0
elif char == "Z":
isbirth += 0
elif char == "b":
isbirth = 1
elif char == "s":
isbirth = 0
elif char == "/":
isbirth = 1-isbirth
elif char == "_":
isbirth = 1-isbirth
elif char in dict:
if isbirth == 1:
birth[dict[char]] = 1
else:
survive[dict[char]] = 1
else:
print "Unknown character in specified rulestring: ",char
raise
numlayers = 3
print """@RULE %s
This is a generated rule, embedding %s in a 2D Neumann rule
@TABLE
# Format: C,N,E,S,W,C'
n_states:%d
neighborhood:vonNeumann
symmetries:permute
""" % (rule.replace("/","_"),rule,1+(1<<numlayers))
print "# DEBUG::birth:",birth
print "# DEBUG::survive:",survive
for i in range(1<<numlayers):
for j in range(i,1<<numlayers):
for k in range(j,1<<numlayers):
for l in range(k,1<<numlayers):
for m in range(1<<numlayers):
centercell = 0
for layer in range(numlayers):
neighbours = +((m & (1<<((layer+1)%numlayers))) and 1)
neighbours += +((m & (1<<((layer-1)%numlayers))) and 1)
neighbours += +((i & (1<<layer)) and 1)
neighbours += +((j & (1<<layer)) and 1)
neighbours += +((k & (1<<layer)) and 1)
neighbours += +((l & (1<<layer)) and 1)
if (m & (1<<layer)): # survive?
if survive[neighbours]:
centercell = centercell | (1<<layer)
else: # birth?
if birth[neighbours]:
centercell = centercell | (1<<layer)
if centercell != m:
print "%d,%d,%d,%d,%d,%d" % (m+1,i+1,j+1,k+1,l+1,centercell+1)
WARNING: increasing layers or the neighbourhood set would dramatically increase the output - probably harmful!