diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..570f03f
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+oldimages/
+.spyproject/
diff --git a/common.py b/common.py
new file mode 100644
index 0000000..80cffec
--- /dev/null
+++ b/common.py
@@ -0,0 +1,46 @@
+# -*- coding: utf-8 -*-
+"""
+Created on Mon Mar 12 20:43:12 2018
+
+@author: Isaac
+"""
+
+import logging
+logger = logging.getLogger(__name__)
+logger.setLevel(logging.INFO)
+
+def StuffRandom(source_array, random_value):
+ a_sum = sum(source_array)
+
+ if 0 == a_sum:
+ for j in range(0, len(source_array)):
+ source_array[j] = 1
+ a_sum = sum(source_array)
+ for j in range(0, len(source_array)):
+ source_array[j] /= a_sum
+ i = 0
+ x = 0
+ while (i < len(source_array)):
+ x += source_array[i]
+ if random_value <= x:
+ return i
+ i += 1
+ return 0
+
+def StuffPower(a, n):
+ product = 1
+ for i in range(0, n):
+ product *= a
+ return product
+
+# TODO: finish StuffGet
+def StuffGet(xml_node, xml_attribute, default_t):
+ s = ""
+ if s == "":
+ return default_t
+ return s
+
+def string2bool(strn):
+ if isinstance(strn, bool):
+ return strn
+ return strn.lower() in ["true"]
diff --git a/learning.xml b/learning.xml
new file mode 100644
index 0000000..0d25603
--- /dev/null
+++ b/learning.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/learnmodel.py b/learnmodel.py
new file mode 100644
index 0000000..173562f
--- /dev/null
+++ b/learnmodel.py
@@ -0,0 +1,516 @@
+# -*- coding: utf-8 -*-
+"""
+Created on Mon Mar 12 20:41:23 2018
+
+@author: Isaac
+"""
+
+import model
+import common
+
+import collections
+
+from sklearn import tree
+
+try:
+ import Image
+except ImportError:
+ from PIL import Image
+
+class LearningModel(model.Model):
+
+ def __init__(self, width, height, name, N_value = 2, periodic_input_value = True, periodic_output_value = False, symmetry_value = 8, ground_value = 0, ground_end = 0, additional_samples=[], additional_periodic="", antipatterns=""):
+ """
+ Initializes the model.
+ """
+ super(LearningModel, self).__init__(width, height)
+ self.propagator = [[[[]]]]
+ self.whitelist = [[[[]]]]
+ self.blacklist = [[[[]]]]
+ self.possiblelist = [[[[]]]]
+ self.allowedlist = [[[[]]]]
+ self.disallowedlist = [[[[]]]]
+ self.observedlist= [[[[]]]]
+
+ self.N = N_value
+ self.periodic = periodic_output_value
+ self.bitmaps = [Image.open("samples/{0}.png".format(name)).convert("RGBA")]
+ self.SMXs = [self.bitmaps[0].size[0]]
+ self.SMYs = [self.bitmaps[0].size[1]]
+ self.samples = [[[0 for _ in range(self.SMYs[0])] for _ in range(self.SMXs[0])]]
+
+ self.antipattern_flags = [int(x) for x in list(antipatterns.ljust(len(additional_samples) + 1, '0'))]
+ #print(self.antipattern_flags)
+
+ add_periodic = 0
+ if periodic_input_value:
+ add_periodic = 1
+ self.periodic_flags = [add_periodic] + [int(x) for x in list(additional_periodic.ljust(len(additional_samples), str(add_periodic)))]
+ #print(self.periodic_flags)
+
+ for additional in additional_samples:
+ self.bitmaps.append(Image.open("samples/{0}.png".format(additional)).convert("RGBA"))
+ add_index = len(self.bitmaps)-1
+ self.SMXs.append(self.bitmaps[add_index].size[0])
+ self.SMYs.append(self.bitmaps[add_index].size[1])
+ self.samples.append([[0 for _ in range(self.SMYs[add_index])] for _ in range(self.SMXs[add_index])])
+
+# self.antibitmaps = []
+# self.aSMXs = []
+# self.aSMYs = []
+# self.antisamples = []
+# for anti in antipatterns:
+# self.antibitmaps.append(Image.open("samples/{0}.png".format(anti)))
+# add_index = len(self.antibitmaps)-1
+# self.SMXs.append(self.antibitmaps[add_index].size[0])
+# self.SMYs.append(self.antibitmaps[add_index].size[1])
+# self.antisamples.append([[0 for _ in range(self.aSMYs[add_index])] for _ in range(self.aSMXs[add_index])])
+
+
+
+ self.colors = []
+ for samp_n in range(len(self.bitmaps)):
+ for y in range(0, self.SMYs[samp_n]):
+ for x in range(0, self.SMXs[samp_n]):
+ a_color = self.bitmaps[samp_n].getpixel((x, y))
+ color_exists = [c for c in self.colors if c == a_color]
+ if len(color_exists) < 1:
+ self.colors.append(a_color)
+ samp_result = [i for i,v in enumerate(self.colors) if v == a_color]
+ self.samples[samp_n][x][y] = samp_result
+
+ #for c in self.colors:
+ # print(c)
+
+ self.color_count = len(self.colors)
+ self.W = common.StuffPower(self.color_count, self.N * self.N)
+
+ # The pattern matrix, as an array of arrays.
+ self.patterns= [[]]
+ #self.ground = 0
+
+ # Additional samples can individually be marked as periodic/non-periodic
+ #periodic_input_values = [periodic_input_value]
+ #for _ in range(len(self.bitmaps)):
+ # periodic_input_values.append(periodic_input_value)
+ #for idx_peri, peri in enumerate(additional_periodic):
+ # periodic_input_values[idx_peri + 1] = ((1 == peri) or ('T' == peri) or ('True' == peri))
+
+
+ def FuncPattern(passed_func):
+ result = [0 for _ in range(self.N * self.N)]
+ for y in range(0, self.N):
+ for x in range(0, self.N):
+ result[x + (y * self.N)] = passed_func(x, y)
+ return result
+
+ pattern_func = FuncPattern
+
+ def PatternFromSample(x, y, n=0):
+ def innerPattern(dx, dy):
+ return self.samples[n][(x + dx) % self.SMXs[n]][(y + dy) % self.SMYs[n]]
+ return pattern_func(innerPattern)
+ def Rotate(p):
+ '''
+ Returns a rotated version of the pattern.
+ '''
+ return FuncPattern(lambda x, y: p[self.N - 1 - y + x * self.N])
+ def Reflect(p):
+ '''
+ Returns a reflected version of the pattern.
+ '''
+ return FuncPattern(lambda x, y: p[self.N - 1 - x + y * self.N])
+
+ def Index(p):
+ '''
+ Converts a color index into a powers-of-two representation for
+ bytewise storage.
+ '''
+ result = 0
+ power = 1
+ for i in range(0, len(p)):
+ result = result + (sum(p[len(p) - 1 - i]) * power)
+ power = power * self.color_count
+ return result
+
+
+
+ def PatternFromIndex(ind):
+ '''
+ Takes a pattern index and returns the pattern byte array.
+ '''
+ residue = ind
+ power = self.W
+ result = [None for _ in range(self.N * self.N)]
+ for i in range(0, len(result)):
+ power = power / self.color_count
+ count = 0
+ while residue >= power:
+ residue = residue - power
+ count = count + 1
+ result[i] = count
+ return result
+
+ self.weights = collections.Counter()
+ ordering = []
+ antiordering = []
+ self.anti_adjacency = []
+
+ for samp_n in range(len(self.bitmaps)):
+ ylimit = self.SMYs[samp_n] - self.N + 1
+ xlimit = self.SMXs[samp_n] - self.N + 1
+ if 1 == self.periodic_flags[samp_n]:
+ ylimit = self.SMYs[samp_n]
+ xlimit = self.SMXs[samp_n]
+ for y in range (0, ylimit):
+ for x in range(0, xlimit):
+ ps = [0 for _ in range(8)]
+ ps[0] = PatternFromSample(x,y,samp_n)
+ ps[1] = Reflect(ps[0])
+ ps[2] = Rotate(ps[0])
+ ps[3] = Reflect(ps[2])
+ ps[4] = Rotate(ps[2])
+ ps[5] = Reflect(ps[4])
+ ps[6] = Rotate(ps[4])
+ ps[7] = Reflect(ps[6])
+ for k in range(0,symmetry_value):
+ ind = Index(ps[k])
+ common.logger.info('pattern: ' + str(ps[k]) + ' index ' + str(ind))
+ if 1 == self.antipattern_flags[samp_n]:
+ if not ind in antiordering:
+ antiordering.append(ind)
+ indexed_weight = collections.Counter({ind : 1})
+ self.weights = self.weights + indexed_weight
+ if not ind in ordering:
+ ordering.append(ind)
+
+ #for indo, o in enumerate(ordering):
+ # print(indo, o, PatternFromIndex(o))
+ self.T = len(self.weights)
+ self.ground = (int((ground_value + self.T) % self.T), int((ground_value + self.T) % self.T))#(102,106)# int((ground_value + self.T) % self.T)
+ if ground_end > 0 and None != ground_end:
+ self.gound = (ground_value, ground_end)
+ #print('self.ground',self.ground)
+
+ self.patterns = [[None] for _ in range(self.T)]
+ self.stationary = [None for _ in range(self.T)]
+ self.propagator = [[[[0]]] for _ in range(2 * self.N - 1)]
+ self.whitelist = [[[[0]]] for _ in range(2 * self.N - 1)]
+ self.blacklist = [[[[0]]] for _ in range(2 * self.N - 1)]
+ self.possiblelist = [[[[0]]] for _ in range(2 * self.N - 1)]
+ self.allowedlist = [[[[0]]] for _ in range(2 * self.N - 1)]
+ self.disallowedlist = [[[[0]]] for _ in range(2 * self.N - 1)]
+ self.observedlist = [[[[0]]] for _ in range(2 * self.N - 1)]
+
+ self.antipatterns = [[None] for _ in antiordering]
+
+ for w in antiordering:
+ self.antipatterns.append(PatternFromIndex(w))
+
+ counter = 0
+ for w in ordering:
+ self.patterns[counter] = PatternFromIndex(w)
+ self.stationary[counter] = self.weights[w]
+ counter += 1
+
+
+
+ for samp_n in range(len(self.bitmaps)):
+ if 1 == self.antipattern_flags[samp_n]:
+ #print('sample #',samp_n)
+ ylimit = self.SMYs[samp_n] - self.N + 1
+ xlimit = self.SMXs[samp_n] - self.N + 1
+ if 1 == self.periodic_flags[samp_n]:
+ ylimit = self.SMYs[samp_n]
+ xlimit = self.SMXs[samp_n]
+ #print('limits',xlimit, ylimit, self.periodic_flags[samp_n])
+ for py in range (0, ylimit):
+ for px in range(0, xlimit):
+ pattern_one = PatternFromIndex(Index(PatternFromSample(px,py,samp_n)))
+ #print('pattern_one', pattern_one)
+ for tx in range(1 - self.N, self.N):
+ for ty in range(1 - self.N,self.N):
+ #print(tx,ty)
+ if not (tx == 0 and ty == 0):
+ if (1 == self.periodic_flags[samp_n]) or ((px + tx >= 0) and (py + ty >= 0) and (px + tx < xlimit) and (py + ty < ylimit)):
+ pattern_two = PatternFromIndex(Index(PatternFromSample(px+tx,py+ty,samp_n)))
+ #print('pattern_two', pattern_two, px + tx, py + ty, tx, ty)
+ self.anti_adjacency.append((pattern_one, pattern_two, (tx, ty)))
+ #print('create antipattern', (pattern_one, pattern_two, (tx, ty)))
+
+ for x in range(0, self.FMX):
+ for y in range(0, self.FMY):
+ self.wave[x][y] = [False for _ in range(self.T)]
+
+
+ def Disallowed(p1, p2, dx, dy):
+ #print(p1,p2,'\n---\n')
+ for anti_adj in self.anti_adjacency:
+ #print(anti_adj)
+ if (anti_adj[0] == p1 and anti_adj[1] == p2):
+ if dx == anti_adj[2][0] and dy == anti_adj[2][1]:
+ #print('antipattern:',p1,p2,dx,dy,'\n',anti_adj,'\n')
+ return True
+ return False
+
+ def Agrees(p1, p2, dx, dy):
+ ifany = True
+ xmin = dx
+ xmax = self.N
+ if dx < 0:
+ xmin = 0
+ xmax = dx + self.N
+ ymin = dy
+ ymax = self.N
+ if dy < 0:
+ ymin = 0
+ ymax = dy + self.N
+ for y in range(ymin, ymax):
+ for x in range(xmin, xmax):
+ if p1[x + self.N * y] != p2[x - dx + self.N * (y - dy)]:
+ common.logger.debug(p1[x + self.N * y] != p2[x - dx + self.N * (y - dy)])
+ ifany = False
+ #return False
+ return ifany
+ #return True
+
+ # create total whitelist
+ for x in range(0, 2 * self.N - 1):
+ self.possiblelist[x] = [[[0]] for _ in range(2 * self.N - 1)]
+ for y in range(0, 2 * self.N - 1):
+ self.possiblelist[x][y] = [[0] for _ in range(self.T)]
+ for t in range(0, self.T):
+ a_list = []
+ for t2 in range(0, self.T):
+ a_list.append(t2)
+ self.possiblelist[x][y][t] = [0 for _ in range(len(a_list))]
+ for c in range(0, len(a_list)):
+ self.possiblelist[x][y][t][c] = a_list[c]
+
+
+
+ for x in range(0, 2 * self.N - 1):
+ self.observedlist[x] = [[[0]] for _ in range(2 * self.N - 1)]
+ self.allowedlist[x] = [[[0]] for _ in range(2 * self.N - 1)]
+ self.disallowedlist[x] = [[[0]] for _ in range(2 * self.N - 1)]
+ for y in range(0, 2 * self.N - 1):
+ self.observedlist[x][y] = [[0] for _ in range(self.T)]
+ self.allowedlist[x][y] = [[0] for _ in range(self.T)]
+ self.disallowedlist[x][y] = [[0] for _ in range(self.T)]
+
+ for t in range(0, self.T):
+ o_list = []
+ a_list = []
+ d_list = []
+ for t2 in range(0, self.T):
+ if not Disallowed(self.patterns[t], self.patterns[t2], x - self.N + 1, y - self.N + 1):
+ if Agrees(self.patterns[t], self.patterns[t2], x - self.N + 1, y - self.N + 1):
+ a_list.append(t2)
+ o_list.append(t2)
+ else:
+ d_list.append(t2)
+ if Agrees(self.patterns[t], self.patterns[t2], x - self.N + 1, y - self.N + 1):
+ a_list.append(t2)
+ self.observedlist[x][y][t] = [0 for _ in range(len(o_list))]
+ for c in range(0, len(o_list)):
+ self.observedlist[x][y][t][c] = o_list[c]
+ self.allowedlist[x][y][t] = [0 for _ in range(len(a_list))]
+ for c in range(0, len(a_list)):
+ self.allowedlist[x][y][t][c] = a_list[c]
+ self.disallowedlist[x][y][t] = [0 for _ in range(len(d_list))]
+ for c in range(0, len(d_list)):
+ self.disallowedlist[x][y][t][c] = d_list[c]
+
+ self.propagator = self.observedlist.copy()
+ #print(self.FlattenPropagator(self.observedlist))
+ self.propagator = self.UnflattenPropagator(self.FlattenPropagator(self.observedlist)).copy()
+# print()
+# for ix, x in enumerate(self.propagator):
+# for iy, y in enumerate(x):
+# for it, t in enumerate(y):
+# print(ix, ',', iy, ':', it, '>>', t)
+
+ return
+
+ def FlattenPropagator(self, prop):
+ def Dehydrate(node):
+ return '{}_{}_{}'.format(node[0], node[1], node[2])
+ flatprop = []
+ for x in range(0, 2 * self.N - 1):
+ for y in range(0, 2 * self.N - 1):
+ for t in range(0, self.T):
+ for t2 in prop[x][y][t]:
+ flatprop.append([Dehydrate([t, x, y]), t2])
+ prop_dict = collections.defaultdict(list)
+ for x in flatprop:
+ prop_dict[x[0]].append(x[1])
+
+ return prop_dict.copy()
+
+ def UnflattenPropagator(self, prop_dict):
+ prop = []
+ for d in prop_dict:
+ for p in prop_dict[d]:
+ prop.append([d, p])
+ hydratedlist = [[[[0]]] for _ in range(2 * self.N - 1)]
+ for x in range(0, 2 * self.N - 1):
+ hydratedlist[x] = [[[0]] for _ in range(2 * self.N - 1)]
+ for y in range(0, 2 * self.N - 1):
+ hydratedlist[x][y] = [[0] for _ in range(self.T)]
+ for t in range(0, self.T):
+ hydratedlist[x][y][t] = []
+ def Rehydrate(node):
+ return [int(x) for x in node.split('_')]
+ for p in prop:
+ t, x, y = Rehydrate(p[0])
+ hydratedlist[x][y][t].append(p[1])
+
+
+ return hydratedlist
+
+ def OnBoundary(self, x, y):
+ return (not self.periodic) and ((x + self.N > self.FMX ) or (y + self.N > self.FMY))
+
+ def Propagate(self):
+ change = False
+ b = False
+
+ #x2 = None
+ #y2 = None
+ for x1 in range(0, self.FMX):
+ for y1 in range(0, self.FMY):
+ if (self.changes[x1][y1]):
+ self.changes[x1][y1] = False
+ dx = (0 - self.N) + 1
+ while dx < self.N:
+ #for dx in range(1 - self.N, self.N):
+ dy = (0 - self.N) + 1
+ while dy < self.N:
+ #for dy in range(1 - self.N, self.N):
+ x2 = x1 + dx
+ if x2 < 0:
+ x2 += self.FMX
+ elif x2 >= self.FMX:
+ x2 -= self.FMX
+ y2 = y1 + dy
+ if y2 < 0:
+ y2 += self.FMY
+ elif y2 >= self.FMY:
+ y2 -= self.FMY
+
+ if (not self.periodic) and (x2 + self.N > self.FMX or y2 + self.N > self.FMY):
+ pass
+ else:
+
+ w1 = self.wave[x1][y1]
+ w2 = self.wave[x2][y2]
+
+ p = self.propagator[(self.N - 1) - dx][(self.N - 1) - dy]
+
+ for t2 in range(0,self.T):
+ if (not w2[t2]):
+ pass
+ else:
+ b = False
+ prop = p[t2]
+ #print("Prop: {0}".format(prop))
+ i_one = 0
+ while (i_one < len(prop)) and (False == b):
+ b = w1[prop[i_one]]
+ i_one += 1
+ if False == b:
+ self.changes[x2][y2] = True
+ change = True
+ w2[t2] = False
+ dy += 1
+ dx += 1
+
+ return change
+
+ def Graphics(self, monochrome=True):
+ result = Image.new("RGB",(self.FMX, self.FMY),(0,0,0))
+ bitmap_data = list(result.getdata())
+ if(self.observed != None):
+ print(self.observed)
+ print(self.patterns)
+ for y in range(0, self.FMY):
+ dy = self.N - 1
+ if (y < (self.FMY - self.N + 1)):
+ dy = 0
+ for x in range(0, self.FMX):
+ dx = 0
+ if (x < (self.FMX - self.N + 1)):
+ dx = self.N - 1
+ local_obsv = self.observed[x - dx][y - dy]
+ local_patt = self.patterns[local_obsv][dx + dy * self.N]
+ c = self.colors[local_patt]
+ #bitmap_data[x + y * self.FMX] = (0xff000000 | (c.R << 16) | (c.G << 8) | c.B)
+ if isinstance(c, (int, float)):
+ bitmap_data[x + y * self.FMX] = (c, c, c)
+ else:
+ bitmap_data[x + y * self.FMX] = (c[0], c[1], c[2])
+
+ else:
+ for y in range(0, self.FMY):
+ for x in range(0, self.FMX):
+ contributors = 0
+ r = 0
+ g = 0
+ b = 0
+ for dy in range(0, self.N):
+ for dx in range(0, self.N):
+ sx = x - dx
+ if sx < 0:
+ sx += self.FMX
+ sy = y - dy
+ if sy < 0:
+ sy += self.FMY
+ if (self.OnBoundary(sx, sy)):
+ pass
+ else:
+ for t in range(0, self.T):
+ if self.wave[sx][sy][t]:
+ contributors += 1
+ color = self.colors[self.patterns[t][dx + dy * self.N]]
+ if isinstance(color, (int, float)):
+ r = int(color)
+ g = int(color)
+ b = int(color)
+ else:
+ r += int(color[0])#.R
+ g += int(color[1])#.G
+ b += int(color[2])#.B
+ #bitmap_data[x + y * self.FMX] = (0xff000000 | ((r / contributors) << 16) | ((g / contributors) << 8) | (b / contributors))
+ if contributors > 0:
+ bitmap_data[x + y * self.FMX] = (int(r / contributors), int(g / contributors), int(b / contributors))
+ else:
+ common.logger.info("INFO: No contributors")
+ bitmap_data[x + y * self.FMX] = (int(r), int(g), int(b))
+ result.putdata(bitmap_data)
+ return result
+
+ def Clear(self):
+ super(LearningModel, self).Clear()
+ if(self.ground != (0,0) ):
+
+ for x in range(0, self.FMX):
+ for t in range(0, self.T):
+ #print('clear?',x,t,(t != self.ground),self.wave[x][self.FMY - 1][t],self.changes[x][self.FMY - 1], self.FMY - 1)
+ if not (t in self.ground):
+ self.wave[x][self.FMY - 1][t] = False
+ self.changes[x][self.FMY - 1] = True
+
+ for y in range(0, self.FMY - 1):
+ for g in range(self.ground[0], self.ground[1]):
+ print(self.wave)
+ print(self.wave[x])
+ print(self.wave[x][y])
+ print(x,y,g)
+ print(self.wave[x][y][g])
+ self.wave[x][y][g] = False
+ self.changes[x][y] = True
+ while self.Propagate():
+ pass
+
+
+
diff --git a/model.py b/model.py
index b1d7851..fdbd0f3 100644
--- a/model.py
+++ b/model.py
@@ -9,11 +9,10 @@
# The software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or the use or other dealings in the software.
#
+import common
+
import math
import random
-import xml.etree.ElementTree as ET
-import collections
-import uuid # used for tracking experiments
try:
import Image
@@ -22,7 +21,8 @@
hackstring = ""
hackcount = 0
-
+
+
class Model:
def __init__(self, width, height):
#initialize
@@ -48,6 +48,8 @@ def __init__(self, width, height):
self.observe_count = 0
self.count_prop_passes = 0
+
+ self.SAVE_IN_PROGRESS = True
def Observe(self):
self.observe_count += 1
@@ -98,10 +100,14 @@ def Observe(self):
observed_min = entropy + noise
argminx = x
argminy = y
-
+ def TrueIndex(cont):
+ return [idx for idx, i in enumerate(cont) if i]
+
# No minimum entropy, so mark everything as being observed...
if (-1 == argminx) and (-1 == argminy):
self.observed = [[0 for _ in range(self.FMY)] for _ in range(self.FMX)]
+ print('self.wave',[[TrueIndex(y) for y in x] for x in self.wave])
+
for x in range(0, self.FMX):
self.observed[x] = [0 for _ in range(self.FMY)]
for y in range(0, self.FMY):
@@ -109,13 +115,14 @@ def Observe(self):
if self.wave[x][y][t]:
self.observed[x][y] = t
break
+ print('self.observed', self.observed)
return True
# A minimum point has been found, so prep it for propogation...
distribution = [0 for _ in range(0,self.T)]
for t in range(0,self.T):
distribution[t] = self.stationary[t] if self.wave[argminx][argminy][t] else 0
- r = StuffRandom(distribution, self.rng.random())
+ r = common.StuffRandom(distribution, self.rng.random())
for t in range(0,self.T):
self.wave[argminx][argminy][t] = (t == r)
self.changes[argminx][argminy] = True
@@ -142,7 +149,8 @@ def Run(self, seed, limit):
while(presult):
presult = self.Propagate()
- self.Graphics().save("in_progress_{0}_{1}.png".format(hackstring, hackcount), format="PNG")
+ if self.SAVE_IN_PROGRESS:
+ self.Graphics().save("in_progress_{0}_{1}.png".format(hackstring, hackcount), format="PNG")
hackcount += 1
#print("Propagate: {0}".format(pcount))
@@ -167,326 +175,6 @@ def OnBoundary(self, x, y):
def Graphics(self):
return Image.new("RGB",(self.FMX, self.FMY),(0,0,0))
-class OverlappingModel(Model):
-
- def __init__(self, width, height, name, N_value = 2, periodic_input_value = True, periodic_output_value = False, symmetry_value = 8, ground_value = 0):
- """
- Initializes the model.
- """
- super( OverlappingModel, self).__init__(width, height)
- self.propagator = [[[[]]]]
- self.N = N_value
- self.periodic = periodic_output_value
- self.bitmap = Image.open("samples/{0}.png".format(name))
- self.SMX = self.bitmap.size[0]
- self.SMY = self.bitmap.size[1]
-
- # .sample is an array of arrays that holds the index values for colors
- # as found in the source image
- self.sample = [[0 for _ in range(self.SMY)] for _ in range(self.SMX)]
- # .colors is the list of colors that are found in the source image
- self.colors = []
-
- # This initializes the .sample array with the color index values.
- # It loops over the pixels in the source bitmap, adds the color to the
- # list of colors if it is new, and sets the .sample x,y value to the
- # index of the color in the list of colors.
- for y in range(0, self.SMY):
- for x in range(0, self.SMX):
- a_color = self.bitmap.getpixel((x, y))
- color_exists = [c for c in self.colors if c == a_color]
- if len(color_exists) < 1:
- self.colors.append(a_color)
- samp_result = [i for i,v in enumerate(self.colors) if v == a_color]
- self.sample[x][y] = samp_result
-
-
- self.color_count = len(self.colors)
- self.W = StuffPower(self.color_count, self.N * self.N)
-
- # The pattern matrix, as an array of arrays.
- self.patterns= [[]]
- #self.ground = 0
-
- # A helper function to extract the neighboring cells from the sample
- # matrix. Takes a function that translates (dx,dy) into a reference to
- # a cell in the matrix.
- def FuncPattern(passed_func):
- result = [0 for _ in range(self.N * self.N)]
- for y in range(0, self.N):
- for x in range(0, self.N):
- result[x + (y * self.N)] = passed_func(x, y)
- return result
-
- pattern_func = FuncPattern
-
- def PatternFromSample(x, y):
- '''
- Takes the sample and returns the pattern for that (x,y) location.
- '''
- def innerPattern(dx, dy):
- return self.sample[(x + dx) % self.SMX][(y + dy) % self.SMY]
- return pattern_func(innerPattern)
- def Rotate(p):
- '''
- Returns a rotated version of the pattern.
- '''
- return FuncPattern(lambda x, y: p[self.N - 1 - y + x * self.N])
- def Reflect(p):
- '''
- Returns a reflected version of the pattern.
- '''
- return FuncPattern(lambda x, y: p[self.N - 1 - x + y * self.N])
-
- def Index(p):
- '''
- Converts a color index into a powers-of-two representation for
- bytewise storage.
- '''
- result = 0
- power = 1
- for i in range(0, len(p)):
- result = result + (sum(p[len(p) - 1 - i]) * power)
- power = power * self.color_count
- return result
-
-
-
- def PatternFromIndex(ind):
- '''
- Takes a pattern index and returns the pattern byte power index.
- '''
- residue = ind
- power = self.W
- result = [None for _ in range(self.N * self.N)]
- for i in range(0, len(result)):
- power = power / self.color_count
- count = 0
- while residue >= power:
- residue = residue - power
- count = count + 1
- result[i] = count
- return result
-
- self.weights = collections.Counter()
- ordering = []
-
- # This chunk converts the sample to patterns.
- # SMX and SMY are the sample size x and y.
- # if periodic_input_value is true, the source image wraps around
- ylimit = self.SMY - self.N + 1
- xlimit = self.SMX - self.N + 1
- if True == periodic_input_value:
- ylimit = self.SMY
- xlimit = self.SMX
- for y in range (0, ylimit):
- for x in range(0, xlimit):
- ps = [0 for _ in range(8)]
- ps[0] = PatternFromSample(x,y)
- ps[1] = Reflect(ps[0])
- ps[2] = Rotate(ps[0])
- ps[3] = Reflect(ps[2])
- ps[4] = Rotate(ps[2])
- ps[5] = Reflect(ps[4])
- ps[6] = Rotate(ps[4])
- ps[7] = Reflect(ps[6])
- for k in range(0,symmetry_value):
- ind = Index(ps[k])
- indexed_weight = collections.Counter({ind : 1})
- self.weights = self.weights + indexed_weight
- if not ind in ordering:
- ordering.append(ind)
-
- self.T = len(self.weights)
- self.ground = int((ground_value + self.T) % self.T)
-
- self.patterns = [[None] for _ in range(self.T)]
- self.stationary = [None for _ in range(self.T)]
- self.propagator = [[[[0]]] for _ in range(2 * self.N - 1)]
-
- counter = 0
- for w in ordering:
- self.patterns[counter] = PatternFromIndex(w)
- self.stationary[counter] = self.weights[w]
- counter += 1
-
- for x in range(0, self.FMX):
- for y in range(0, self.FMY):
- self.wave[x][y] = [False for _ in range(self.T)]
-
- def Agrees(p1, p2, dx, dy):
- ifany = True
- xmin = dx
- xmax = self.N
- if dx < 0:
- xmin = 0
- xmax = dx + self.N
- ymin = dy
- ymax = self.N
- if dy < 0:
- ymin = 0
- ymax = dy + self.N
- for y in range(ymin, ymax):
- for x in range(xmin, xmax):
- if p1[x + self.N * y] != p2[x - dx + self.N * (y - dy)]:
- print(p1[x + self.N * y] != p2[x - dx + self.N * (y - dy)])
- ifany = False
- #return False
- return ifany
- #return True
-
- for x in range(0, 2 * self.N - 1):
- self.propagator[x] = [[[0]] for _ in range(2 * self.N - 1)]
- for y in range(0, 2 * self.N - 1):
- self.propagator[x][y] = [[0] for _ in range(self.T)]
-
- for t in range(0, self.T):
- a_list = []
- for t2 in range(0, self.T):
- if Agrees(self.patterns[t], self.patterns[t2], x - self.N + 1, y - self.N + 1):
- a_list.append(t2)
- self.propagator[x][y][t] = [0 for _ in range(len(a_list))]
- for c in range(0, len(a_list)):
- self.propagator[x][y][t][c] = a_list[c]
- return
-
- def OnBoundary(self, x, y):
- return (not self.periodic) and ((x + self.N > self.FMX ) or (y + self.N > self.FMY))
-
- def Propagate(self):
- change = False
- b = False
-
- #x2 = None
- #y2 = None
- for x1 in range(0, self.FMX):
- for y1 in range(0, self.FMY):
- if (self.changes[x1][y1]):
- self.changes[x1][y1] = False
- dx = (0 - self.N) + 1
- while dx < self.N:
- #for dx in range(1 - self.N, self.N):
- dy = (0 - self.N) + 1
- while dy < self.N:
- #for dy in range(1 - self.N, self.N):
- x2 = x1 + dx
- if x2 < 0:
- x2 += self.FMX
- elif x2 >= self.FMX:
- x2 -= self.FMX
- y2 = y1 + dy
- if y2 < 0:
- y2 += self.FMY
- elif y2 >= self.FMY:
- y2 -= self.FMY
-
- if (not self.periodic) and (x2 + self.N > self.FMX or y2 + self.N > self.FMY):
- pass
- else:
-
- w1 = self.wave[x1][y1]
- w2 = self.wave[x2][y2]
-
- p = self.propagator[(self.N - 1) - dx][(self.N - 1) - dy]
-
- for t2 in range(0,self.T):
- if (not w2[t2]):
- pass
- else:
- b = False
- prop = p[t2]
- #print("Prop: {0}".format(prop))
- i_one = 0
- while (i_one < len(prop)) and (False == b):
- b = w1[prop[i_one]]
- i_one += 1
- if False == b:
- self.changes[x2][y2] = True
- change = True
- w2[t2] = False
- dy += 1
- dx += 1
-
- return change
-
- def Graphics(self):
- result = Image.new("RGB",(self.FMX, self.FMY),(0,0,0))
- bitmap_data = list(result.getdata())
- if(self.observed != None):
- for y in range(0, self.FMY):
- dy = self.N - 1
- if (y < (self.FMY - self.N + 1)):
- dy = 0
- for x in range(0, self.FMX):
- dx = 0
- if (x < (self.FMX - self.N + 1)):
- dx = self.N - 1
- local_obsv = self.observed[x - dx][y - dy]
- local_patt = self.patterns[local_obsv][dx + dy * self.N]
- c = self.colors[local_patt]
- #bitmap_data[x + y * self.FMX] = (0xff000000 | (c.R << 16) | (c.G << 8) | c.B)
- if isinstance(c, (int, float)):
- bitmap_data[x + y * self.FMX] = (c, c, c)
- else:
- bitmap_data[x + y * self.FMX] = (c[0], c[1], c[2])
-
- else:
- for y in range(0, self.FMY):
- for x in range(0, self.FMX):
- contributors = 0
- r = 0
- g = 0
- b = 0
- for dy in range(0, self.N):
- for dx in range(0, self.N):
- sx = x - dx
- if sx < 0:
- sx += self.FMX
- sy = y - dy
- if sy < 0:
- sy += self.FMY
- if (self.OnBoundary(sx, sy)):
- pass
- else:
- for t in range(0, self.T):
- if self.wave[sx][sy][t]:
- contributors += 1
- color = self.colors[self.patterns[t][dx + dy * self.N]]
- if isinstance(color, (int, float)):
- r = int(color)
- g = int(color)
- b = int(color)
- else:
- r += int(color[0])#.R
- g += int(color[1])#.G
- b += int(color[2])#.B
- #bitmap_data[x + y * self.FMX] = (0xff000000 | ((r / contributors) << 16) | ((g / contributors) << 8) | (b / contributors))
- if contributors > 0:
- bitmap_data[x + y * self.FMX] = (int(r / contributors), int(g / contributors), int(b / contributors))
- else:
- print("WARNING: No contributors")
- bitmap_data[x + y * self.FMX] = (int(r), int(g), int(b))
- result.putdata(bitmap_data)
- return result
-
- def Clear(self):
- super(OverlappingModel, self).Clear()
- if(self.ground != 0 ):
-
- for x in range(0, self.FMX):
- for t in range(0, self.T):
- if t != self.ground:
- self.wave[x][self.FMY - 1][t] = False
- self.changes[x][self.FMY - 1] = True
-
- for y in range(0, self.FMY - 1):
- self.wave[x][y][self.ground] = False
- self.changes[x][y] = True
- while self.Propagate():
- pass
-
-
-
class SimpleTiledModel(Model):
def __init__(self, width, height, name, subset_name, periodic_value, black_value):
@@ -505,97 +193,4 @@ def __init__(self, width, height, name, subset_name, periodic_value, black_value
#def getNextRandom():
# return random.random()
-def StuffRandom(source_array, random_value):
- a_sum = sum(source_array)
- if 0 == a_sum:
- for j in range(0, len(source_array)):
- source_array[j] = 1
- a_sum = sum(source_array)
- for j in range(0, len(source_array)):
- source_array[j] /= a_sum
- i = 0
- x = 0
- while (i < len(source_array)):
- x += source_array[i]
- if random_value <= x:
- return i
- i += 1
- return 0
-
-def StuffPower(a, n):
- product = 1
- for i in range(0, n):
- product *= a
- return product
-
-# TODO: finish StuffGet
-def StuffGet(xml_node, xml_attribute, default_t):
- s = ""
- if s == "":
- return default_t
- return s
-
-def string2bool(strn):
- if isinstance(strn, bool):
- return strn
- return strn.lower() in ["true"]
-
-class Program:
- def __init__(self):
- pass
-
- def Main(self):
- self.random = random.Random()
- xdoc = ET.ElementTree(file="samples.xml")
- counter = 1
- for xnode in xdoc.getroot():
- if("#comment" == xnode.tag):
- continue
- a_model = None
-
- name = xnode.get('name', "NAME")
- global hackstring
- hackstring = name
-
-
-
- print("< {0} ".format(name), end='')
- if "overlapping" == xnode.tag:
- #print(xnode.attrib)
- a_model = OverlappingModel(int(xnode.get('width', 48)), int(xnode.get('height', 48)), xnode.get('name', "NAME"), int(xnode.get('N', 2)), string2bool(xnode.get('periodicInput', True)), string2bool(xnode.get('periodic', False)), int(xnode.get('symmetry', 8)), int(xnode.get('ground',0)))
- pass
- elif "simpletiled" == xnode.tag:
- print("> ", end="\n")
- continue
- else:
- continue
-
-
-
- for i in range(0, int(xnode.get("screenshots", 2))):
- for k in range(0, 10):
- print("> ", end="")
- seed = self.random.random()
- finished = a_model.Run(seed, int(xnode.get("limit", 0)))
- if finished:
- print("DONE")
- a_model.Graphics().save("{0}_{1}_{2}_{3}.png".format(counter, name, i, uuid.uuid4()), format="PNG")
- break
- else:
- print("CONTRADICTION")
- counter += 1
-
-
-prog = Program()
-prog.Main()
-
-#a_model = OverlappingModel(8, 8, "Chess", 2, True, True, 8,0)
-#a_model = OverlappingModel(48, 48, "Hogs", 3, True, True, 8,0)
-#gseed = random.Random()
-#finished = a_model.Run(364, 0)
-#if(finished):
- #test_img = a_model.Graphics()
-#else:
-# print("CONTRADICTION")
-#test_img
\ No newline at end of file
diff --git a/overlapmodel.py b/overlapmodel.py
new file mode 100644
index 0000000..2374b3d
--- /dev/null
+++ b/overlapmodel.py
@@ -0,0 +1,432 @@
+# -*- coding: utf-8 -*-
+"""
+Created on Mon Mar 12 20:41:23 2018
+
+@author: Isaac
+"""
+
+import model
+import common
+
+import collections
+
+from sklearn import tree
+
+try:
+ import Image
+except ImportError:
+ from PIL import Image
+
+class OverlappingModel(model.Model):
+
+ def __init__(self, width, height, name, N_value = 2, periodic_input_value = True, periodic_output_value = False, symmetry_value = 8, ground_value = 0, ground_end = 0, additional_samples=[], additional_periodic="", antipatterns=""):
+ """
+ Initializes the model.
+ """
+ super( OverlappingModel, self).__init__(width, height)
+ self.propagator = [[[[]]]]
+ self.N = N_value
+ self.periodic = periodic_output_value
+ self.bitmaps = [Image.open("samples/{0}.png".format(name)).convert("RGBA")]
+ self.SMXs = [self.bitmaps[0].size[0]]
+ self.SMYs = [self.bitmaps[0].size[1]]
+ self.samples = [[[0 for _ in range(self.SMYs[0])] for _ in range(self.SMXs[0])]]
+
+ self.antipattern_flags = [int(x) for x in list(antipatterns.ljust(len(additional_samples) + 1, '0'))]
+ print(self.antipattern_flags)
+
+ add_periodic = 0
+ if periodic_input_value:
+ add_periodic = 1
+ self.periodic_flags = [add_periodic] + [int(x) for x in list(additional_periodic.ljust(len(additional_samples), str(add_periodic)))]
+ print(self.periodic_flags)
+
+ for additional in additional_samples:
+ self.bitmaps.append(Image.open("samples/{0}.png".format(additional)).convert("RGBA"))
+ add_index = len(self.bitmaps)-1
+ self.SMXs.append(self.bitmaps[add_index].size[0])
+ self.SMYs.append(self.bitmaps[add_index].size[1])
+ self.samples.append([[0 for _ in range(self.SMYs[add_index])] for _ in range(self.SMXs[add_index])])
+
+# self.antibitmaps = []
+# self.aSMXs = []
+# self.aSMYs = []
+# self.antisamples = []
+# for anti in antipatterns:
+# self.antibitmaps.append(Image.open("samples/{0}.png".format(anti)))
+# add_index = len(self.antibitmaps)-1
+# self.SMXs.append(self.antibitmaps[add_index].size[0])
+# self.SMYs.append(self.antibitmaps[add_index].size[1])
+# self.antisamples.append([[0 for _ in range(self.aSMYs[add_index])] for _ in range(self.aSMXs[add_index])])
+
+
+
+ self.colors = []
+ for samp_n in range(len(self.bitmaps)):
+ for y in range(0, self.SMYs[samp_n]):
+ for x in range(0, self.SMXs[samp_n]):
+ a_color = self.bitmaps[samp_n].getpixel((x, y))
+ color_exists = [c for c in self.colors if c == a_color]
+ if len(color_exists) < 1:
+ self.colors.append(a_color)
+ samp_result = [i for i,v in enumerate(self.colors) if v == a_color]
+ self.samples[samp_n][x][y] = samp_result
+
+ for c in self.colors:
+ print(c)
+
+ self.color_count = len(self.colors)
+ self.W = common.StuffPower(self.color_count, self.N * self.N)
+
+ # The pattern matrix, as an array of arrays.
+ self.patterns= [[]]
+ #self.ground = 0
+
+ # Additional samples can individually be marked as periodic/non-periodic
+ #periodic_input_values = [periodic_input_value]
+ #for _ in range(len(self.bitmaps)):
+ # periodic_input_values.append(periodic_input_value)
+ #for idx_peri, peri in enumerate(additional_periodic):
+ # periodic_input_values[idx_peri + 1] = ((1 == peri) or ('T' == peri) or ('True' == peri))
+
+
+ def FuncPattern(passed_func):
+ result = [0 for _ in range(self.N * self.N)]
+ for y in range(0, self.N):
+ for x in range(0, self.N):
+ result[x + (y * self.N)] = passed_func(x, y)
+ return result
+
+ pattern_func = FuncPattern
+
+ def PatternFromSample(x, y, n=0):
+ def innerPattern(dx, dy):
+ return self.samples[n][(x + dx) % self.SMXs[n]][(y + dy) % self.SMYs[n]]
+ return pattern_func(innerPattern)
+ def Rotate(p):
+ '''
+ Returns a rotated version of the pattern.
+ '''
+ return FuncPattern(lambda x, y: p[self.N - 1 - y + x * self.N])
+ def Reflect(p):
+ '''
+ Returns a reflected version of the pattern.
+ '''
+ return FuncPattern(lambda x, y: p[self.N - 1 - x + y * self.N])
+
+ def Index(p):
+ '''
+ Converts a color index into a powers-of-two representation for
+ bytewise storage.
+ '''
+ result = 0
+ power = 1
+ for i in range(0, len(p)):
+ result = result + (sum(p[len(p) - 1 - i]) * power)
+ power = power * self.color_count
+ return result
+
+
+
+ def PatternFromIndex(ind):
+ '''
+ Takes a pattern index and returns the pattern byte array.
+ '''
+ residue = ind
+ power = self.W
+ result = [None for _ in range(self.N * self.N)]
+ for i in range(0, len(result)):
+ power = power / self.color_count
+ count = 0
+ while residue >= power:
+ residue = residue - power
+ count = count + 1
+ result[i] = count
+ return result
+
+ self.weights = collections.Counter()
+ ordering = []
+ antiordering = []
+ self.anti_adjacency = []
+
+ for samp_n in range(len(self.bitmaps)):
+ ylimit = self.SMYs[samp_n] - self.N + 1
+ xlimit = self.SMXs[samp_n] - self.N + 1
+ if 1 == self.periodic_flags[samp_n]:
+ ylimit = self.SMYs[samp_n]
+ xlimit = self.SMXs[samp_n]
+ for y in range (0, ylimit):
+ for x in range(0, xlimit):
+ ps = [0 for _ in range(8)]
+ ps[0] = PatternFromSample(x,y,samp_n)
+ ps[1] = Reflect(ps[0])
+ ps[2] = Rotate(ps[0])
+ ps[3] = Reflect(ps[2])
+ ps[4] = Rotate(ps[2])
+ ps[5] = Reflect(ps[4])
+ ps[6] = Rotate(ps[4])
+ ps[7] = Reflect(ps[6])
+ for k in range(0,symmetry_value):
+ ind = Index(ps[k])
+ common.logger.info('pattern: ' + str(ps[k]) + ' index ' + str(ind))
+ if 1 == self.antipattern_flags[samp_n]:
+ if not ind in antiordering:
+ antiordering.append(ind)
+ indexed_weight = collections.Counter({ind : 1})
+ self.weights = self.weights + indexed_weight
+ if not ind in ordering:
+ ordering.append(ind)
+
+ for indo, o in enumerate(ordering):
+ print(indo, o, PatternFromIndex(o))
+ self.T = len(self.weights)
+ self.ground = (int((ground_value + self.T) % self.T), int((ground_value + self.T) % self.T))#(102,106)# int((ground_value + self.T) % self.T)
+ if ground_end > 0 and None != ground_end:
+ self.gound = (ground_value, ground_end)
+ print('self.ground',self.ground)
+
+ self.patterns = [[None] for _ in range(self.T)]
+ self.stationary = [None for _ in range(self.T)]
+ self.propagator = [[[[0]]] for _ in range(2 * self.N - 1)]
+
+ self.antipatterns = [[None] for _ in antiordering]
+
+ for w in antiordering:
+ self.antipatterns.append(PatternFromIndex(w))
+
+ counter = 0
+ for w in ordering:
+ self.patterns[counter] = PatternFromIndex(w)
+ self.stationary[counter] = self.weights[w]
+ counter += 1
+
+ for samp_n in range(len(self.bitmaps)):
+ if 1 == self.antipattern_flags[samp_n]:
+ #print('sample #',samp_n)
+ ylimit = self.SMYs[samp_n] - self.N + 1
+ xlimit = self.SMXs[samp_n] - self.N + 1
+ if 1 == self.periodic_flags[samp_n]:
+ ylimit = self.SMYs[samp_n]
+ xlimit = self.SMXs[samp_n]
+ #print('limits',xlimit, ylimit, self.periodic_flags[samp_n])
+ for py in range (0, ylimit):
+ for px in range(0, xlimit):
+ pattern_one = PatternFromIndex(Index(PatternFromSample(px,py,samp_n)))
+ print('pattern_one', pattern_one)
+ for tx in range(1 - self.N, self.N):
+ for ty in range(1 - self.N,self.N):
+ #print(tx,ty)
+ if not (tx == 0 and ty == 0):
+ if (1 == self.periodic_flags[samp_n]) or ((px + tx >= 0) and (py + ty >= 0) and (px + tx < xlimit) and (py + ty < ylimit)):
+ pattern_two = PatternFromIndex(Index(PatternFromSample(px+tx,py+ty,samp_n)))
+ #print('pattern_two', pattern_two, px + tx, py + ty, tx, ty)
+ self.anti_adjacency.append((pattern_one, pattern_two, (tx, ty)))
+ #print('create antipattern', (pattern_one, pattern_two, (tx, ty)))
+
+ for x in range(0, self.FMX):
+ for y in range(0, self.FMY):
+ self.wave[x][y] = [False for _ in range(self.T)]
+
+
+ def Disallowed(p1, p2, dx, dy):
+ #print(p1,p2,'\n---\n')
+ for anti_adj in self.anti_adjacency:
+ #print(anti_adj)
+ if (anti_adj[0] == p1 and anti_adj[1] == p2):
+ if dx == anti_adj[2][0] and dy == anti_adj[2][1]:
+ print('antipattern:',p1,p2,dx,dy,'\n',anti_adj,'\n')
+ return True
+ return False
+
+ def Agrees(p1, p2, dx, dy):
+ ifany = True
+ xmin = dx
+ xmax = self.N
+ if dx < 0:
+ xmin = 0
+ xmax = dx + self.N
+ ymin = dy
+ ymax = self.N
+ if dy < 0:
+ ymin = 0
+ ymax = dy + self.N
+ for y in range(ymin, ymax):
+ for x in range(xmin, xmax):
+ if p1[x + self.N * y] != p2[x - dx + self.N * (y - dy)]:
+ common.logger.debug(p1[x + self.N * y] != p2[x - dx + self.N * (y - dy)])
+ ifany = False
+ #return False
+ return ifany
+ #return True
+
+ for x in range(0, 2 * self.N - 1):
+ #print('x',x)
+ self.propagator[x] = [[[0]] for _ in range(2 * self.N - 1)]
+ for y in range(0, 2 * self.N - 1):
+ #print('y',y)
+ self.propagator[x][y] = [[0] for _ in range(self.T)]
+
+ for t in range(0, self.T):
+ #print('t',t)
+ a_list = []
+ #print('pattern',self.patterns[t])
+ for t2 in range(0, self.T):
+ #if not (((2 in self.patterns[t]) and (3 in self.patterns[t2])) or ((3 in self.patterns[t]) and (2 in self.patterns[t2]))):
+ if not Disallowed(self.patterns[t], self.patterns[t2], x - self.N + 1, y - self.N + 1):
+ if Agrees(self.patterns[t], self.patterns[t2], x - self.N + 1, y - self.N + 1):
+ a_list.append(t2)
+ self.propagator[x][y][t] = [0 for _ in range(len(a_list))]
+ for c in range(0, len(a_list)):
+ self.propagator[x][y][t][c] = a_list[c]
+
+ for x in self.propagator:
+ for y in x:
+ for t in y:
+ #print('-----')
+ for c in t:
+ #print(c)
+ pass
+ return
+
+ def OnBoundary(self, x, y):
+ return (not self.periodic) and ((x + self.N > self.FMX ) or (y + self.N > self.FMY))
+
+ def Propagate(self):
+ change = False
+ b = False
+
+ #x2 = None
+ #y2 = None
+ for x1 in range(0, self.FMX):
+ for y1 in range(0, self.FMY):
+ if (self.changes[x1][y1]):
+ self.changes[x1][y1] = False
+ dx = (0 - self.N) + 1
+ while dx < self.N:
+ #for dx in range(1 - self.N, self.N):
+ dy = (0 - self.N) + 1
+ while dy < self.N:
+ #for dy in range(1 - self.N, self.N):
+ x2 = x1 + dx
+ if x2 < 0:
+ x2 += self.FMX
+ elif x2 >= self.FMX:
+ x2 -= self.FMX
+ y2 = y1 + dy
+ if y2 < 0:
+ y2 += self.FMY
+ elif y2 >= self.FMY:
+ y2 -= self.FMY
+
+ if (not self.periodic) and (x2 + self.N > self.FMX or y2 + self.N > self.FMY):
+ pass
+ else:
+
+ w1 = self.wave[x1][y1]
+ w2 = self.wave[x2][y2]
+
+ p = self.propagator[(self.N - 1) - dx][(self.N - 1) - dy]
+
+ for t2 in range(0,self.T):
+ if (not w2[t2]):
+ pass
+ else:
+ b = False
+ prop = p[t2]
+ #print("Prop: {0}".format(prop))
+ i_one = 0
+ while (i_one < len(prop)) and (False == b):
+ b = w1[prop[i_one]]
+ i_one += 1
+ if False == b:
+ self.changes[x2][y2] = True
+ change = True
+ w2[t2] = False
+ dy += 1
+ dx += 1
+
+ return change
+
+ def Graphics(self, monochrome=False):
+ result = Image.new("RGB",(self.FMX, self.FMY),(0,0,0))
+ bitmap_data = list(result.getdata())
+ if(self.observed != None):
+ for y in range(0, self.FMY):
+ dy = self.N - 1
+ if (y < (self.FMY - self.N + 1)):
+ dy = 0
+ for x in range(0, self.FMX):
+ dx = 0
+ if (x < (self.FMX - self.N + 1)):
+ dx = self.N - 1
+ local_obsv = self.observed[x - dx][y - dy]
+ local_patt = self.patterns[local_obsv][dx + dy * self.N]
+ c = self.colors[local_patt]
+ #bitmap_data[x + y * self.FMX] = (0xff000000 | (c.R << 16) | (c.G << 8) | c.B)
+ if monochrome:
+ if isinstance(c, (int, float)):
+ bitmap_data[x + y * self.FMX] = (c, c, c)
+ else:
+ bitmap_data[x + y * self.FMX] = (c[0], c[1], c[2])
+ else:
+ bitmap_data[x + y * self.FMX] = (c[0], c[1], c[2])
+
+ else:
+ for y in range(0, self.FMY):
+ for x in range(0, self.FMX):
+ contributors = 0
+ r = 0
+ g = 0
+ b = 0
+ for dy in range(0, self.N):
+ for dx in range(0, self.N):
+ sx = x - dx
+ if sx < 0:
+ sx += self.FMX
+ sy = y - dy
+ if sy < 0:
+ sy += self.FMY
+ if (self.OnBoundary(sx, sy)):
+ pass
+ else:
+ for t in range(0, self.T):
+ if self.wave[sx][sy][t]:
+ contributors += 1
+ color = self.colors[self.patterns[t][dx + dy * self.N]]
+ if isinstance(color, (int, float)):
+ r = int(color)
+ g = int(color)
+ b = int(color)
+ else:
+ r += int(color[0])#.R
+ g += int(color[1])#.G
+ b += int(color[2])#.B
+ #bitmap_data[x + y * self.FMX] = (0xff000000 | ((r / contributors) << 16) | ((g / contributors) << 8) | (b / contributors))
+ if contributors > 0:
+ bitmap_data[x + y * self.FMX] = (int(r / contributors), int(g / contributors), int(b / contributors))
+ else:
+ common.logger.info("INFO: No contributors")
+ bitmap_data[x + y * self.FMX] = (int(r), int(g), int(b))
+ result.putdata(bitmap_data)
+ return result
+
+ def Clear(self):
+ super(OverlappingModel, self).Clear()
+ if(self.ground != (0,0) ):
+
+ for x in range(0, self.FMX):
+ for t in range(0, self.T):
+ #print('clear?',x,t,(t != self.ground),self.wave[x][self.FMY - 1][t],self.changes[x][self.FMY - 1], self.FMY - 1)
+ if not (t in self.ground):
+ self.wave[x][self.FMY - 1][t] = False
+ self.changes[x][self.FMY - 1] = True
+
+ for y in range(0, self.FMY - 1):
+ for g in range(self.ground[0], self.ground[1]):
+ self.wave[x][y][g] = False
+ self.changes[x][y] = True
+ while self.Propagate():
+ pass
+
+
+
diff --git a/program.py b/program.py
new file mode 100644
index 0000000..94af0c3
--- /dev/null
+++ b/program.py
@@ -0,0 +1,95 @@
+# -*- coding: utf-8 -*-
+"""
+Created on Mon Mar 12 20:45:58 2018
+
+@author: Isaac
+"""
+
+import random
+import xml.etree.ElementTree as ET
+import uuid
+
+import common
+import model
+import overlapmodel
+import learnmodel
+
+
+class Program:
+ def __init__(self):
+ pass
+
+ def Main(self):
+ self.random = random.Random()
+ xdoc = ET.ElementTree(file="learning.xml")
+ counter = 1
+ for xnode in xdoc.getroot():
+ if("#comment" == xnode.tag):
+ continue
+ a_model = None
+
+ name = xnode.get('name', "NAME")
+ global hackstring
+ hackstring = name
+
+
+
+ print("< {0} ".format(name), end='')
+ if "learning" == xnode.tag:
+ #print(xnode.attrib)
+ add_samp_string = xnode.get('additional', "NONE")
+
+ add_samp = []
+ if "NONE" != add_samp_string:
+ add_samp = add_samp_string.split(':')
+
+ add_peri = xnode.get('additional_periodic', "")
+
+ a_model = learnmodel.LearningModel(int(xnode.get('width', 48)), int(xnode.get('height', 48)), xnode.get('name', "NAME"), int(xnode.get('N', 2)), common.string2bool(xnode.get('periodicInput', True)), common.string2bool(xnode.get('periodic', False)), int(xnode.get('symmetry', 8)), int(xnode.get('ground',0)), int(xnode.get('ground_end',0)), additional_samples=add_samp, additional_periodic=add_peri, antipatterns=xnode.get('antipatterns', '0'))
+ pass
+ elif "overlapping" == xnode.tag:
+ #print(xnode.attrib)
+ add_samp_string = xnode.get('additional', "NONE")
+
+ add_samp = []
+ if "NONE" != add_samp_string:
+ add_samp = add_samp_string.split(':')
+
+ add_peri = xnode.get('additional_periodic', "")
+
+ a_model = overlapmodel.OverlappingModel(int(xnode.get('width', 48)), int(xnode.get('height', 48)), xnode.get('name', "NAME"), int(xnode.get('N', 2)), common.string2bool(xnode.get('periodicInput', True)), common.string2bool(xnode.get('periodic', False)), int(xnode.get('symmetry', 8)), int(xnode.get('ground',0)), int(xnode.get('ground_end',0)), additional_samples=add_samp, additional_periodic=add_peri, antipatterns=xnode.get('antipatterns', '0'))
+ pass
+ elif "simpletiled" == xnode.tag:
+ print("> ", end="\n")
+ continue
+ else:
+ continue
+
+
+
+ for i in range(0, int(xnode.get("screenshots", 2))):
+ for k in range(0, 10):
+ print("> ", end="")
+ seed = self.random.random()
+ finished = a_model.Run(seed, int(xnode.get("limit", 0)))
+ if finished:
+ print("DONE")
+ a_model.Graphics().save("{0}_{1}_{2}_{3}.png".format(counter, name, i, uuid.uuid4()), format="PNG")
+ break
+ else:
+ print("CONTRADICTION")
+ counter += 1
+
+
+prog = Program()
+prog.Main()
+
+#a_model = OverlappingModel(8, 8, "Chess", 2, True, True, 8,0)
+#a_model = OverlappingModel(48, 48, "Hogs", 3, True, True, 8,0)
+#gseed = random.Random()
+#finished = a_model.Run(364, 0)
+#if(finished):
+ #test_img = a_model.Graphics()
+#else:
+# print("CONTRADICTION")
+#test_img
diff --git a/samples.xml b/samples.xml
index c280657..b967c0d 100644
--- a/samples.xml
+++ b/samples.xml
@@ -1,77 +1,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
diff --git a/samples/Yellow Maze.png b/samples/Yellow Maze.png
new file mode 100644
index 0000000..f7e4799
Binary files /dev/null and b/samples/Yellow Maze.png differ
diff --git a/samples/anti_flower_ground.png b/samples/anti_flower_ground.png
new file mode 100644
index 0000000..335e538
Binary files /dev/null and b/samples/anti_flower_ground.png differ
diff --git a/samples/blue_flowers.png b/samples/blue_flowers.png
new file mode 100644
index 0000000..3371495
Binary files /dev/null and b/samples/blue_flowers.png differ
diff --git a/samples/blue_flowers2.png b/samples/blue_flowers2.png
new file mode 100644
index 0000000..0b02dfd
Binary files /dev/null and b/samples/blue_flowers2.png differ
diff --git a/samples/blue_flowers3.png b/samples/blue_flowers3.png
new file mode 100644
index 0000000..5d17408
Binary files /dev/null and b/samples/blue_flowers3.png differ
diff --git a/samples/blue_flowers4.png b/samples/blue_flowers4.png
new file mode 100644
index 0000000..a3ff563
Binary files /dev/null and b/samples/blue_flowers4.png differ
diff --git a/samples/blue_flowers5.png b/samples/blue_flowers5.png
new file mode 100644
index 0000000..fb42aa7
Binary files /dev/null and b/samples/blue_flowers5.png differ
diff --git a/samples/blue_flowers6.png b/samples/blue_flowers6.png
new file mode 100644
index 0000000..e2cf067
Binary files /dev/null and b/samples/blue_flowers6.png differ
diff --git a/samples/blue_flowers8.psd b/samples/blue_flowers8.psd
new file mode 100644
index 0000000..7dc836d
Binary files /dev/null and b/samples/blue_flowers8.psd differ
diff --git a/samples/blue_flowers8_anti1.png b/samples/blue_flowers8_anti1.png
new file mode 100644
index 0000000..f8101ad
Binary files /dev/null and b/samples/blue_flowers8_anti1.png differ
diff --git a/samples/blue_flowers8_anti2.png b/samples/blue_flowers8_anti2.png
new file mode 100644
index 0000000..b5af3a8
Binary files /dev/null and b/samples/blue_flowers8_anti2.png differ
diff --git a/samples/blue_flowers9.png b/samples/blue_flowers9.png
new file mode 100644
index 0000000..4ca2d7e
Binary files /dev/null and b/samples/blue_flowers9.png differ
diff --git a/samples/blue_flowers9_anti1.png b/samples/blue_flowers9_anti1.png
new file mode 100644
index 0000000..51acbbb
Binary files /dev/null and b/samples/blue_flowers9_anti1.png differ
diff --git a/samples/red_flowers.png b/samples/red_flowers.png
new file mode 100644
index 0000000..a3ead9f
Binary files /dev/null and b/samples/red_flowers.png differ
diff --git a/samples/test_antipattern.png b/samples/test_antipattern.png
new file mode 100644
index 0000000..4bf1c61
Binary files /dev/null and b/samples/test_antipattern.png differ
diff --git a/samples/test_antipattern10.png b/samples/test_antipattern10.png
new file mode 100644
index 0000000..5d830ab
Binary files /dev/null and b/samples/test_antipattern10.png differ
diff --git a/samples/test_antipattern2.png b/samples/test_antipattern2.png
new file mode 100644
index 0000000..bcec0dc
Binary files /dev/null and b/samples/test_antipattern2.png differ
diff --git a/samples/test_antipattern3.png b/samples/test_antipattern3.png
new file mode 100644
index 0000000..264e43d
Binary files /dev/null and b/samples/test_antipattern3.png differ
diff --git a/samples/test_antipattern4.png b/samples/test_antipattern4.png
new file mode 100644
index 0000000..1541aa4
Binary files /dev/null and b/samples/test_antipattern4.png differ
diff --git a/samples/test_antipattern5.png b/samples/test_antipattern5.png
new file mode 100644
index 0000000..8d5ad1c
Binary files /dev/null and b/samples/test_antipattern5.png differ
diff --git a/samples/test_antipattern6.png b/samples/test_antipattern6.png
new file mode 100644
index 0000000..41cddc9
Binary files /dev/null and b/samples/test_antipattern6.png differ
diff --git a/samples/test_antipattern7.png b/samples/test_antipattern7.png
new file mode 100644
index 0000000..735b666
Binary files /dev/null and b/samples/test_antipattern7.png differ
diff --git a/samples/test_antipattern8.png b/samples/test_antipattern8.png
new file mode 100644
index 0000000..3656bbd
Binary files /dev/null and b/samples/test_antipattern8.png differ
diff --git a/samples/test_antipattern9.png b/samples/test_antipattern9.png
new file mode 100644
index 0000000..ddfaca3
Binary files /dev/null and b/samples/test_antipattern9.png differ
diff --git a/samples1.xml b/samples1.xml
new file mode 100644
index 0000000..5409f8d
--- /dev/null
+++ b/samples1.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/wfc.yml b/wfc.yml
new file mode 100644
index 0000000..ced8c18
--- /dev/null
+++ b/wfc.yml
@@ -0,0 +1,117 @@
+name: wfc
+channels:
+- anaconda-fusion
+- defaults
+dependencies:
+- alabaster=0.7.10=py36hcd07829_0
+- asn1crypto=0.24.0=py36_0
+- astroid=1.6.0=py36_0
+- babel=2.5.3=py36_0
+- bleach=2.1.2=py36_0
+- ca-certificates=2017.08.26=h94faf87_0
+- certifi=2018.1.18=py36_0
+- cffi=1.11.4=py36hfa6e2cd_0
+- chardet=3.0.4=py36h420ce6e_1
+- cloudpickle=0.5.2=py36h6b1d831_0
+- colorama=0.3.9=py36h029ae33_0
+- cryptography=2.1.4=py36he1d7878_0
+- decorator=4.2.1=py36_0
+- docutils=0.14=py36h6012d8f_0
+- entrypoints=0.2.3=py36hfd66bb0_2
+- freetype=2.8=h51f8f2c_1
+- html5lib=1.0.1=py36h047fa9f_0
+- icc_rt=2017.0.4=h97af966_0
+- icu=58.2=ha66f8fd_1
+- idna=2.6=py36h148d497_1
+- imagesize=0.7.1=py36he29f638_0
+- intel-openmp=2018.0.0=hd92c6cd_8
+- ipykernel=4.8.0=py36_0
+- ipython=6.2.1=py36h9cf0123_1
+- ipython_genutils=0.2.0=py36h3c5d0ee_0
+- isort=4.2.15=py36h6198cc5_0
+- jedi=0.11.1=py36_0
+- jinja2=2.10=py36h292fed1_0
+- jpeg=9b=hb83a4c4_2
+- jsonschema=2.6.0=py36h7636477_0
+- jupyter_client=5.2.2=py36_0
+- jupyter_core=4.4.0=py36h56e9d50_0
+- lazy-object-proxy=1.3.1=py36hd1c21d2_0
+- libpng=1.6.34=h79bbb47_0
+- libtiff=4.0.9=h0f13578_0
+- markupsafe=1.0=py36h0e26971_1
+- mccabe=0.6.1=py36hb41005a_1
+- mistune=0.8.3=py36_0
+- mkl=2018.0.1=h2108138_4
+- nbconvert=5.3.1=py36h8dc0fde_0
+- nbformat=4.4.0=py36h3a5bc1b_0
+- numpy=1.14.1=py36hb69e940_2
+- numpydoc=0.7.0=py36ha25429e_0
+- olefile=0.44=py36h0a7bdd2_0
+- openssl=1.0.2n=h74b6da3_0
+- pandoc=1.19.2.1=hb2460c7_1
+- pandocfilters=1.4.2=py36h3ef6317_1
+- parso=0.1.1=py36hae3edee_0
+- pickleshare=0.7.4=py36h9de030f_0
+- pillow=5.0.0=py36h0738816_0
+- pip=9.0.1=py36h226ae91_4
+- prompt_toolkit=1.0.15=py36h60b8f86_0
+- psutil=5.4.3=py36hfa6e2cd_0
+- pycodestyle=2.3.1=py36h7cc55cd_0
+- pycparser=2.18=py36hd053e01_1
+- pyflakes=1.6.0=py36h0b975d6_0
+- pygments=2.2.0=py36hb010967_0
+- pylint=1.8.1=py36_0
+- pyopenssl=17.5.0=py36h5b7d817_0
+- pyqt=5.6.0=py36hb5ed885_5
+- pysocks=1.6.7=py36h698d350_1
+- python=3.6.4=h6538335_1
+- python-dateutil=2.6.1=py36h509ddcb_1
+- pytz=2017.3=py36h1d3fa6b_0
+- pyzmq=16.0.3=py36he714bf5_0
+- qt=5.6.2=vc14h6f8c307_12
+- qtawesome=0.4.4=py36h5aa48f6_0
+- qtconsole=4.3.1=py36h99a29a9_0
+- qtpy=1.3.1=py36hb8717c5_0
+- requests=2.18.4=py36h4371aae_1
+- rope=0.10.7=py36had63a69_0
+- scikit-learn=0.19.1=py36h53aea1b_0
+- scipy=1.0.0=py36h1260518_0
+- setuptools=38.4.0=py36_0
+- simplegeneric=0.8.1=py36heab741f_0
+- sip=4.18.1=py36h9c25514_2
+- six=1.11.0=py36h4db2310_1
+- snowballstemmer=1.2.1=py36h763602f_0
+- sphinx=1.6.6=py36_0
+- sphinxcontrib=1.0=py36hbbac3d2_1
+- sphinxcontrib-websupport=1.0.1=py36hb5e5916_1
+- spyder=3.2.6=py36_0
+- sqlite=3.21.0=h9d3ae62_2
+- testpath=0.3.1=py36h2698cfe_0
+- tk=8.6.7=hcb92d03_3
+- tornado=4.5.3=py36_0
+- traitlets=4.3.2=py36h096827d_0
+- typing=3.6.2=py36hb035bda_0
+- urllib3=1.22=py36h276f60a_0
+- vc=14=h0510ff6_3
+- vs2015_runtime=14.0.25123=3
+- wcwidth=0.1.7=py36h3d5aa90_0
+- webencodings=0.5.1=py36h67c50ae_1
+- wheel=0.30.0=py36h6c3ec14_1
+- win_inet_pton=1.0.1=py36he67d7fd_1
+- wincertstore=0.2=py36h7fe50ca_0
+- wrapt=1.10.11=py36he5f5981_0
+- zlib=1.2.11=h8395fce_2
+- pip:
+ - appdirs==1.4.3
+ - exifread==2.1.2
+ - imagehash==4.0
+ - ipython-genutils==0.2.0
+ - jupyter-client==5.2.2
+ - jupyter-core==4.4.0
+ - prompt-toolkit==1.0.15
+ - pymzn==0.16.5
+ - pywavelets==0.5.2
+ - pyyaml==3.12
+ - win-inet-pton==1.0.1
+prefix: C:\Software\Anaconda3\envs\wfc
+