-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathMetafierV2.py
78 lines (66 loc) · 3.12 KB
/
MetafierV2.py
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
# Metafier V2: writes directly to output.mc
# Uses numpy and memoization to speed up a crap ton & compress data a bit
# ===REQUIRES metatemplate11.mc===
import golly as g
import numpy as np
from shutil import copyfile
#Get the selection
selection = g.getselrect()
if not selection: g.exit("No selection.")
#Get the cells in the selection
cells = g.getcells(selection)
if not cells: g.exit("No pattern in selection")
if len(cells) % 3: cells = cells[:-1]
selw = selection[2]
selh = selection[3]
patternsize = 1 << int(np.ceil(np.log2(selh | selw)))
metapattern = np.zeros((patternsize, patternsize))
#Pseudo-convolution, to detect diagonal neighbors
# +1 +0 +2
# +0 *16 +0
# +4 +0 +8
for cell in np.reshape(cells, (-1, 3)):
selx = cell[0] - selection[0]
sely = cell[1] - selection[1]
metapattern[sely][selx] += 16 * cell[2]
if sely:
if selx:
metapattern[sely - 1][selx - 1] += 8
if selx + 1 < selw:
metapattern[sely - 1][selx + 1] += 4
if sely + 1 < selh:
if selx:
metapattern[sely + 1][selx - 1] += 2
if selx + 1 < selw:
metapattern[sely + 1][selx + 1] += 1
#Remove all B/S cells
metapattern[metapattern < 32] = np.nan
metapattern += 5630 - 32 #5632 is starting point of 11s in template
metapattern[np.isnan(metapattern)] = 0
metapattern = metapattern.astype(int)
#Using metatemplate11, memoization, and some recursion
def createLine(pattern, outfile, linenum = [5726], memo = {}): #linenum and memo are mutable function arguments, which are only initialized during function definition
if tuple(pattern.ravel().tolist()) not in memo: #If we haven't seen this type of pattern before, let's remember it
if pattern.shape[0] == 2: #Pattern is a leaf, write leaf line
outfile.write('{} {} {} {} {}\n'.format(pattern.shape[0].bit_length() + 10,
pattern[0, 0],
pattern[0, 1],
pattern[1, 0],
pattern[1, 1]))
else: #Pattern is a branch, keep going down quadtree
subpatterns = pattern.reshape(2, pattern.shape[0] >> 1, 2, pattern.shape[0] >> 1).swapaxes(1,2)
outfile.write('{} {} {} {} {}\n'.format(pattern.shape[0].bit_length() + 10,
createLine(subpatterns[0, 0], outfile),
createLine(subpatterns[0, 1], outfile),
createLine(subpatterns[1, 0], outfile),
createLine(subpatterns[1, 1], outfile)))
memo[tuple(pattern.ravel().tolist())] = linenum[0]
linenum[0] += 1
return memo[tuple(pattern.ravel().tolist())]
copyfile('metatemplate11.mc', 'output.mc')
with open('output.mc', 'a') as outputfile:
createLine(metapattern, outputfile)
#Display output.mc
g.addlayer()
g.open('output.mc')
#TODO: Use metatemplate10?