Compare commits

...

6 commits

7 changed files with 98 additions and 21 deletions

View file

@ -17,3 +17,38 @@ python3 -m gte generate -o /tmp/gte.png -T 15 --steps 20000 -P ' 0x008E 0x000F B
python3 -m gte generate -o /tmp/gte.png -T 5 --steps 40000 -P '+ 0x008E 0x000B B JCMP'
python3 -m gte generate -o /tmp/gte.png -T 15 --steps 15000 -P 'B 0xEECD Y G << X ^ |'
python3 -m gte generate -o /tmp/gte.png -T 15 --steps 10000 -P 'B - |'
python3 -m gte generate -o /tmp/gte.png -T 15 --steps 10000 -P 'B - * |'
python3 -m gte generate -o /tmp/gte.png -T 5 --steps 30000 -P 'B - * |'
python3 -m gte generate -o /tmp/gte.png -T 25 --steps 5000 -P 'B - R - |'
python3 -m gte generate -o /tmp/gte.png -T 10 --steps 8000 -P 'B ^'
python3 -m gte generate -o /tmp/gte.png -T 10 --steps 8000 -P 'B JCMP JZ ^'
python3 -m gte generate -o /tmp/gte.png -T 10 --steps 10000 -P 'B << ^'
python3 -m gte generate -o /tmp/gte.png -T 25 --steps 5000 -P 'R MOD POP'
python3 -m gte generate -o /tmp/gte.png -T 25 --steps 5000 -P 'G | +'
python3 -m gte generate -o /tmp/gte.png -T 15 --steps 6000 -P 'r g b + + + |'
python3 -m gte generate -o /tmp/gte.png -T 15 --steps 6000 -P 'X + |'
python3 -m gte generate -o /tmp/gte.png -T 15 --steps 10000 -P '0x982A - 0xAE9D R & +'
python3 -m gte generate -o /tmp/gte.png -T 15 --steps 10000 -P '0x982A POP 0x4 R & +'
python3 -m gte generate -o /tmp/gte.png -T 15 --steps 6000 -P 'X G & 0xF8 ^ ^'
WOOT WOOT
python3 -m gte generate -o /tmp/gte.png -T 5 --steps 15000 -P '0xD | B | ^'
python3 -m gte generate -o /tmp/gte.png -T 5 --steps 15000 -P 'B | G | ^'
python3 -m gte generate -o /tmp/gte.png -T 5 --steps 15000 -P 'B | G - ^'
python3 -m gte generate -o /tmp/gte.png -T 5 --steps 15000 -P '0xDB4B | R | ^'
python3 -m gte generate -o /tmp/gte.png -T 5 --steps 15000 -P '0xD | R MEM_SZ ^'
WOOT 2
python3 -m gte generate -o /tmp/gte.png -T 35 --steps 5000 -P 'B 0xEECD Y G << X ^ |'

View file

