Browse Source

Add a score to evaluate the use of variable in direction calculation

Yann Weber 6 years ago
parent
commit
6f004245f3
3 changed files with 82 additions and 48 deletions
  1. 15
    3
      gte/rpnlib.py
  2. 57
    42
      gte/turmit.py
  3. 10
    3
      gte/world.py

+ 15
- 3
gte/rpnlib.py View File

24
 _var_list['g'] = 0
24
 _var_list['g'] = 0
25
 _var_list['b'] = 0
25
 _var_list['b'] = 0
26
 
26
 
27
-def RpnOp(method):
27
+def RpnOpNoMod(method):
28
+    return RpnOp(method, True)
29
+
30
+def RpnOp(method, nomod = False):
28
     ''' @brief Decorator for RPN operation that autodetect argument count
31
     ''' @brief Decorator for RPN operation that autodetect argument count
29
         
32
         
30
         Autodetect argument count and pop them from the stack. Then attempt
33
         Autodetect argument count and pop them from the stack. Then attempt
36
     narg = len(inspect.signature(method).parameters)-1
39
     narg = len(inspect.signature(method).parameters)-1
37
     def wrapped(self):
40
     def wrapped(self):
38
         args = [ self._pop() for _ in range(narg) ]
41
         args = [ self._pop() for _ in range(narg) ]
42
+        determinist = True
43
+        if not nomod:
44
+            for arg in args:
45
+                if isinstance(arg, IntVar):
46
+                    determinist = False
47
+                    break
39
         args.reverse()
48
         args.reverse()
40
         try:
49
         try:
41
             res = method(self, *args)
50
             res = method(self, *args)
42
         except ZeroDivisionError:
51
         except ZeroDivisionError:
43
             res = None
52
             res = None
44
         if res is None:
53
         if res is None:
45
-            return None
54
+            return determinist
46
         try:
55
         try:
47
             for topush in res:
56
             for topush in res:
48
                 if not isinstance(topush, int):
57
                 if not isinstance(topush, int):
