Author Topic: Evolved a zerobot descendant which uses a cond to toggle between storing different values in .dn, causing the bot to appear to pace back and forth  (Read 3323 times)

Offline Trafalgar

  • Bot Destroyer
  • ***
  • Posts: 122
    • View Profile
So today I evolved a zerobot descendant which uses a cond (actually a couple conds) to toggle between storing different values in .dn, causing the bot to appear to pace back and forth.

It took a while to figure out what was causing this, but I've effectively determined what's causing it and why, and what parts of the DNA are causing it (and what parts are not).

First, a bit of information on how I evolved this. This was evolved in a (size 1) sim which started this morning with 30 or so 429 gene bots, in 4.23a, with shepherds providing energy and reproduction, and some selection. Most of the descendants of the original 429 gene bots had fallen back to 426 genes before evolving this (or so it appears from the existance of many other 426 gene bots which did not possess this behavior). Before starting this sim, I had modified my Shepherd veggies to begin selecting for higher trefaimsx and trefaimdx values, and reducing the value of genes towards determining fitness to 1/20th of what it was before (They were also selecting for trefeyes, but had already been doing so for a day or two). The result was that the bots stopped evolving higher numbers of genes at breakneck speed, and instead stayed around the same level of genes while theoretically evolving more aimdx and aimsx references.

Currently I have costs slightly modified from F1 defaults: veggies get 400 instead of 40 energy per cycle, first, and secondly the cost multiplier is set to 2, and finally the cost for conditions was set to 0.04. (Why? Because the bots were proliferating too much, and if I upped the cost multiplier more, the veggies died a couple cycles after being born. Since the veggies had one cond and no actual conditions, I could safely ramp up the conditions cost without affecting them.)

The bots had gotten up to 1-4 total trefaimdx and trefaimsx around the time that I saved this bot's DNA (I also saved a couple other less interesting bots, one of which was firing shots constantly while moving, and one of which was doing the same while sitting still), although I don't actually SEE aimdx or aimsx in the DNA anywhere... There are quite a few references to aimleft and aimright in the DNA, though, but more than the amount trefaimdx and trefaimsx showed for the bot, so... I have no clue what myaimdx/myaimsx/trefaimdx/trefaimsx are actually looking at (unless I were to hunt for it in the DB .bas files).

The bot's DNA, saved as a .txt file (unmodified, of course), in a zip file (7 KB - the uncompressed .txt was 24 KB): http://shadowlord13.googlepages.com/bigzer...aimdx_3aims.zip

And here's my analyzed version of the bot's DNA. To analyze the DNA, I copied it into a new file, found the two .dn store instructions, and began removing sections and testing to see if the behavior persisted. Once I had determined that it went back more than just one cond, I was able to cut out all the irrelevant blocks. Then, I began determining which lines were important to the behavior, and commenting out lines which weren't. In the comments here I explain what I think is happening, and why. Although the analyzed version, if loaded as a bot and run, does exhibit the pacing behavior.

Most of the DNA which didn't contribute to this behavior was removed, for reading clarity, and the rest of the DNA which does nothing has been mostly commented out, also for reading clarity. (The bot's original .txt file is unmodified, of course)

I made some hypotheses (and noted them in comments in here) based on what I saw in the DNA, but I haven't looked in the DB source to confirm them.

Code: [Select]
' Lines which do nothing that impacts the result have been commented out for clarity.
' Hundreds of lines of DNA were omitted from this snippet. Some of it does interesting stuff, but none of it appears to directly affect this behavior, except that it makes the bots not go in a perfectly straight line.
' The main reason the lines which are commented out in here were not omitted entirely is because they were either much closer to the relevant code, or were in the same cond/start/else/etc blocks.
' The easiest way to find this code in the original .txt file is to search for .dn store. The -15 .dn store and 365 .dn store are the only places in the DNA that write to .dn, remarkably enough. (It turns out there are 17 .up stores - odd, that)

'Hundreds of lines of DNA were omitted here.

