1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
|
# Make a pattern from states 3 and 0, select it and then
# run this script to make a Banks-IV CA pattern that will then
# construct the pattern.
#
# The machine will attempt to activate the pattern by injecting
# a signal at a special trigger point.
# See: Patterns/Self-Rep/Banks/Banks-IV-constructor.rle.gz
#
# You may need to change trigger_row for your pattern, or disable
# triggering.
#
# Tim Hutton <tim.hutton@gmail.com>
from glife import rect
from time import time
import golly as g
r = rect( g.getselrect() )
if r.empty: g.exit("There is no selection.")
oldsecs = time()
maxstate = g.numstates() - 1
top_tape = '00'
bottom_tape = '00'
# write a state 3 to the required position, relative to the centre of the face
def write_cell(x,y):
global top_tape
global bottom_tape
# delay one of the tapes, to select the correct row
if y<0: top_tape += '00'*abs(y)
elif y>0: bottom_tape += '00'*y
# send out a write arm to the right length
arm_length=2
while arm_length < x:
top_tape += '120' + '00'*arm_length + '12000'
bottom_tape += '120' + '00'*arm_length + '12000'
arm_length += 1
# send an erasing wing down the arm, to write a cell at the end
top_tape += '120' + '00'*(arm_length-3) + '120000'
bottom_tape += '120' + '00'*(arm_length-3) + '120000'
# undo the delay on the tapes (could just add the difference but this is simpler)
if y<0: bottom_tape += '00'*abs(y)
elif y>0: top_tape += '00'*y
# we first write the commands to 2 strings, and then to the grid
H_OFFSET = 10 # how far from the construction face should the new pattern be?
half_height = (r.height-(r.height%2))/2
# write the cells that are in state 1 (can ignore the zeros)
# (still plenty of room for optimisation here)
for col in xrange(r.left + r.width-1, r.left-1,-1):
# if large selection then give some indication of progress
newsecs = time()
if newsecs - oldsecs >= 1.0:
oldsecs = newsecs
g.update()
for row in xrange(r.top, r.top + r.height):
if g.getcell(col,row)==3:
write_cell(H_OFFSET + col-r.left,row - r.top - half_height)
# trigger
trigger_row = 3 # from the vertical middle
write_cell(H_OFFSET + 2,trigger_row)
# (optional) restore the trigger input
write_cell(H_OFFSET-3, trigger_row-1)
write_cell(H_OFFSET-2, trigger_row+2)
write_cell(H_OFFSET-2, trigger_row+1) # actually just sends an erasing wing
write_cell(H_OFFSET, trigger_row-2)
write_cell(H_OFFSET, trigger_row+2)
fx = r.left-20 # constructing face
fy = r.top+r.height*2 # centre of constructing face
half_height += 10
# draw the constructing face
for cy in range(fy-(half_height-6),fy+(half_height-6)+1):
g.setcell(fx,cy,3)
# draw the top shoulder
g.setcell(fx,fy-half_height,3)
g.setcell(fx,fy-half_height-3,3)
g.setcell(fx-1,fy-half_height-3,3)
g.setcell(fx+1,fy-half_height-3,3)
g.setcell(fx-1,fy-half_height-2,3)
g.setcell(fx+1,fy-half_height-2,3)
g.setcell(fx+1,fy-half_height-1,3)
g.setcell(fx+1,fy-half_height+1,3)
g.setcell(fx+1,fy-half_height+2,3)
g.setcell(fx+1,fy-half_height+3,3)
g.setcell(fx+1,fy-half_height+4,3)
g.setcell(fx+1,fy-half_height+5,3)
g.setcell(fx-1,fy-half_height+2,3)
g.setcell(fx-1,fy-half_height+3,3)
g.setcell(fx-1,fy-half_height+4,3)
g.setcell(fx-1,fy-half_height+5,3)
g.setcell(fx+2,fy-half_height-1,3)
g.setcell(fx+3,fy-half_height-1,3)
g.setcell(fx+3,fy-half_height,3)
g.setcell(fx+2,fy-half_height+1,3)
g.setcell(fx+3,fy-half_height+1,3)
g.setcell(fx+2,fy-half_height+4,3)
g.setcell(fx-2,fy-half_height+5,3)
# draw the bottom shoulder
g.setcell(fx,fy+half_height,3)
g.setcell(fx,fy+half_height+3,3)
g.setcell(fx-1,fy+half_height+3,3)
g.setcell(fx+1,fy+half_height+3,3)
g.setcell(fx-1,fy+half_height+2,3)
g.setcell(fx+1,fy+half_height+2,3)
g.setcell(fx+1,fy+half_height+1,3)
g.setcell(fx+1,fy+half_height-1,3)
g.setcell(fx+1,fy+half_height-2,3)
g.setcell(fx+1,fy+half_height-3,3)
g.setcell(fx+1,fy+half_height-4,3)
g.setcell(fx+1,fy+half_height-5,3)
g.setcell(fx-1,fy+half_height-2,3)
g.setcell(fx-1,fy+half_height-3,3)
g.setcell(fx-1,fy+half_height-4,3)
g.setcell(fx-1,fy+half_height-5,3)
g.setcell(fx+2,fy+half_height-1,3)
g.setcell(fx+3,fy+half_height-1,3)
g.setcell(fx+3,fy+half_height,3)
g.setcell(fx+2,fy+half_height+1,3)
g.setcell(fx+3,fy+half_height+1,3)
g.setcell(fx+2,fy+half_height-4,3)
g.setcell(fx-2,fy+half_height-5,3)
# draw the tapes
x = fx-1
for c in range(0,len(top_tape)):
g.setcell(x,fy-half_height-1,3)
g.setcell(x,fy-half_height,int(top_tape[c]))
g.setcell(x,fy-half_height+1,3)
x -= 1
x = fx-1
for c in range(0,len(bottom_tape)):
g.setcell(x,fy+half_height-1,3)
g.setcell(x,fy+half_height,int(bottom_tape[c]))
g.setcell(x,fy+half_height+1,3)
x -= 1
|