I think it's actually pretty easy to modify it to save all results into a file. Here is the modification (I haven't run it for a long time though):
Code: Select all
import golly as g
import time
#import os
#os.system("pip3 install pyperclip")
g.warn("done")
import pyperclip
'''Initializing'''
g.select([0,0,1,1])
#g.autoupdate(1)
test1 = False
test2 = 0
test2a = 0
mode = 'C2' #C2, C4, D4, X4, D8
spark_mode = 'mwhw'
copies = 8 if mode == 'D8' else 2 if mode == 'C2' else 4
g.new("example")
input_pattern = g.parse('b3o$o3bo$2ob2o!')
g.putcells(input_pattern, 0, 0)
initial_box = g.getrect()
width = g.getrect()[2]
height = g.getrect()[3]
'''Generating rotations and reflections'''
if mode == 'C2':
r_up = input_pattern
g.select(initial_box)
g.rotate(1)
g.rotate(1)
g.cut()
g.paste(0,0,"or")
r_down = g.getcells(g.getrect())
elif mode in ('C4','X4','D8'):
a = 0 #1 if even symmetry, 0 if odd; C4 and D8 only
r_n = input_pattern
initial_box = g.getrect()
g.select(initial_box)
if mode == 'X4':
g.flip(1)
g.rotate(mode != 'X4')
g.select(g.getrect())
g.cut()
g.paste(0,0,"or")
r_e = g.getcells(g.getrect())
g.select(g.getrect())
if mode == 'X4':
g.flip(1)
g.rotate(1)
g.cut()
g.paste(0,0,"or")
r_s = g.getcells(g.getrect())
g.select(g.getrect())
if mode == 'X4':
g.flip(1)
g.rotate(mode != 'X4')
g.cut()
g.paste(0,0,"or")
r_w = g.getcells(g.getrect())
if mode == 'D8':
g.select(g.getrect())
g.flip(0)
g.rotate(1)
g.rotate(1)
g.cut()
g.paste(0,0,"or")
r_nw = g.getcells(g.getrect())
g.select(g.getrect())
g.rotate(1)
g.cut()
g.paste(0,0,"or")
r_ne = g.getcells(g.getrect())
g.select(g.getrect())
g.rotate(1)
g.cut()
g.paste(0,0,"or")
r_se = g.getcells(g.getrect())
g.select(g.getrect())
g.rotate(1)
g.cut()
g.paste(0,0,"or")
r_sw = g.getcells(g.getrect())
elif mode == 'D4':
r_se = input_pattern
g.select(initial_box)
g.flip(1)
g.select(g.getrect())
g.cut()
g.paste(0,0,"or")
r_ne = g.getcells(g.getrect())
g.select(g.getrect())
g.flip(0)
g.cut()
g.paste(0,0,"or")
r_nw = g.getcells(g.getrect())
g.select(g.getrect())
g.flip(1)
g.cut()
g.paste(0,0,"or")
r_sw = g.getcells(g.getrect())
else:
g.exit('Invalid symmetry input.')
g.new("example")
#single_cell = g.parse('o!')
'''Starting and ending bounds'''
if mode == 'C2':
start_x, end_x, start_y, end_y = -10, 10, -10, 10
elif mode == 'C4':
start_x, end_x, start_y, end_y = -10, 10, 0, 10
elif mode == 'D4':
start_x, end_x, start_y, end_y = width+1, width+12, height+1, height+12
elif mode == 'X4':
start_x, end_x, start_y, end_y = -15, 15, -15, 10
elif mode == 'D8':
start_x, end_x, start_y, end_y = 0, 15, 0, 15
'''Main loop'''
for x in range(start_x, end_x+1):
for y in range(start_y, end_y+1):
for z in range(1 if mode in ('C2','X4') else 8 if mode == 'D8' else 4):
#if x == 15 and y < 15:
# continue
if mode == 'C4' and not -y-width <= x < y: #C4 has a diagonal bounding box
continue
#if x < 0 and y < 0:
# continue
if mode == 'D8' and y > x: #D8 takes only an eighth
continue
if mode == 'C4': #rotating
width, height = height, width
r_n, r_e, r_s, r_w = r_e, r_s, r_w, r_n
if mode == 'D8':
if z % 4 == 0:
r_n, r_e, r_s, r_w, r_ne, r_se, r_sw, r_nw = \
r_ne, r_se, r_sw, r_nw, r_n, r_e, r_s, r_w
width, height = height, width
r_n, r_e, r_s, r_w, r_ne, r_se, r_sw, r_nw = \
r_w, r_n, r_e, r_s, r_se, r_sw, r_nw, r_ne
if mode == 'D4': #flipping
if z % 2 == 0:
r_se, r_ne, r_nw, r_sw = r_ne, r_se, r_sw, r_nw
else:
r_se, r_ne, r_nw, r_sw = r_sw, r_nw, r_ne, r_se
#if (y,z) == (2,3):
# continue
for spark_type_num in range(4 if spark_mode == 'mwhw' else 1):
if spark_type_num == 0:
spark_type = g.parse('2$b2o$b3o$4o$b3o$b2o!')
spark_type2 = g.parse('$b2o$3o$4o$3o$b2o!')
spark_type3 = g.parse('3bo$b5o$b5o$2b3o!')
spark_type4 = g.parse('3b3o$2b5o$2b5o$4bo!')
elif spark_type_num == 1:
spark_type = g.parse('$b2o$b3o$4o$4o$b3o$b2o!')
spark_type2 = g.parse('$b2o$3o$4o$4o$3o$b2o!')
spark_type3 = g.parse('3b2o$b6o$b6o$2b4o!')
spark_type4 = g.parse('2b4o$b6o$b6o$3b2o!')
elif spark_type_num == 2:
spark_type = g.parse('$2bo$2bo$b3o$2b2o$b3o$2bo$2bo!')
spark_type2 = g.parse('bo$bo$3o$2o$3o$bo$bo!')
spark_type3 = g.parse('$2bobo$7o$2b3o!')
spark_type4 = g.parse('3b3o$b7o$3bobo!')
else:
spark_type = g.parse('2bo$2bo$b3o$2b2o$2b2o$b3o$2bo$2bo!')
spark_type2 = g.parse('bo$bo$3o$2o$2o$3o$bo$bo!')
spark_type3 = g.parse('$2bo2bo$8o$2b4o!')
spark_type4 = g.parse('2b4o$8o$2bo2bo!')
recent_pops = list(range(100,109)) #9 same population in a row: end
recent_min_x = list(range(100,108)) #checking for escaping gliders
current_gen = None
g.new("example")
'''Putting patterns in place'''
if mode == 'C2':
g.putcells(r_down, 0, 0)
num1 = int(g.getpop())
g.putcells(r_up, x, y)
elif mode == 'C4':
g.putcells(r_n, x, y)
num1 = int(g.getpop())
g.putcells(r_e, y, -x-width+1-a)
g.putcells(r_s, -x-width+1-a, -y-height+1-a)
g.putcells(r_w, -y-height+1-a, x)
elif mode == 'D4':
g.putcells(r_se, x, y)
num1 = int(g.getpop())
g.putcells(r_ne, x, 0)
g.putcells(r_nw, 0, 0)
g.putcells(r_sw, 0, y)
elif mode == 'X4':
'''g.putcells(r_n, x, y)
num1 = int(g.getpop())
g.putcells(r_w, 0, y-x-width+height)
g.putcells(r_e, x+y+width-1, -width+1)
g.putcells(r_s, y+height-1, -x-width+1)'''
g.putcells(r_n, x, y)
num1 = int(g.getpop())
g.putcells(r_w, 0, y-x-width+height)
g.putcells(r_e, x+y+width, -width)
g.putcells(r_s, y+height, -x-width)
elif mode == 'D8':
g.putcells(r_n, x, y)
num1 = int(g.getpop())
g.putcells(r_ne, -x-width+1-a, y)
g.putcells(r_e, y, -x-width+1-a)
g.putcells(r_se, y, x)
g.putcells(r_s, -x-width+1-a, -y-height+1-a)
g.putcells(r_sw, x, -y-height+1-a)
g.putcells(r_w, -y-height+1-a, x)
g.putcells(r_nw, -y-height+1-a, -x-width+1-a)
if int(g.getpop()) != copies * num1:
continue
g.run(0)
#if y == 0 and int(g.getpop()) == 32:
# continue
if g.empty():
continue
g.show(str((x,y)))
g.update()
initial_box = g.getrect()
initial_box[0] -= 1 #must not touch initial pattern
initial_box[1] -= 1
initial_box[2] += 2
initial_box[3] += 2
hash1 = g.hash(initial_box)
g.select(initial_box)
g.flip(0)
hash2 = g.hash(initial_box)
g.flip(0)
g.select(g.getrect())
g.rotate(1)
initial_box2 = g.getrect()
initial_box2[0] -= 1 #must not touch initial pattern
initial_box2[1] -= 1
initial_box2[2] += 2
initial_box2[3] += 2
hash3 = g.hash(initial_box2)
g.flip(0)
hash4 = g.hash(initial_box2)
g.flip(0)
g.rotate(0)
generation_snapshots = [''] * 200 #prevents same sequence from repeating
test1 = False
min_x = -100
for generation in range(150):
'''Outer loop'''
#g.show('Generation ' + str(generation))
if generation == 0:
g.run(0)
pass
else:
g.new("example")
g.putcells(current_gen)
if generation > 0:
g.run(1)
if g.getcells(g.getrect()) == current_gen:
break
recent_pops.append(int(g.getpop()))
recent_pops.pop(0)
if recent_pops[-1] < 4 * copies: #no growth
break
if recent_pops[-1] > 125 * copies:
break
if max(recent_pops) == min(recent_pops): #9 generations with same population
break
#if not g.getcell(8,0) or not g.getcell(0,8): #block broken
#break
for w in range(1 if mode in ('D4','D8') else 2):
if w == 1:
g.new("example")
g.putcells(current_gen)
'''min_x = g.getrect()[0]
edge = g.getcells([min_x,-40+y,1,80])[1::2]
if not edge:
current_gen = g.getcells(g.getrect())[:]
continue'''
'''temp = g.getcells(g.getrect())
g.select([-50,0,100,14])
g.clear(0)
if g.empty():
g.putcells(temp,0,0)
current_gen = g.getcells(g.getrect())[:]
continue'''
prev_min_x = min_x
min_x = g.getrect()[0]
#if min_x == x or min_x == 0: #used when there's an eater or still life
# current_gen = g.getcells(g.getrect())[:]
# continue
edge = g.getcells([min_x,-40+y,1,80])[1::2]
if not edge:
#g.putcells(temp,0,0)
current_gen = g.getcells(g.getrect())[:]
continue
'''if prev_min_x == min_x: #not a new leading edge
#g.putcells(temp,0,0)
current_gen = g.getcells(g.getrect())[:]
continue'''
if w == 1 and max(edge) - len(edge) + 1 == min(edge):
#g.putcells(temp,0,0)
current_gen = g.getcells(g.getrect())[:]
continue
while max(edge) - len(edge) + 1 != min(edge):
if w == 1:
edge.remove(max(edge))
else:
edge.remove(min(edge))
#g.putcells(temp,0,0)
current_gen = g.getcells(g.getrect())[:]
#g.update()
#time.sleep(.5)
if w == 0:
recent_min_x.append(min_x)
recent_min_x.pop(0)
'''Checking for gliders'''
if g.getcells([min_x+3,min(edge)-8,3,16]): #not by itself
recent_min_x[-1] = 123
if recent_min_x == [recent_min_x[0]]*4 + [recent_min_x[4]]*4 \
and recent_min_x[4] == recent_min_x[0] - 1:
for i in range(min_x, min_x+3):
for j in range(min(edge),min(edge)+3):
g.setcell(i,j,0) #delete glider
test1 = True
current_gen = g.getcells(g.getrect())[:]
continue
#if not test1:
# continue
'''Determine sparks'''
if len(edge) == 1:
if spark_mode == 'dot':
sparks = [(-2,-1),(-1,0),(0,1),(1,2)]
elif spark_mode == 'neardot':
sparks = [(-1,),(-0,),(1,),(-2,-1),(-1,0),(0,1),(1,2)]
elif spark_mode == 'mwhw':
sparks = [(-3,),(-2,),(-1,),(0,),(1,),(2,),(3,),(4,)]
if len(edge) == 2:
if spark_mode == 'dot':
sparks = [(-1,),(0,),(2,),(-2,-1),(-1,0),(1,2),(2,3)]
elif spark_mode == 'neardot':
sparks = [(-1,),(0,),(1,),(2,),(-2,-1),(-1,0),(0,1),(1,2),(2,3)]
elif spark_mode == 'mwhw':
sparks = [(-3,),(-2,),(-1,),(0,),(1,),(2,),(3,),(4,),(5,)]
if len(edge) == 3:
if spark_mode == 'dot':
sparks = [(-1,),(0,),(1,),(2,),(3,),(-2,-1),(-1,0),(2,3),(3,4)]
elif spark_mode == 'neardot':
sparks = [(-1,),(0,),(1,),(2,),(3,),(-2,-1),(-1,0),(0,1),(1,2),(2,3),(3,4)]
elif spark_mode == 'mwhw':
sparks = [(-3,),(-2,),(-1,),(0,),(1,),(2,),(3,),(4,),(5,),(6,)]
if len(edge) >= 4:
if spark_mode != 'mwhw':
sparks = [(-1,),(0,),(1,),(2,),(3,),(4,),(-2,-1),(-1,0),(0,1),(1,2),(2,3),(3,4),(4,5)]
else:
sparks = [(-3,),(-2,),(-1,),(0,),(1,),(2,),(3,),(4,),(5,),(6,),(7,)]
if spark_mode == 'mwhw' and spark_type_num in (0,2): #edge length 3
sparks = sparks[:-1]
#sparks = [(-20,)]
for spark in sparks:
'''Add sparks'''
g.new("example")
g.putcells(current_gen)
for spark1 in spark:
if mode == 'C2':
if spark_mode == 'mwhw':
g.putcells(spark_type,min_x-5,spark1+min(edge)-4) #-3, -4
g.putcells(spark_type2,-min_x+x+1+width,-spark1-min(edge)+y+height-4)
elif spark_mode == 'dot':
g.setcell(min_x-2,spark1+min(edge),1)
g.setcell(-min_x+x+1+width,-spark1-min(edge)+y-1+height,1)
elif spark_mode == 'neardot':
g.setcell(min_x-1,spark1+min(edge),1)
g.setcell(-min_x+x+width,-spark1-min(edge)+y-1+height,1)
elif mode in ('C4','D8'):
if spark_mode == 'mwhw':
g.putcells(spark_type,min_x-5,spark1+min(edge)-4)
g.putcells(spark_type2,-min_x+2-a,-spark1-min(edge)-3-a)
g.putcells(spark_type3,-spark1-min(edge)-3-a,min_x-5)
g.putcells(spark_type4,spark1+min(edge)-4,-min_x+2-a)
elif spark_mode == 'dot':
g.setcell(min_x-2,spark1+min(edge),1)
g.setcell(-min_x+2-a,-spark1-min(edge)-a,1)
g.setcell(-spark1-min(edge)-a,min_x-2,1)
g.setcell(spark1+min(edge),-min_x+2-a,1)
elif spark_mode == 'neardot':
g.setcell(min_x-1,spark1+min(edge),1)
g.setcell(-min_x+1-a,-spark1-min(edge)-a,1)
g.setcell(-spark1-min(edge)-a,min_x-1,1)
g.setcell(spark1+min(edge),-min_x+1-a,1)
elif mode == 'D4':
if spark_mode == 'mwhw':
g.putcells(spark_type,min_x-5,spark1+min(edge)-4)
g.putcells(spark_type2,-min_x+x+width+1,-spark1+height+y-min(edge)-4)
g.putcells(spark_type,min_x-5,-spark1+height+y-min(edge)-5+(spark_type_num in (1,3)))
g.putcells(spark_type2,-min_x+x+width+1,spark1+min(edge)-3-(spark_type_num in (1,3)))
elif spark_mode == 'dot':
g.setcell(min_x-2,spark1+min(edge),1)
g.setcell(-min_x+x+width+1,-spark1+height+y-min(edge)-1,1)
g.setcell(min_x-2,-spark1+height+y-min(edge)-1,1)
g.setcell(-min_x+x+width+1,spark1+min(edge),1)
elif spark_mode == 'neardot':
g.setcell(min_x-1,spark1+min(edge),1)
g.setcell(-min_x+x+width,-spark1+height+y-min(edge)-1,1)
g.setcell(min_x-1,-spark1+height+y-min(edge)-1,1)
g.setcell(-min_x+x+width,spark1+min(edge),1)
elif mode == 'X4':
center = (x+y+height-1+width, y-x-width+height+1) #actually twice center
offset_x = 2*(min_x-2)-center[0]
offset_y = 2*(spark1+min(edge))-center[1]
if spark_mode == 'mwhw':
g.putcells(spark_type,(center[0]-offset_x)//2-1, (center[1]-offset_y)//2-1)
g.putcells(spark_type2,(center[0]-offset_y)//2-1, (center[1]-offset_x)//2-1)
g.putcells(spark_type3,(center[0]+offset_x)//2, (center[1]+offset_y)//2)
g.putcells(spark_type4,(center[0]+offset_y)//2, (center[1]+offset_x)//2)
elif spark_mode == 'neardot':
g.setcell((center[0]-offset_x)//2, (center[1]-offset_y)//2-2, 1)
g.setcell((center[0]-offset_y)//2-1, (center[1]-offset_x)//2-1, 1)
g.setcell((center[0]+offset_x)//2, (center[1]+offset_y)//2, 1)
g.setcell((center[0]+offset_y)//2+1, (center[1]+offset_x)//2-1, 1)
elif spark_mode == 'dot':
g.setcell((center[0]-offset_x)//2-1, (center[1]-offset_y)//2-2, 1) #-2, -1
g.setcell((center[0]-offset_y)//2-1, (center[1]-offset_x)//2-2, 1) #-1, -2
g.setcell((center[0]+offset_x)//2+1, (center[1]+offset_y)//2, 1) #+1, 0
g.setcell((center[0]+offset_y)//2+1, (center[1]+offset_x)//2, 1) #0, +1
if mode == 'D8':
if spark_mode == 'mwhw':
g.putcells(spark_type,min_x-5,-spark1-min(edge)-4-a+(spark_type_num in (1,3)))
g.putcells(spark_type2,-min_x+2-a,spark1+min(edge)-3-(spark_type_num in (1,3)))
g.putcells(spark_type3,spark1+min(edge)-3-(spark_type_num in (1,3)),min_x-5)
g.putcells(spark_type4,-spark1-min(edge)-4-a+(spark_type_num in (1,3)),-min_x+2-a)
elif spark_mode == 'dot':
g.setcell(min_x-2,-spark1-min(edge)-a,1)
g.setcell(-min_x+2-a,spark1+min(edge),1)
g.setcell(spark1+min(edge),min_x-2,1)
g.setcell(-spark1-min(edge)-a,-min_x+2-a,1)
elif spark_mode == 'neardot':
g.setcell(min_x-1,-spark1-min(edge)-a,1)
g.setcell(-min_x+1-a,spark1+min(edge),1)
g.setcell(spark1+min(edge),min_x-1,1)
g.setcell(-spark1-min(edge)-a,-min_x+1-a,1)
x1, y1 = min_x-5,spark1+min(edge)
current_gen_a = g.getcells(g.getrect())[:]
#g.update()
#time.sleep(.4)
hash_list = []
test2a += 1
recent_pops1 = list(range(100,139)) #40 generations same population: end
for generation1 in range(200):
#g.update()
'''Inner loop'''
g.run(1)
if not int(g.getpop()): #g.getrect() crashes if empty
break
if 5 <= generation1 <= 8: #prevents repeating evolution
if g.hash(g.getrect()) in generation_snapshots:
generation_snapshots.pop(0)
generation_snapshots.append(g.hash(g.getrect()))
if int(g.getpop()) > 6:
test2 += 1
#g.show(str(test2/test2a))
break
generation_snapshots.pop(0)
generation_snapshots.append(g.hash(g.getrect()))
recent_pops1.append(int(g.getpop()))
recent_pops1.pop(0)
#if recent_pops1[-1] < 4 * copies: #no growth
# break
if recent_pops1[-1] > 250 * copies: #too complicated, very unlikely
break
if max(recent_pops1) == min(recent_pops1):
break
if generation1 % 10 == 0: #checks for same pattern
hash_list.append(g.hash(g.getrect()))
if hash_list[-1] in hash_list[:-1]:
break
#if not g.getcell(8,0) or not g.getcell(0,8): #block broken
# break
if generation1 > 3 and g.getcell(x1, y1): #hits sparker
break
if g.hash(initial_box) in (hash1, hash2) or g.hash(initial_box2) in (hash3, hash4):
g.warn("Partial found")
#if y == 2 and generation+generation1 in (45,91):
# continue
#if (y, generation, int(g.getpop())) == (1,2,72):
# continue
g.reset()
g.select(g.getrect())
g.copy()
if generation != 0:
with open("partials.txt", "a") as writefile:
writefile.write(str(generation) + "\n" + str(pyperclip.paste() + "\n"))
writefile.flush()
writefile.close()
#g.warn("Partial found")