Certainly. Sometimes a lot more lines of rules will be needed, though. There's a minor combinatorial explosion if you have birth and survival conditions with lots of different neighbor counts, instead of just the three conditions for Conway's Life.
For example, I think HighLife would need 4*3+3 = 15 groups of rules, because it has four birth survival conditions, instead of regular Life's 3 survival conditions and 3*2+3 = 9 groups of rules. And the groups would sometimes be larger when the birth or survival is on a 4 or 5 neighbor count, because there are more different ways to overlap the independent states.
Maybe we could agree on a standardizable name for these double rules -- e.g., "DoubleB36S23" for HighLife.
I found it a little confusing that the combined state was mapped onto state 1. I had initially assumed that the mapping would be something like red = 1 (
).
Below is a translated "DoubleB3S23" rule with the binary-based state mapping, and some added comments to make it clear what the various rules are doing. I've also attached a ZIP file that can be opened in Golly to load the rule and display a test pattern, showing (I hope) that I did the conversion correctly and the rule is now symmetric with respect to state 1 and state 2:
If someone wants to try tackling the problem, it should be fairly straightforward to write a Golly script that generates Double rules on demand for any Lifelike CA. Might be easier to skip the variables and write out all the specific state transitions. Could be a little trickier (though definitely a nicer result) to use variables to boil down the rule file to a minimum number of lines, as Bullet51 has done for B3/S23.
Code: Select all
@RULE DoubleB3S23
@TABLE
n_states:4
neighborhood:Moore
symmetries:permute
# 0x01 bit ON
var a={1,3}
var aa=a
var ab=a
var ac=a
var ad=a
var ae=a
var af=a
var ag=a
# 0x01 bit OFF
var b={0,2}
var ba=b
var bb=b
var bc=b
var bd=b
var be=b
var bf=b
var bg=b
# 0x10 bit ON
var c={2,3}
var ca=c
var cb=c
var cc=c
var cd=c
var ce=c
var cf=c
var cg=c
# 0x10 bit OFF
var d={0,1}
var da=d
var db=d
var dc=d
var dd=d
var de=d
var df=d
var dg=d
# don't-care cells
var x={0,1,2,3}
var xa=x
var xb=x
var xc=x
var xd=x
var xe=x
var xf=x
var xg=x
var xh=x
# birth for both 0x01 and 0x10 bits
x,1,1,1,2,2,2,0,0,3
x,1,1,3,2,2,0,0,0,3
x,1,3,3,2,0,0,0,0,3
x,3,3,3,0,0,0,0,0,3
# survival for 0x01 bit, birth for 0x10 bit
1,2,2,2,1,1,0,0,0,3
1,2,2,3,1,0,0,0,0,3
1,2,3,3,0,0,0,0,0,3
# birth for 0x01 bit, survival for 0x10 bit
2,1,1,1,2,2,0,0,0,3
2,1,1,3,2,0,0,0,0,3
2,1,3,3,0,0,0,0,0,3
# 2-neighbor survival for 0x01 bit, 3-neighbor survival for 0x10 bit
3,1,1,2,2,2,0,0,0,3
3,1,3,2,2,0,0,0,0,3
3,3,3,2,0,0,0,0,0,3
# 3-neighbor survival for 0x01 bit, 2-neighbor survival for 0x10 bit
3,1,1,1,2,2,0,0,0,3
3,1,1,3,2,0,0,0,0,3
3,1,3,3,0,0,0,0,0,3
# 2-neighbor survival for both 0x01 and 0x10 bits
3,1,1,2,2,0,0,0,0,3
3,1,3,2,0,0,0,0,0,3
3,3,3,0,0,0,0,0,0,3
# birth for 0x01 bit, death for 0x10 bit
x,a,aa,ab,ba,bb,bc,bd,be,1
x,a,aa,ab,ba,bb,bc,bd,be,1
1,a,aa,ba,bb,bc,bd,be,bf,1
3,a,aa,ba,bb,bc,bd,be,bf,1
# death for 0x01 bit, birth for 0x10 bit
x,c,ca,cb,da,db,dc,dd,de,2
x,c,ca,cb,da,db,dc,dd,de,2
2,c,ca,da,db,dc,dd,de,df,2
3,c,ca,da,db,dc,dd,de,df,2
# death for both bits
x,xa,xb,xc,xd,xe,xf,xg,xh,0
@COLORS
0 0 0 0
1 255 0 0
2 0 255 0
3 255 255 255