55
                 raise ValueError('Turmit.%s() returned a list containing a\
64
                 raise ValueError('Turmit.%s() returned a list containing a\
56
 %s : %s' % (method.__name__, type(res), res))
65
 %s : %s' % (method.__name__, type(res), res))
57
             self._push(res)
66
             self._push(res)
58
-        return res
67
+        return determinist
59
     _op_list[method.__name__] = (method, wrapped)
68
     _op_list[method.__name__] = (method, wrapped)
60
     return wrapped
69
     return wrapped
61
 
70
 
219
         ''' @return Random value '''
228
         ''' @return Random value '''
220
         return cls.random(cls.VALUE)
229
         return cls.random(cls.VALUE)
221
 
230
 
231
+
232
+class IntVar(int):
233
+    pass

+ 57
- 42
gte/turmit.py View File

74
         if self._prog is None:
74
         if self._prog is None:
75
             self._prog = RpnExpr.random(self._prog_sz)
75
             self._prog = RpnExpr.random(self._prog_sz)
76
 
76
 
77
-        self.__expr_fun = lambda *args, **kwargs: (0,)
77
+        self._determin_score = 5
78
+
79
+        self.__expr_fun = lambda *args, **kwargs: (0, True, None)
78
 
80
 
79
     def __call__(self, **context):
81
     def __call__(self, **context):
80
         ''' @brief Exec the RPN expression and return the stack head
82
         ''' @brief Exec the RPN expression and return the stack head
81
             @param context dict : dict with variable values (see @ref rpnlib._var_list)
83
             @param context dict : dict with variable values (see @ref rpnlib._var_list)
82
             @return stack head after RPN
84
             @return stack head after RPN
83
         '''
85
         '''
84
-        context = {k:int(context[k]) % self._max_int for k in context}
86
+        context = {k:IntVar(context[k]) % self._max_int for k in context}
85
 
87
 
86
         if self.__expr_fun is None:
88
         if self.__expr_fun is None:
87
             self._compile()
89
             self._compile()
88
         ret = self.__expr_fun(self, **context)
90
         ret = self.__expr_fun(self, **context)
89
-        if isinstance(ret, int):
91
+
92
+        determinist = ret[1]
93
+
94
+        if len(ret) == 2:
95
+            ret = ret[0]
90
             return ret
96
             return ret
97
+        #if len(ret) == 3 -> returned a continuation address in RPN expr
91
 
98
 
92
         #self.__ip = 0
99
         #self.__ip = 0
93
         self.__ip = ret[0]
100
         self.__ip = ret[0]
97
             if sym.optype == RpnSymbol.VALUE:
104
             if sym.optype == RpnSymbol.VALUE:
98
                 self._push(sym.value)
105
                 self._push(sym.value)
99
             elif sym.optype == RpnSymbol.VARIABLE:
106
             elif sym.optype == RpnSymbol.VARIABLE:
100
-                self._push(context[sym.value.lower()])
107
+                self._push(IntVar(context[sym.value.lower()]))
101
             elif sym.optype == RpnSymbol.OPERATION:
108
             elif sym.optype == RpnSymbol.OPERATION:
102
-                getattr(self, sym.value.lower())()
109
+                op = getattr(self, sym.value.lower())
110
+                if determinist:
111
+                    if not op():
112
+                        determinist = False
113
+                else:
114
+                    op()
103
             self.__ip += 1
115
             self.__ip += 1
116
+
117
+        self._determin_score += 0 if determinist else 1
104
         return self.shead
118
         return self.shead
105
 
119
 
106
     def _compile(self):
120
     def _compile(self):
107
-        code = 'def expr_fun(self, x, y, r, g, b):\n'
121
+        code = '''def expr_fun(self, x, y, r, g, b):
122
+
123
+    determinist = True'''
124
+
125
+        op2_head = '''a = self._stack[self._cur]
126
+    self._cur = (self._cur - 1) if self._cur > 0 else (len(self._stack) - 1)
127
+    if isinstance(a, IntVar) or isinstance(self._stack[self._cur], IntVar):
128
+        determinist = False
129
+'''
108
         for ip, sym in enumerate(self._prog):
130
         for ip, sym in enumerate(self._prog):
109
             if sym.optype == RpnSymbol.VALUE:
131
             if sym.optype == RpnSymbol.VALUE:
110
                 code += '''
132
                 code += '''
120
 ''' % sym.value.lower()
142
 ''' % sym.value.lower()
121
             elif sym.value == 'add':
143
             elif sym.value == 'add':
122
                 code += '''
144
                 code += '''
123
-    a = self._stack[self._cur]
124
-    self._cur = (self._cur - 1) if self._cur > 0 else (len(self._stack) - 1)
145
+    %s
125
     self._stack[self._cur] += a
146
     self._stack[self._cur] += a
126
     self._stack[self._cur] %= self._max_int
147
     self._stack[self._cur] %= self._max_int
127
-'''
148
+''' % op2_head
128
             elif sym.value == 'sub':
149
             elif sym.value == 'sub':
129
                 code += '''
150
                 code += '''
130
-    a = self._stack[self._cur]
131
-    self._cur = (self._cur - 1) if self._cur > 0 else (len(self._stack) - 1)
151
+    %s
132
     self._stack[self._cur] = self._stack[self._cur] - a
152
     self._stack[self._cur] = self._stack[self._cur] - a
133
     if self._stack[self._cur] < 0:
153
     if self._stack[self._cur] < 0:
134
         self._stack[self._cur] += self._max_int
154
         self._stack[self._cur] += self._max_int
135
-'''
155
+''' % op2_head
136
             elif sym.value == 'mul':
156
             elif sym.value == 'mul':
137
                 code += '''
157
                 code += '''
138
-    a = self._stack[self._cur]
139
-    self._cur = (self._cur - 1) if self._cur > 0 else (len(self._stack) - 1)
158
+    %s
140
     self._stack[self._cur] *= a
159
     self._stack[self._cur] *= a
141
     self._stack[self._cur] %= self._max_int
160
     self._stack[self._cur] %= self._max_int
142
-'''
161
+''' % op2_head
143
             elif sym.value == 'div':
162
             elif sym.value == 'div':
144
                 code += '''
163
                 code += '''
145
-    a = self._stack[self._cur]
146
-    self._cur = (self._cur - 1) if self._cur > 0 else (len(self._stack) - 1)
164
+    %s
147
     if a != 0:
165
     if a != 0:
148
         self._stack[self._cur] = self._stack[self._cur] // a
166
         self._stack[self._cur] = self._stack[self._cur] // a
149
-'''
167
+''' % op2_head
150
             elif sym.value == 'mod':
168
             elif sym.value == 'mod':
151
                 code += '''
169
                 code += '''
152
-    a = self._stack[self._cur]
153
-    self._cur = (self._cur - 1) if self._cur > 0 else (len(self._stack) - 1)
170
+    %s
154
     if a != 0:
171
     if a != 0:
155
         self._stack[self._cur] = self._stack[self._cur] % a
172
         self._stack[self._cur] = self._stack[self._cur] % a
156
-'''
173
+''' % op2_head
157
             elif sym.value == 'bin_and':
174
             elif sym.value == 'bin_and':
158
                 code += '''
175
                 code += '''
159
-    a = self._stack[self._cur]
160
-    self._cur = (self._cur - 1) if self._cur > 0 else (len(self._stack) - 1)
176
+    %s
161
     self._stack[self._cur] &= a
177
     self._stack[self._cur] &= a
162
-'''
178
+''' % op2_head
163
             elif sym.value == 'bin_or':
179
             elif sym.value == 'bin_or':
164
                 code += '''
180
                 code += '''
165
-    a = self._stack[self._cur]
166
-    self._cur = (self._cur - 1) if self._cur > 0 else (len(self._stack) - 1)
181
+    %s
167
     self._stack[self._cur] |= a
182
     self._stack[self._cur] |= a
168
-'''
183
+''' % op2_head
169
             elif sym.value == 'bin_xor':
184
             elif sym.value == 'bin_xor':
170
                 code += '''
185
                 code += '''
171
-    a = self._stack[self._cur]
172
-    self._cur = (self._cur - 1) if self._cur > 0 else (len(self._stack) - 1)
186
+    %s
173
     self._stack[self._cur] ^= a
187
     self._stack[self._cur] ^= a
174
-'''
188
+''' % op2_head
175
             elif sym.value == 'lshift':
189
             elif sym.value == 'lshift':
176
                 code += '''
190
                 code += '''
177
-    a = self._stack[self._cur]
178
-    self._cur = (self._cur - 1) if self._cur > 0 else (len(self._stack) - 1)
191
+    %s
179
     self._stack[self._cur] = (self._stack[self._cur] << a) % self._max_int
192
     self._stack[self._cur] = (self._stack[self._cur] << a) % self._max_int
180
-'''
193
+''' % op2_head
181
             elif sym.value == 'rshift':
194
             elif sym.value == 'rshift':
182
                 code += '''
195
                 code += '''
183
-    a = self._stack[self._cur]
184
-    self._cur = (self._cur - 1) if self._cur > 0 else (len(self._stack) - 1)
196
+    %s
185
     self._stack[self._cur] = self._stack[self._cur] >> a
197
     self._stack[self._cur] = self._stack[self._cur] >> a
186
-'''
198
+''' % op2_head
187
             elif sym.value == 'dup':
199
             elif sym.value == 'dup':
188
                 code += '''
200
                 code += '''
189
     a = self._stack[self._cur]
201
     a = self._stack[self._cur]
202
+    if isinstance(a, IntVar):
203
+        determinist = False
190
     self._cur += 1
204
     self._cur += 1
191
     self._cur %= len(self._stack)
205
     self._cur %= len(self._stack)
192
     self._stack[self._cur] = a
206
     self._stack[self._cur] = a
197
 '''
211
 '''
198
             else:
212
             else:
199
                 code += '''
213
                 code += '''
200
-    return (%d,)
214
+    return (%d,determinist, None)
201
 ''' % ip
215
 ''' % ip
202
         code += '''
216
         code += '''
203
-    return self._stack[self._cur]
217
+    return (self._stack[self._cur], determinist)
204
 '''
218
 '''
205
         g = {}
219
         g = {}
206
         l = {}
220
         l = {}
245
             @param val int : integer to transform
259
             @param val int : integer to transform
246
             @return integer
260
             @return integer
247
         '''
261
         '''
262
+        intvar = isinstance(val, IntVar)
248
         val = int(val)
263
         val = int(val)
249
         if self._max_int is not None:
264
         if self._max_int is not None:
250
             val %= self._max_int
265
             val %= self._max_int
251
             if not self._signed_int and val < 0:
266
             if not self._signed_int and val < 0:
252
                 val = self._max_int - val
267
                 val = self._max_int - val
253
-        return val
268
+        return IntVar(val) if intvar else val
254
 
269
 
255
     @RpnOp
270
     @RpnOp
256
     def mem_sz(self, new_sz):
271
     def mem_sz(self, new_sz):
295
         '''
310
         '''
296
         return a & b
311
         return a & b
297
 
312
 
298
-    @RpnOp
313
+    @RpnOpNoMod
299
     def dup(self, a):
314
     def dup(self, a):
300
         ''' @brief Duplicates stack head
315
         ''' @brief Duplicates stack head
301
             @param a int : value
316
             @param a int : value
359
         '''
374
         '''
360
         return a ^ b
375
         return a ^ b
361
 
376
 
362
-    @RpnOp
377
+    @RpnOpNoMod
363
     def pop(self, a):
378
     def pop(self, a):
364
         ''' @brief Pops a, head of the stack
379
         ''' @brief Pops a, head of the stack
365
             @param a int : value
380
             @param a int : value
366
         '''
381
         '''
367
         pass
382
         pass
368
 
383
 
369
-    @RpnOp
384
+    @RpnOpNoMod
370
     def swp(self, a, b):
385
     def swp(self, a, b):
371
         ''' @brief Swap the two values on top of the stack
386
         ''' @brief Swap the two values on top of the stack
372
             @param a int : v1
387
             @param a int : v1

+ 10
- 3
gte/world.py View File

39
     stop = time.time()
39
     stop = time.time()
40
 
40
 
41
     score_dir = sum([t.dirvar() for t in turmits]) / len(turmits)
41
     score_dir = sum([t.dirvar() for t in turmits]) / len(turmits)
42
+    score_deter = sum([t.determinist() for t in turmits]) / len(turmits)
42
     score_fract = w.fractdim()
43
     score_fract = w.fractdim()
43
-    score = score_dir * score_fract
44
+    score = (score_dir * score_fract) * (score_deter * 0.2 + 0.8)
44
     sinfo = {'F':score_fract, 'D':score_dir}
45
     sinfo = {'F':score_fract, 'D':score_dir}
45
     #score = sum([score_fract] + [score_dir] * 4) / 5
46
     #score = sum([score_fract] + [score_dir] * 4) / 5
46
     if not args.quiet:
47
     if not args.quiet:
47
         tall = time.time() - startall
48
         tall = time.time() - startall
48
-        msg = 'G%d P%d R%d: %d steps scores %.3f:(D:%.3f,F:%.3f) in %.3fs (%dus per step)\t%s'
49
+        msg = 'G%d P%d R%d: %d steps scores %.3f:(D:%.3f,F:%.3f,Dtr:%.3f) in %.3fs (%dus per step)\t%s'
49
         msg %= (generation, progid, trynum, steps, score, score_dir,
50
         msg %= (generation, progid, trynum, steps, score, score_dir,
50
-                score_fract, tall,
51
+                score_fract, score_deter, tall,
51
                 ((stop - start)*1000000)//steps//len(turmits),
52
                 ((stop - start)*1000000)//steps//len(turmits),
52
                 str(prog))
53
                 str(prog))
53
         logger.info(msg)
54
         logger.info(msg)
243
         self._dirvar_cnt -= 1
244
         self._dirvar_cnt -= 1
244
         self._steps += 1
245
         self._steps += 1
245
 
246
 
247
+    def determinist(self):
248
+        ''' @brief Process a determinit score : determinist_expr / total expr
249
+            @return float in [0.0..1.0]
250
+        '''
251
+        return (self._determin_score + 1) / self._steps
252
+
246
     def dirvar(self):
253
     def dirvar(self):
247
         ''' @brief Process @ref _dirvar to return a direction variation
254
         ''' @brief Process @ref _dirvar to return a direction variation
248
             score
255
             score

Loading…
Cancel
Save