'Th store in here is always run. It just sets .dn to -15. The cond is probably always false. I wonder how xor handles having no arguments. Does it explicity return false because there are no arguments, or does it say "Oh, <no argument> is equal to <no argument>, therefore I should return false!" Hmmmm.
 cond
 0 5 0 xor
 start
 ++ ~ and
 1 else
 0 0 0 -15 .dn store

'Hundreds more lines of DNA were omitted here.

 'These two lines (starting with the cond) are necessary unless the first < in the next cond is commented out - If you comment out these, but not the <, the pacing stops happening. That indicates that < can still access stack values from previous conds :O
 'However, commenting out both these two lines along with the < results in no impact on the result, because the result of that comparison is always true (since it's checking if -12 < 0).
 cond
 0 *661 0 ~ 0 0 0 316 0 1 -8 0 -12 0 else
 '0 store
 '<
 '0 start
 '0 -21 else
 'start
 '563 1 -6 ~ 0 0 0 0 0 0 0 0 -8 0 -2 0 0 0 0 0 -14 0 0 0 *.up *0 .up inc
 '0 store
 '*1082 0 0 0 0 0 0 0 * 0 0 0 0 0 *0 0 0 0 start
 '-3 0 angle 0 << ++ *0 0 1 0 1 0 start
 'store
 'and

 cond
 'This pulls values from the previous cond! (We proved it, see the comments for the previous cond)
 <
 'The 'and' doesn't seem to be needed, but I'm not sure why it works. Best guess: There's a stack for values in conds, another stack for values in regular blocks, as well as a stack for boolean values from comparisons. Theoretically, "and" must check only the booleans, the boolean stack must be cleared after each cond, but the cond value stack must NOT be cleared after each cond, and "and" must return true if there is only has one boolean on the stack.
 and
 'Both these lines are needed:, but only the '461 0 0 0 <= 0 angle <' are actually used. The stuff before the 461 on the line is junk.
 0 1 0 ^ 1 26 ~ 461 0 0 0 <=
 0 angle <
 'What's actually happening there is (I think):
 'First, everything before 461 is unused by the comparison, so we ignore it here. It's all going on the value stack, but since it's not used, it's not shown below.
 'VS for value stack, BS for boolean stack, () enclosing an operator name, <> enclosing a value which was calculated in a previous step.
 'VS: 461 0 0 0 (<=)        BS:
 'VS: 461 0                    BS: true
 'VS: 461 0 0 (angle)        BS: true
 'VS: 461 <some angle> (<)    BS: true
 'VS:                         BS: true <true if the angle was less than 461, false if not>
 'All the rest of the junk after this line does nothing until the next uncommented line (which has a start at the end of it)
 
 'Not needed:
 '0 0 0 0 0 23 0 else
 '0 0 0 1 0 0 *.myeye 0 5 0 0 0 start
 '0 1 1 0 else
 '0 0 *-70 else
 '*284 0 -3 -11 0 start
 '0 16 0 218 1 angle 0 add <
 '12 -12 0 0 ~ 0 0 0 0 store
 '17 * 0 floor 1 0 0 0 ~ 0 0 and
 'inc
 '0 17 angle 0 0 else
 '1 0 -12 ~ 0 0 0 0 0 angle dist 1 else
 '0 0 1 0 0 0 0 0 0 4 507 0 0 1 start
 '0 start
 '0 0 add 0 0 *.dn rnd else
 '0 start
 '0 store
 'Theoretically, the next line should write 14 to something if memloc 980 contains a value. But it's not important for this, since 980 is never written to. Of course, another bot could fire an info shot into 980 to (sometimes) cleverly make the bot do interesting and/or evil things to itself
 '^ 14 *-20 store
 '0 0 0 0 0 0 start
 '0 0 add 0 0 ~=
 '605 0 and
 '0 0 0 else
 'mult 0 0 0 0 -11 0 angle -6 0 0 0 <
 '0 0 0 <
 'mod 0 1 floor add 0 1 xor
 '0 0 - 0 0 0 -808 not
 'store
 'angle =
 
 'This is controlled by the above cond. Apparently a cond can have multiple start and elses attached to it, even alternating them, without any problems.
 'start
 '0 inc
 '-275 0 0 store
 '1 1 1 0 0 0 0 0 0 1 0 0 0 0 1 and
 '0 12 0 <
 '0 0 add else
 'In this next line, only the start is actually needed (the rest isn't used, but a bot could later evolve a store before that start which happens whenever the condition above is false):
 1 0 0 0 *-30 6 | 0 *678 0 0 ~ 0 0 start
 'The < on the next line does nothing, as far as I know:
 '<
 'sets .dn to 365 if angle(0,0) < 461
 0 365 .dn store