@ -46,6 +46,10 @@ parser_evolve.add_argument('--pool-div', '-D', type=int, metavar='N',
default=2,
help='Each generation keep 1/N of the pool')
parser_evolve.add_argument('--max', '-m', action='store_const',
default=False, const=True,
help="Keep maximum score instead of average")
parser_evolve.add_argument('--prog-size', type=int, metavar='SIZE',
default=5)
@ -72,6 +76,12 @@ parser_evolve.add_argument('--mod-steps', '-M', action='store_const',
parser_evolve.add_argument('--quiet', '-q', action='store_const',
default=False, const=True)
parser_evolve.add_argument('--no-diagonals', '-d', action='store_const',
default=False, const=True)
parser_evolve.add_argument('--target', '-t', type=float, metavar="FLOAT",
default=None,
help="0 < Float <= 2.0 for targeted score")
parser_gen = subparsers.add_parser('generate', help='evolving help')
@ -87,6 +97,8 @@ parser_gen.add_argument('--steps', '-s', type=int, metavar='N',
default=30000)
parser_gen.add_argument('--gray', '-G', action='store_const',
default=False, const=True)
parser_gen.add_argument('--no-diagonals', '-d', action='store_const',
default=False, const=True)
args = parser.parse_args()
@ -133,17 +145,26 @@ if 'pool_size' in args:
# running jobs
res = pool.imap(eval_prog, works)
# Processing results
scores = [0 for _ in range(len(progs))]
for pid, score in res:
scores[pid] += score
scores = [(scores[i] / args.repeat_eval, progs[i])
for i in range(len(progs))]
if args.max:
scores = [ [] for _ in range(len(progs))]
for pid, score in res:
scores[pid].append(score)
scores = [(max(scores[i]), progs[i]) for i in range(len(progs))]
else:
scores = [0 for _ in range(len(progs))]
for pid, score in res:
scores[pid] += score
scores = [(scores[i] / args.repeat_eval, progs[i])
for i in range(len(progs))]
genstop = time.time()
# Displaying eval results
logger.info('Generation evaluating ended in %.2fs' % (genstop - genstart))
scores = sorted(scores, key=lambda x: x[0], reverse=True)
if args.target is None:
scores = sorted(scores, key=lambda x: x[0], reverse=True)
else:
scores = sorted(scores, key=lambda x: abs(x[0] - args.target),)
for i, (score, prog) in enumerate(scores):
logger.info('P%d %.3f : "%s"' % (i, score, str(prog)))
if args.log_progs is not None:
@ -176,7 +197,7 @@ else:
# Generate
w = World(args.world_height, args.world_width, gray=args.gray)
prog = rpnlib.RpnExpr.from_string(args.prog)
turmits = [LivingTurmit(world=w, prog=prog)
turmits = [LivingTurmit(world=w, prog=prog, diag=not args.no_diagonals)
for _ in range(args.turmit_count)]
msg = 'Generating image for program %s with %d steps and %d turmits'
logger.info(msg % (str(prog), args.steps, args.turmit_count))
@ -190,6 +211,9 @@ else:
logger.info(msg)
for turmit in turmits:
turmit()
#if step % 2 == 0:
# #w.save('/tmp/anim/GTE_ANIM_%d.png' % (step/10))
# w.save('/tmp/anim/GTE_ANIM_%d.png' % (step/2))
stop = time.time()
msg = 'Fractdim %.3f after %d steps in %.2fs (%dus per step)'

View file

@ -40,14 +40,16 @@ def mutate(expr, force = True, mutcount = 1):
return res
def mutatef(expr, mutcount = 1):
"""
mutations = [mutadd] * 3
if len(expr) > 1:
mutations += [mutdel] * 3
mutations += [mutupdtype for _ in range(3)]
mutations += [mutupdval for _ in range(6)]
#mutations = [mutadd, mutdel]
#mutations += [mutupdtype for _ in range(3)]
#mutations += [mutupdval for _ in range(6)]
"""
mutations = [mutadd, mutdel]
mutations += [mutupdtype for _ in range(3)]
mutations += [mutupdval for _ in range(6)]
res = copy.copy(expr)
for _ in range(mutcount):
mutations[randint(0, len(mutations)-1)](res)

View file

@ -10,6 +10,7 @@ _op_alias['add'] = '+'
_op_alias['sub'] = '-'
_op_alias['mul'] = '*'
_op_alias['div'] = '/'
_op_alias['mod'] = '%'
_op_alias['bin_and'] = '&'
_op_alias['bin_or'] = '|'
_op_alias['bin_xor'] = '^'
@ -146,12 +147,15 @@ class RpnSymbol(object):
if err:
msg = 'Invalid %s : "%s"' % (err_type, value.upper())
def __str__(self):
def __str__(self, small=True):
''' @brief Return a string representation of current symbol '''
if self.optype == self.OPERATION:
return _op_list[self.value][0].__name__.upper()
elif self.optype == self.VALUE:
return '0x%04X' % self.value
if small:
return '0x%X' % self.value
else:
return '0x%04X' % self.value
else:
return self.value.upper()

View file

@ -216,6 +216,15 @@ class Turmit(object):
'''
return a * b
@RpnOp
def div(self, a, b):
''' @brief Divides a with b
@param a int : value
@param b int : value
@return a // b
'''
return a // b
@RpnOp
def bin_or(self, a, b):
''' @brief Binary or

View file

@ -19,7 +19,7 @@ def eval_prog(args):
w = World(args.world_height, args.world_width, gray=True)
logger.debug('Running P%d run#%d %s' % (progid, trynum, prog))
w.raz()
turmits = [LivingTurmit(world=w, prog=prog)
turmits = [LivingTurmit(world=w, prog=prog, diag=not args.no_diagonals)
for _ in range(args.turmit_count)]
start = time.time()
@ -150,7 +150,7 @@ class World(object):
class LivingTurmit(Turmit):
''' @brief Represent a Turmit with coordinates in a world '''
def __init__(self, world, color = None, x=None, y=None, **kwargs):
def __init__(self, world, color = None, x=None, y=None, diag=True, **kwargs):
super().__init__(**kwargs)
if not isinstance(world, World):
@ -159,6 +159,8 @@ class LivingTurmit(Turmit):
if color is not None and len(color) != 3:
msg = 'Color expected to be a tuple(R,G,B) but %s found'
raise TypeError(msg % color)
## @brief If true direction contains diagonals
self._diag = bool(diag)
## @brief Stores Turmit color
rand_hue = randint(0,255) / 255
rand_lvl = randint(127,255) / 255
@ -167,12 +169,12 @@ class LivingTurmit(Turmit):
for i in colorsys.hsv_to_rgb(rand_hue,
rand_lvl,
rand_val))
if world._gray:
#self._col = 255.0
if world._gray == 'bw':
self._col = 255.0
elif world._gray:
self._col = tuple(round(i * 255)
for i in colorsys.hsv_to_rgb(rand_hue,1,1))
self._col = World.single_rgb2gray(self._col)
#self._col = (randint(0,255), randint(0, 255), randint(0,255))
if color is not None:
self._col = color
## @brief @ref World instance
@ -210,11 +212,12 @@ class LivingTurmit(Turmit):
if setcol:
self._world[self._y][self._x] = self._col
tdir %= 8
tdir %= 8 if self._diag else 4
if tdir == 0 or tdir == 4 or tdir == 5:
self._x += 1
self._x %= self._world.width
elif tdir == 2 or tdir == 6 or tdir == 7:
elif tdir == 2 or tdir == 7 or tdir == 6:
if self._x == 0:
self._x = self._world.width -1
else:
@ -222,7 +225,7 @@ class LivingTurmit(Turmit):
if tdir == 1 or tdir == 4 or tdir == 6:
self._y += 1
self._y %= self._world.height
elif tdir == 3 or tdir == 5 or tdir == 7:
elif tdir == 3 or tdir == 7 or tdir == 5:
if self._y == 0:
self._y = self._world.height - 1
else:

View file

@ -13,7 +13,7 @@ class RpnSymbolTestCase(unittest.TestCase):
def test_value(self):
sym = RpnSymbol(42, RpnSymbol.VALUE)
self.assertEqual(str(sym), '0x002A')
self.assertEqual(str(sym), '0x2A')
def test_op(self):
sym = RpnSymbol(0, RpnSymbol.OPERATION)