Methinks evolution is messy . If I were coding that for a bot, and were using multiple conds, I would have written:
Code: [Select]
cond start -15 .dn store stop cond 461 0 0 angle < start 365 .dn store stop
Or SGized:
Code: [Select]
cond start -15 .dn store 365 461 0 0 angle sub sgn - 0 floor .dn mult store
Or combined into one store (still SGizing, but on a modifier to the value, instead of on the address of one of the stores):
Code: [Select]
cond start -15 380 461 0 0 angle sub sgn 0 floor mult add .dn store
Of course, the SGized stuff looks almost as messy as the evolved stuff.

I thought about whether it was likely or unlikely for evolution to have resulted in a real condition rather than an SGized one, and I'm thinking it's probably more likely for evolution to evolve actual conditions than to evolve SGized ones, since SGizing effectively requires chaining multiple specific operators (if evolution gets any part of a SGized operation wrong, it will either fail or cause side-effects in other memory locations), whereas regular conditions just require getting a single comparison operator after some comparable dynamic values.

Or if it had evolved something semi-SGized-like, it would probably have been unreliable. Who knows. I guess we'll have to wait until someone spots a SGized condition in a zerobot descendant.

Also, we can be quite certain that no DNA from the shepherds got into these bots' ancestors, as:
1. There is nothing like the shepherd's DNA visible in the bot's DNA (it would be highly compact SGized stuff), and
2. The shepherds destroy any bots which are producing viruses.
3. The shepherds kill themselves if infected with a virus.
4. If the shepherds' gene got into another bot anyways, it would then kill that bot (by recognizing that it isn't actually a shepherd).
5. The shepherds' anti-virus capabilities got an actual test (and improvement, along with these other features, most of which weren't in existance before viruses got loose) several days or a week ago, when the shepherds' anti-virus code was not as good, and apoptosis wasn't implemented - The bots which had obtained shepherd DNA were all destroyed, and the sim which had evolved the gene-stealers was re-run from their last saved non-corrupted but virus-producing ancestor, until the shepherds' were proven capable of preventing it from happening again. (It reliably happened again every time a sim was run from that ancestor until the shepherds' virus-maker-killing code was strengthened and the shepherd-apoptosis code was added)

My thinking from the start was that viruses were the number one threat to zerobot evolution sims, as they could result in corruption of the zerobot-descendant DNA by stealing human-made DNA from the veggies - of course, if the veggies were DNA-disabled, stealing DNA would be impossible, but it was even more important (but also easier to detect) with a sophisticated shepherd veggie. Even when the virus-killing measures had failed, and the shepherds had by and large deleted the virus gene (eventually), the effect was still quite visible as the shepherds had ceased functioning normally. Of course, now, instead of ceasing functioning, they kill themselves (Technically they do still cease functioning normally, so it would be visible in case the apoptosis failed).

Theoretically a human-created virus could get in, block apoptosis, and block delgene, then steal the shepherd's gene for other bots, but this would probably be beyond the capability of evolution to evolve. To accomplish that, the bot would have to find a location that's not near any shepherds, or hover out of tie range of them, then make a virus, then find a shepherd when the virus is almost ready to fire, then manage to shoot the shepherd with it before the shepherd disintegrates the bot with an instakill tie attack, not to mention that the virus would need to be sophisticated enough to prevent the shepherd from killing itself (by constantly clearing both strvenom and strpoison), and would need to prevent the shepherd from deleting the virus gene (An infected shepherd tries killing itself AND deleting the virus, but also accounts for viruses with delgene dec defenses, since I copied the antivirus code from Guardian). If it were to steal the shepherd's gene for itself or other bots, it would first take several thousand cycles to copy the shepherd's gene (Its length at present is 2810), and then the bot receiving the gene in a virus would also need to be capable of protecting itself from strvenom and strpoison, even though it won't be able to predict where in its genome the shepherd gene will be added (meaning the bot's anti-apoptosis DNA would, to be reliable, need to be in one of the last genes in the bot, and even then might get unlucky with injected gene placement)...)

P.S. I still haven't evolved any bots which can repro themselves!

P.P.S. The reason I specifically evolved bots with 400+ genes was that I figured that with that many genes, they would be far more likely to evolve a condition which did something noticeable than bots with less DNA and/or less genes. It appears to have worked.

Offline Numsgil

  • Administrator
  • Bot God
  • *****
  • Posts: 7742
    • View Profile
  Nice work

Quote from: Trafalgar
although I don't actually SEE aimdx or aimsx in the DNA anywhere... There are quite a few references to aimleft and aimright in the DNA, though, but more than the amount trefaimdx and trefaimsx showed for the bot, so... I have no clue what myaimdx/myaimsx/trefaimdx/trefaimsx are actually looking at (unless I were to hunt for it in the DB .bas files).

aimleft and aimright are more modern labels for aimdx and aimsx.  Aimright points to the same place as aimdx.

Quote
' The easiest way to find this code in the original .txt file is to search for .dn store. The -15 .dn store and 365 .dn store are the only places in the DNA that write to .dn, remarkably enough. (It turns out there are 17 .up stores - odd, that)

.up is 1, and .dn is 2.  So since 1 is closer to 0 than 2, it would make sense for there to be more .up.

Quote
'Th store in here is always run. It just sets .dn to -15. The cond is probably always false. I wonder how xor handles having no arguments. Does it explicity return false because there are no arguments, or does it say "Oh, <no argument> is equal to <no argument>, therefore I should return false!" Hmmmm.

If the condition stack is empty, it just returns true for any queries.  So xor would test true vs. true.

Quote
- If you comment out these, but not the <, the pacing stops happening. That indicates that < can still access stack values from previous conds

This is correct.  In fact, there is only a single stack for numbers, so a cond can access values from previous gene bodies as well.  There were reasons it's set up like this, but I forget what they were.  Had to do with backwards compatibility for some weird bots no doubt.

Quote
'This is controlled by the above cond. Apparently a cond can have multiple start and elses attached to it, even alternating them, without any problems.

Right.  A cond sets up a condition flag that determines wether starts or elses after it will run.  You can have lots of genes controlled by a single cond.

Quote
P.S. I still haven't evolved any bots which can repro themselves!

Not really that surprising, since you shepherd bot reproduces them.

I figured that the sort of sophistication you're using here would require a scripting system.  Good to see you working within the current system for the same effect.  You might consider selecting for some more esoteric traits, such as *.refkills, *,refshell, etc.  You might be able to grow some evo battle bots using your methods, which would certainly impress me

Offline Trafalgar

  • Bot Destroyer
  • ***
  • Posts: 122
    • View Profile
Quote from: Numsgil
I figured that the sort of sophistication you're using here would require a scripting system.  Good to see you working within the current system for the same effect.  You might consider selecting for some more esoteric traits, such as *.refkills, *,refshell, etc.  You might be able to grow some evo battle bots using your methods, which would certainly impress me

At the moment, I'm trying to evolve waste-disposal from bots which currently shoot memloc 1 info shots (they're using .shoot inc).
Maybe I'll try evolving battle bots after that. (The problem with battle bots is that they'll kill the shepherds too. )

Offline Numsgil

  • Administrator
  • Bot God
  • *****
  • Posts: 7742
    • View Profile
That's when you know they're ready for the leagues.  "When you can kill me, then your training is complete".