Talk:PY tutorial

From WikiManual
Revision as of 09:24, 18 December 2005 by Griz (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

stash of complete tute
for reference while constructing pages.

DarwinBots

A complete tutorial for DarwinBots Written by Purple Youko. All rights reserved.

Revised for V2.3

Contents


A Basic Overview What is a DarwinBot?

A DarwinBot lives in a 2-dimensional universe and feeds by extracting energy from other DarwinBots. DarwinBots of various design form the entire food chain.

For the purpose of this tutorial I will largely ignore mutations and focus on programming strategies instead.

What commands can a DarwinBot use in his DNA?


What is a Command? A command is a memory location into which a value is stored in order to make the robot perform a certain operation. They are addressed via labels.

What is a label? A label is a name preceded by a period. Each command and function can be addressed either by a label or by using their numerical address. Examples of labels are .refeye or .up.


What is a function


How does the DarwinBot process the information in his DNA.

The DarwinBot DNA uses a version of the more common IF/THEN statements found in all versions of BASIC, to decide on which actions to take based on input from certain of his memory locations (Functions).




Cond

start

stop


IF Apples = 10 THEN

END IF


Cond

  • .eye5 10 =

start

stop


  • .eye5 could also be written as *505 (the value stored in location 505)


  • .eye5 places the value stored in memory location 505, onto the top of the stack.

10 places the value 10 onto the top of the stack. It goes in above the previous value, providing there is enough remaining space in the stack for it to do so. =


= The 2 values are equal. != The 2 values are not equal. > The first value is greater than the second value. < The first value is less than the second value. %= The two values are almost equal (within 10%) !%= The two values are not almost equal (within 10%)

How do I create a robot?

In order to make a good robot, you need to give him three things.

1. The ability to find food. 2. The ability to eat the food. 3. The ability to reproduce.


Alternatively each stage of the development of Simplebot can just be loaded into the game from the Simplebot files included with this tutorial.


You should be about ready to go now.

During this tutorial I will take you through all the stages of development of a combat oriented robot. Many of the things we try will inevitably be dead ends and will make our robot worse than at previous stages. These failed strategies can teach us a lot about the war DarwinBots works and hopefully make us all better programmers. Tip. I used the table in Appendix 2 to estimate the turn angle for eye3 and eye7


cond

 *.eye3 *.eye5 >

start

 -70 .aimdx store

stop


cond

 *.eye7 *.eye5 >

start

 70 .aimdx store

stop


cond start

 5 .up store

stop


cond

 *.eye5 40 >

start

 -1 .shoot store

stop


cond

 *.nrg 5000 >

start

 50 .repro store

stop

end Available as Simplebot1.txt Please note that all Simplebots for V2.3 are different than previous versions.



The second is that he keeps missing all the food and going into orbit around it instead of eating the stuff.



cond

  *.refeye 5 =

start

 180 .aimdx store

stop Available as Simplebot2.txt

See how much more efficient he is now? We have turned a pretty useless little robot into a pretty good one. He already beats the heck out of some of the more basic robots such as C-Ancestralis and even gives good old Preservans a good run. With a few minor alterations, we could probably make him really good. Let the program run for a few thousand cycles and see what the population reaches. He should max out at around 80 or so.




The NON-Spinning approach. OK then. How do we stop Simplebot from spinning? We need to make sure that the new gene that makes him spin is only activated under certain circumstances and not all the time. We put the gene in to make him turn away from his family members so I guess we need to make sure he only turns when he is actually looking at one of them and not at a permanent afterimage.

Try adding the following line to the condition section of gene 6.

  • .eye5 0 >

You will also need to change the value of the other line in this gene from.

*.refeye 5 =   to  *.refeye 6 =

Available as Simplebot3.txt

This is because we have added another eye cell to the genome. Save the file and restart the simulation again. Let it run for a few thousand cycles again to see what the robot population reaches. It should max out at around 60. That is a bit worse but still pretty respectable.


They are obviously running out of energy and dying.


Now click on the button with the circular arrow. This will run the entire program for one cycle. Do this a few times in a row and note how much energy Simplebot is expending just to stay alive and search for food. He loses, on average, about 2.5 energy points each cycle. We need to try to improve that. Now, where do you think that Simplebot expends the most energy?





  • .vel 40 <

Available as simplebot4.txt

Now save the Simplebot file and restart the simulation. Open up the console as before and take a look at his energy expenditure now. He hardly uses any at all does he? About once every 15 or 20 cycles he boosts his speed by five points to keep his speed up but the rest of the time he just coasts along.

Why not let him run for a couple of thousand cycles to see how high the population gets while we think about possible improvements. He only reached about 25 robots in 2000 cycles on my system. (He will reach about 70 if you leave him long enough but that is only because he has no competition so he loses very little energy..) Why has he gotten so much worse? He is obviously much more energy efficient. He is just a really crappy hunter.

So how do we improve him again?

Maybe there is some way we can use the value in .vel to calculate a suitable acceleration automatically. That would let Simplebot accelerate really hard when he needs to and cruise effortlessly once he reaches a good speed.




Try changing the action line in gene 3 from..

 5 .up store  to  40 *.vel sub .up store

Available as simplebot5.txt

What does this line do? Well first we need to remember the order in which these calculations are carried out in Reverse Polish Notation. First we place 40 onto the top of the stack just by typing in the number 40. next we place the value stored in the memory location pointed at by the label .vel onto the stack. The * in front of the label means that we are using the value in the location rather than the number of the location. So now the stack has 2 numbers in it. First there is 40 then there is whatever value *.vel represents. The next thing we see in the code is the word sub. This tells the program to subtract the top number in the stack from the next number in the stack. In doing so both numbers are removed from the stack. The result of the subtraction is then placed on top of the stack again. So in effect we could have written something like a = 40 - *.vel if we had been using algebra. Next we take the number on top of the stack and move it to the .up memory location by using the store command.

Try it out and see what happens.





Any ideas?

No?

Well here is one possible way to address the problem. We just stop the acceleration while ties are present. Luckily we have an easy way to detect the presence of ties with the .numties function. This function automatically places a value into the .numties memory position every cycle so all we have to do is read it.

Try adding this line to the condition part of gene 3, right underneath the *.vel 40 < line.

  • .numties 0 =

Available as simplebot6.txt

This will prevent the activation of the gene as long as there are any ties attached to the robot. Load up your new version and try it out.


The reason is that once there are enough simplebots floating around the screen then they tend to see each other quite often. Every time they do so, they change direction so their forward velocity is no longer 40. This means that they will accelerate at whatever rate it takes in order to get up to full speed again. This is quite a useful feature when dogfighting with another species of robot but is counterproductive when trying to get top movement and feeding efficiency.

There are a number of ways to substantially improve Simplebot6. These include improving his food finding genes, possibly by adding an extra 2 genes to look at wider angle eyes such as *.eye1 and *.eye9. Look at the chart in appendix 2 to see where the eyes are able to see and which course changes to apply to .aimdx or .aimsx. You could also experiment with his acceleration genes by dividing the acceleration amount by 2 or 3 so he expends less energy.


Save your robot as SimpleBot7. I have deliberately left that name free for you to do so.

The Spinning Approach

Try this out yourself or just load up simplebot8.txt and let him run for a while.

When you have finished tearing out handfuls of your own hair, have a really good look at the way he spins. There is something not quite right about it. Can you see what?


  • .refeye 5 !=

Available as simplebot9.txt




Just load up I_Flamma. Give him a different color than Simplebot9 and 5 individuals at 3000 starting energy. Disable his mutation and start the simulation. Now let them fight it out for a while.

Are you surprised that Simplebot actually won? I flamma would have won in older versions of DarwinBots. It just goes to show the number of changes that have been made behind the scenes. For example, why not adjust the maximum veggie population and growth rate from the options window. Set max veggies to 100 and adjust the number in the top left until it shows the approximate number of veggies (message to the right of it) as around 250. This gives us a whole lot more veggies and levels the playing field a little. They grow much faster too.


Now have a really good look at the way Simplebot is behaving. Notice anything not quite right?


Available as simplebot10.txt

Well Simplebot10 really sucks. In less than 5000 cycles he died out completely. The reason?



' Gene 7 wide search 1 cond

  • .eye1 *.eye5 >

start -140 .aimdx store stop

' Gene 8 wide search 2 cond

  • .eye9 *.eye5 >

start 140 .aimdx store stop Available as simplebot11.txt


Try it out and see what happens. Not very good is it? Simplebot eats his own kind again just like he used to in the early days. Why is that? It is because we added 4 more eye functions without changing the .refeye function to allow for it. We need to go back and change the .refeye functions in gene 3 and gene 6 from 5 to 9. Available as simplebot12.txt

Either make the changes or load up simplebot12.txt and start the simulation again. That made a little bit of difference but he still has that orbiting problem. Simplebot12 is starting to get quite good now. If we can just stop that orbiting then he would be REALLY good. There is still at least one major flaw in his design. Anyone spotted it yet? Let him carry on for a few thousand cycles to see what his population reaches while you think about it.

Look carefully at the way he searches for food. Check it by cycling through the console as he approaches a veg. You will often see gene 1 activate to rotate him a small amount toward his target then gene 7 will also activate to rotate him a lot. The result is that gene 7, which is situated later in the genome than gene 1, places its value into the same .aimdx location that gene 1 already did. Since only one value can exist in .aimdx (or any other memory location) at any one time, the gene 7 value overwrites the smaller gene 1 value. Think about it a bit and you will see that the smaller gene 1 value is the one that needs to be set last. It is far more important to home in on a target near to the center of the field of vision than it is turn towards one in peripheral vision when there is already one near to the center.


Run the simulation again.


No matter what we do, he just keeps going into orbit. We will have to do something about that I think He still beats Flamma but not too convincingly


What we need to do is to stop his forward momentum when he turns but how?


One thing that becomes quite obvious is that rotation commands are carried out before everything else. That means that if Simplebot rotates then he will be facing in a slightly different direction before any acceleration commands are carried out. That gives me an idea. Why not make use of the sideways acceleration commands as we will be kind of sideways to the direction of movement already anyway. We can add an extra .dx command to each turn gene. That aught to do it.


Go and change the four search genes. Here is how you do the first one

' Gene 7 wide search 1 cond

  • .eye1 *.eye5 >

start -140 .aimdx store -14 .dx store stop

Note that I have set the .dx value at one tenth of the .aimdx value. Do this for all four genes (alternatively load up Simplebot14.txt) and run the SIM again.

Now that is MUCH better! No more orbiting! However he still seems to have a little difficulty with very fine angle adjustments. Remember that the innermost eyes that he is using are eye3 and eye7. (Perhaps we could try using eye4 and eye6 for tighter control?) So how large a population does simplebot14 reach?

Did you also notice that the population reaches a peak then begins to decline again? If you leave the SIM running long enough, they actually die out completely.



Mystery solved!



We should probably sort out that waste problem now so add this gene to the very end of the genome.

'Gene 9. Get rid of that waste cond

  • .waste 100 >

start -4 .shoot store

  • .waste .shootval store

stop

I have already added this to Simplebot15


For a start, he is much better at shooting those veggies now. Hardly any of his shots miss now. His population increases much faster than before due to his more aggressive feeding. Let him run for a while to see how he does. I have just let them run for 20,000 cycles and none of them have more than 100 waste. It worked!!


Try him against poor old I Flamma again and see how quickly he wipes the floor with him now.


Well that concludes the basic stuff. There are still a load of ways to improve Simplebot though





ADVANCED PROGRAMMING!


First of all though I want you to think about this question.


The answer is simple too. He still expends too much energy, a lot of the time, just to keep living. He is also fraught with inefficiencies.


Every store command that is executed costs 0.2 energy and every point put into acceleration (.up .dn .dx .sx) costs 0.5 points of energy too. On top of that, every shot that he creates costs 2 energy. Simplebot needs to go on a diet.


How do we fix that?

We need to decide the hierarchy of the turning controls then place them with the lowest priority at the start of the genome and higher priorities later in the genome where they will overwrite the earlier ones. The priorities are as follows.

1. Make sure that if simplebot is already facing food then he does not turn at all. 2. Avoid conspecifics. If this is overwritten then Simplebot will just chase his family around and waste energy. 3. Turn toward food near to the center of his field of vision. 4. Turn toward food at the outer edges of his field of vision.


What we are going to do is to delve deep into the dynamics of the stack so that we can avoid all those store commands.



We can also modify the .dx commands that we added to the steering genes earlier.

That is where we have to get clever. Each time we put a value in, we also have to take one out. I will show you how to alter gene 7 (now the first gene in the genome) then you can alter all the others yourself.

Change.

' Gene 7 wide search 1 cond

  • .eye1 *.eye5 >

start -140 .aimdx store -14 .dx store stop

into

' Gene 7 wide search 1 cond

  • .eye1 *.eye5 >

start mult -140 stop






cond start .aimdx store stop


' Gene 11. slide to the side. cond

  • .aimdx 0 !=
  • .aimdx 180 !=

start

  • .aimdx 10 div .dx store

stop


Why?

Notice that I have also use a division so as to apply one tenth of the .aimdx value to .dx. I am beginning to feel a little sorry for poor old I_Flamma. He is just getting his butt kicked up and down the screen all the time. So how is our population doing this time? It got up there around 170-180 pretty quickly but still seems to be rising a little bit. Looks like it topped out around 195. Not bad.

Have you noticed, though, that even when there are no veggies about they are still shooting sometimes? I think we need to take a look at that shoot gene that I mentioned earlier. The only condition there is that Simplebot sees something at a value of greater than 40. (about the shot distance limit) We need to stop him shooting at friends. Add this line to the conditional step of gene 4.

  • .refeye *.myeye !=

Wait a minute!!! What is this *.myeye thing?



After you make this minor change, try it again. Also available as Simplebot17.txt


I notice that he is still having a tiny bit of trouble in precisely lining up on a veggie. The reason for this is that at this kind of range (almost touching) the veggie takes up 3 eye-cells instead of 1 as it does when further away. Maybe we should compare eye4 with eye6 rather than with eye5? That way he should be able to home in a little better while he is really close. What do you think? Try it out for yourself then load up Simplebot18.txt and see if you got it right.

That is more like it. Now we are seeing some real aggression. I Flamma is completely wiped out in a couple of hundred cycles and Simplebot goes way on up to 300 population and beyond. (450 @ 4500 cycles and still climbing) It really made that much difference? Hey! I just realized that Simplebot is way up there on the Formula 2 league table by now. Perhaps we need to move on to the next rung.



It seems that in match after match, Simplebot just carves his way up the Formula 2 table. He was only stopped, in fact, by Circumversor Cantharissa (a poison bot). He actually beat Circumversor Cantharis (also a poison bot but not quite as efficient) in a very close match. They say the female of the species is more aggressive and in this case they are right.



Just step the program through a few cycles and watch the gene activations. He keeps reaching 5000 energy and attempting to reproduce. But no baby. This is rather inefficient behavior if he wants to gain rapidly in population so need to be sorted out. How though? (It is considerably better than earlier versions still. In those he would actually lose a big chunk of energy equal to the length of his own genome. That has been stopped for V2.3)



  • .eye5 40 <


Why not just load up simplebot19.txt and save yourself the trouble of changing it all. Go on. I know you want to.




We are going to start by adding two new genes. Place them anywhere you like.


cond

  • .robage 0 =

start .tie inc stop


cond

  • .robage 1 =

start .deltie inc stop

Note the free energy tie firing and deleting by using inc instead of store to place a value of 1 into both of these commands.

Go back to the reproduction gene and add these two lines to the action step.

mult 628 50 inc

Why? You ask. Well the first line should be obvious by now. We are making simplebot rotate by a value of 628 (or 180 degrees). Since reproduction, shooting, tie firing and just about everything takes place after rotation on each cycle, this means that simplebot will rotate 180 degrees then pop out a baby. The 50 inc line is a bit less obvious. What we are doing is setting a reference value that will be used next cycle to turn simplebot back the way he was originally facing and carry right on feeding. We use inc instead of store to save energy.

We also have to go into the condition step of the reproduction gene and take out the line that we added in the last step. You know. The one that only allows simplebot to reproduce when his eye5 cell is almost empty. We have to get rid of this or the whole improvement would be pointless. We want simplebot to reproduce while he is still actively feeding. Go ahead and delete that line now.

The final step is to add a new gene that will make simplebot rotate again when the value in memory location 50 is equal to 1 or more realistically greater than zero just in case it becomes 2 or more. Stranger things have happened.


cond

  • 50 0 >

start mult 628 50 dec stop

Finally cut and paste gene 6 (avoid conspecifics) in between gene 4 (shoot the food) and your new gene 12.

If this is all getting too much for you then just load up simplebot20.txt and start up the simulation again. Prepare to be amazed! When you see how simplebot has improved.


He easily reaches a population of 400 in under 5000 cycles. The scary thing is that there are still a bunch of minor (and one or two major) adjustments that could be made to improve him still further. Simplebot is now undeniably one of the all time great F2 bots second only to Cantharissa. WOAH!


Tie Bots The next evolutionary step for a DarwinBot has to be improved feeding capabilities. How are we going to improve on Simplebot?

The name of my Devincio series of robots really says it all. Devincio is Latin for tie. All Devincio robots use ties to feed though some are better than others. Simplebot is able to defeat the first tie feeder bots with ease due to its amazingly efficient reproduction system. H_Devincio_Venator (HDV) was the robot that first started the tie feeders on their path to glory. HDV4 is a somewhat modified version of the original HDV and held the top spot for some while. VEX was the first tie feeder to utilize the spinning search pattern that Simplebot uses and it gave him enough of an edge to unseat HDV.

What are ties? That is a good question. Ties are a feature of DarwinBots that was added in order to enable multiple individual DarwinBots to join up and form a multi cellular organism. A tie represents a defined relationship between two robots and is seen in DarwinBots as a thick line joining the two robots together. The tie keeps the robots in a fixed but flexible orientation to each other but only after a certain number of game cycles have passed. For the first 20 cycles the ties allow for free rotation of both robots.

What do ties do? Ties are one of the best and most challenging parts of the whole game. The things that ties allow robots to do are amazingly varied and a good proportion of all gene commands relate to ties in some way or other.

Once hardened, the tie can also be set for length and orientation angle with respect to the robot on either end of it. It also enables sharing of energy, waste, shell and slime.

For the time being we are not interested in hardened ties. If we wish to feed from the tie then we need to act fast, not wait 20 cycles before doing anything. The only thing we need to do is to utilize the energy transfer function to drain energy from the robot on the other end of the tie.

How do we make a tie? Actually creating a tie is quite easy. All you need to do is to store a non zero value in .tie (memory location 330).


Here is Tie bot 1

' Tie-Bot 1

cond

  • .eye4 *.eye6 !=

start

  • .eye4 *.eye6 sub .aimsx store

stop

cond

  • .vel 40 <

start 40 *.vel sub .up store stop

end Available as Tie Bot 1.txt



A much larger problem is that he has a very narrow field of vision so he misses food that is just a little bit too far away from where he is facing.

Look back over the lessons you learned from Simplebot and try to figure out where we need to add the new gene. Its positioning will be critical to the operation of Tie-Bot 3.




Not bad. He reaches 170 robots pretty quickly. In 3000 cycles to be exact. We still have that problem with energy wastage while reproducing though. Both robots tend to pull on the tie with an acceleration of about 40 each and in many cases one or both end up dying because of it. We could reduce the acceleration rate or disable movement in young robots but either of those options would make Tie-Bot less effective as a hunter and would leave his young extremely vulnerable.


I will eventually use a similar method to that employed by Simplebot but for the moment I will leave reproduction the way it is. You will see why a little later on.



Cond Start 1 .tie store stop

This is a really stupid gene but demonstrates some of the difficulties associated with tie feeders.


Notice the way that he sometimes ends up collecting 3 vegs and then dragging them around the screen while shooting other vegs for food.


Did you also see the way he reproduces? The babies just pop out with no tie connecting them to the parent at all.

Obviously we need to be a little more careful about when and where we shoot ties. We also need a way to feed through the ties once they are attached. First we need to add a condition or two to the gene that fires the ties. Change the gene to this. Note that we now have an extra eye but the use of *.myeye takes care of that automatically

cond
  • .eye5 30 >
  • .refeye *.myeye !=

start 1 .tie store stop

In order to feed through the ties we have to set values for .tieloc, .tieval and .tienum. .tienum is the memory location that tell the program the identification number of the tie through which we want to feed. Since we stored a value of 1 into .tie when we fired our tie, we also need to store 1 into .tienum to address the tie.

The number stored in .tieval is the quantity of energy that we wish to exchange while we are feeding through the tie. If we want to give energy away we would use a positive number but if we want to take energy then we need a negative value. When I first discovered this feeding method the amount of energy that could be given away was limited to 100 but there was no limit to the amount that could be taken. This led to many crashes in the program so my later releases (2.12 and later) have a built in limit of 1000 energy points per cycle in either direction.


cond

  • .numties 0 >

start -1 .tieloc store -1000 .tieval store 1 .tienum store stop

The condition *.numties tells the DNA how many ties are currently attached to the robot. In this instance no attempt is made to feed unless at least one tie is detected.


Watch closely from the console as one of our robots reproduces after swallowing a couple of vegs whole. Select a robot and step him forward until he reproduces. The young one appears as normal complete with a reproduction tie. This tie has an identification code of zero so it cannot be directly addressed using .tienum. This is because the program requires a non-zero value in order to process the command. With the parent robot selected immediately after reproduction, click the button in the console window that looks like an eye. A row of 9 numbers will appear in the output window. These represent the eye cells. You will note that the middle 5 numbers are all 77 (at least they normally are). The young one is so close that he fill 5 eye cells.

  • .eye5 is definitely bigger than 30 so one of the conditions needed to fire a tie is satisfied. What about the other condition then? *.refeye needs to be something other than the value in *.myeye.


? .refeye


The console output window should now read

? .refeye 708-> 0


This means that the second condition in the tie-firing gene is also satisfied in both the parent and the young. They both fire ties at each other immediately after birth. How do we get rid of this tie then? Or should we prevent it from firing in the first place?


cond

  • .robage 0 =

start 50 rnd 55 store stop


OK then. Where were we before we got side tracked? Trying to figure out how to stop the tie being fired when the new robot has just been born. We can easily stop the young one from firing it. All we would have to do is to add a condition to the tie-firing gene which would prevent a robot of age 0 from firing a tie at all. Stopping the parent from shooting a tie is a little more complex though. We cannot use *.robage this time.


  • .refeye 0 !=

Would this work in addition to the other conditions in the tie-firing gene?


  • .refeaimdx 0 !=

Vegs have one .aimdx command so this would work to allow shots at them still. Trouble is that Tie Bot has no .aimdx commands at all. Do you think this would be a problem?


This is a real problem. Hey here is a thought. Those eye cells are always equal to 77 when a new robot is born so we could add this line.

  • .eye5 77 !=


Note the addition of an initialize gene to put a random value into memory location 55 to be used as the ID number for ties. Each time we address a tie now, whether to fire it or feed through it, we now use *55 (the value stored in location 55) rather than 1 Sorted!! No more robots fixed together by red ties. At least most of the time anyway. Now the feeding takes place only when and where we want it to.


We still get the occasional two robots joined together by red ties but they are few and far between now. Another problem is in the way that Tie Bot breeds. We get large chains of young ones all fixed together so they are less effective than robots such as Devincio Dominator Invincibalis (also included in the tutorial directory). Try running Tie Bot-7 against Dominator Invincibalis and watch the differences in the way they reproduce. We need to make Tie-Bot reproduce that way. Fortunately it is reasonably easy to do this. In fact it can be done in several ways.


1 .tie store

and then to add an entirely new gene to follow it..

cond

  • .robage 1 =

start 1 .deltie store stop



We can stop this either by making the targeting routine more accurate or by deleting the tie if it is attached to a friend. Lets try both.


The best way is to make sure that the central 3 eyes are all seeing the same thing at the same distance. If this is the case then the chances are that Tie-Bot is facing directly toward the target. Lets try adding the following line to the conditions of the tie-firing gene.

  • .eye4 *.eye6 =


  • .eye5 30 <

That should give us enough room to reproduce. I am so glad that we decided to use *.myeye in all of the conspecifics recognition routines or else we would have to change all of the .refeye conditions.. Again.. There are 17 of them now.

Well Tie-Bot 8 seems to work OK but it still does the same thing as before. We need to delete those ties I think. Another problem that we seem to have introduced is that Tie-Bot sometimes pushes a veggie around the screen for ages without firing a tie at it. Obviously by making sure that eye4 and eye6 are the same before allowing a tie to be fired, we have made him a bit of a fussy eater. So how come he still manages to eat his relatives then?


How about we use a slightly different condition? Instead of making sure that eye4 and eye6 are exactly equal, we can be a bit clever and make them almost equal. Do you think that might help? Check out Tie-Bot 9 to see if it does.

Yes it did. The targeting seems much better now.


  • 55 .readtie store

This will allow us to read the tref variables from the robot that we are tied to. We only need to use this line once since the value is never reset until we set it ourself. We will now be able to read values through the tie that corresponds to the value in *55. Next we will add a new gene..

Cond

  • .trefeye *.myeye =

start

  • 55 .deltie store

stop






cond

  • .slime 100 <

start 50 .mkslime store stop

You will find the new version as Tie Bot-11.txt

This time it is a bit of a different story. Tie Bot-11 still loses but it is a much closer fight now.

Slime actually reduces the overall efficiency but gives a tie feeder a much better fighting chance when facing others of similar persuasion. We can now only reach a population of around 450. The trouble is that slime slowly degrades and has to be constantly replaced so it is a drain on available energy.

Did you notice something else a little strange? Some of our Tie-Bots appear to be moving backwards some of the time. That is a bit weird.


What is Poison? It is a nasty, insidious defense mechanism that can be employed by any robot that wants to use it. By spending a little energy, a robot can fill up a sac of poison. When he is hit by a shot from an enemy robot, instead of sending an energy shot back the other way, he sends a poison shot of equal value to the energy that he would have sent. This can only happen if the poison sac contains enough poison or else the robot just loses energy in the normal way.

So how come Tie-Bot is affected when he is, in fact, a TIE bot rather than a Shot-Bot?

So how do we defend against this poison stuff?


Try adding this line to condition step of the shoot gene.

  • .refpoison 0 =

That should stop him being poisoned anyway.

Load up Tie-Bot 12 and run an F1 sim against HDV4. Now things are much closer. Tie-Bot actually wins some of the duels now. He still gets poisoned now and then but no trick programming is completely foolproof. There is still one more thing that I see happening that needs fixing. Sometimes a Tie-Bot seems to be unable to fire any ties at anything. That is because the value stored in *55 can sometimes be zero. Since the program looks for a non-zero value in order to activate the .tie command, no tie will ever be formed. See if you can figure out how to fix this little fault on your own.

As before with simplebot, there are still a number of things that we could do to make Tie Bot even stronger. I will leave you to figure out what they are. A robot that can hold its own against HDV4 is quite good enough for a tutorial. There are many ways to create a tie-feeding robot as good as Tie Bot-12 This tutorial follows but a single path that was chosen for its differences from the methods used in Simplebot. As you can see from this tutorial, the possibilities are almost endless. I expect to see a whole bunch of new and stronger robots out there in the F1 league soon.


In the next part of this tutorial we will begin to delve into the complexities of creating stable Multi-Bots. If you think that the lessons you have learned this far have been complex then you are sadly mistaken. In order to make a Multi-Bot work properly we will need to learn a whole new set of rules.



Multi-Bots. Tricky but fun.

First off; what is a Multi-Bot? A Multi-Bot is simply an organism made up of more than one DarwinBot. In order to qualify as a genuine Multi-Bot (or MB) it also has to be able to move, hunt, reproduce and all the other little things that make up a living creature. Anybody can make an MB that just forms a huge mat of DarwinBots then just sits there until it runs out of energy. What we are going to attempt to make here is an organism that is capable of thriving and reproducing as an MB.

To start off with, we will try a simple 2-cell MB that hunts with ties. We will give it a 2 stage life cycle so that a small juvenile form can zip around the screen eating veggies until he gains enough energy to become an adult MB. Once it becomes an MB it will continue to feed and grow until it gives birth to a new juvenile.


First of all, I would like to introduce you to Multi-Bot 1

' Multi-Bot 1

cond

  • .eye2 *.eye8 !=

start

  • .eye2 *.eye8 sub .aimsx store

stop

cond

  • .eye4 *.eye6 !=

start

  • .eye4 *.eye6 sub .aimsx store

stop

cond

  • .refeye *.myeye =
  • .eye5 50 >

start 120 .aimsx store stop

cond

  • .vel 40 <

start 40 *.vel sub .up store stop

cond

  • .eye5 50 >
  • .refeye *.myeye !=
  • .eye4 *.eye6 %=
  • .eye5 77 !=

start 100 .tie store stop

cond

  • .numties 0 >

start -1000 .tieval store -1 .tieloc store 100 .tienum store stop

end


He is a basic tie feeder based on a modified version of Tie-Bot 4. Should be a good starting point for a simple (well reasonably simple anyway) Multi-Bot.



cond

  • .waste 100 >

start

  • .waste .shootval store

-4 .shoot store stop


So.. How is Multi-Bot going to reproduce then? Well first we need a fairly high threshold so that he can make a good strong MB so we will set it to around 10,000.

cond

  • .nrg 10000 >
  • .numties 0 =

start 50 .repro store stop

Notice that I also included a condition to prevent him from reproducing if he has any ties present.


cond

  • .robage 0 =

start 1 .tie store stop

We also need to add a bunch of conditions such that the robot behaves differently when he is a juvenile and when he is an adult. We will do that in a minute but first you should save Multi-Bot 3 and give him a test drive.



First up we will make sure that our existing movement gene can only be activated by a juvenile. Add this line to the movement genes condition step.

  • 50 0 =

Next we will add a line into the repro gene to change the identity of the adult as soon as it reproduces.

1 50 store


' Program offspring cond

  • 50 1 =
  • .numties 1 =

start 2 50 store 1 .tienum store 50 .tieloc store 3 .tieval store stop


Try this out as Multi-Bot 4 (or just load up Multi-Bot 4.txt) Start up the SIM and follow one of our juveniles till he reaches 10000 energy to see what happens.


How do we fix this then? It is obvious that despite our careful planning, the parent is attempting to program the young before the tie is fully registering on either of their senses. Daddy is going up to state 2 (head) before junior becomes state 3 (tail).

Well one way to fix it is to take out the *.numties condition which returns a non zero value for any tie and be a little more specific by using *.tiepres 1 = to make sure that daddy only does his stuff when he detects a #1 tie.



Found it yet?


Try changing the *.numties condition in the feeding gene with another *.tiepres only this time make it conditional on being equal to 100 (the feeding tie). (Check out Multi-Bot 6.txt to see what happens now.)

Well that is much more like it. Now they just join together and float there. No genes ever get activated at all unless a veg or a juvenile Multi-Bot happen to pass by.

But what use is a Multi-Bot that just sits there doing nothing?



Now what?





cond

  • .multi 1 =
  • 50 2 =

start 1 .tienum store .fixang .tieloc store 628 .tieval store 628 .fixang store stop

Save the robot as Multi-Bot 7.txt (or just load up the demo model) and check it out.


The answer is a bit tricky to figure out.


Well that is our problem!


So how are we going to do it then?



.fixang .tieloc store


51 .tieloc store


So how is that going to help?

It will be a trigger for the gene that we are about to add. As I said, we are going to make the young robot program himself. Add this gene just before the last gene and save your robot as Multi-Bot 8.txt (or not since I have provided you with a ready made copy of this robot)

cond

  • .multi 1 =
  • 51 0 !=

start 1 .tienum store

  • 51 .fixang store

0 51 store stop



4 50 store

to the action step. This is to prevent that gene being activated forever too. Give Multi-Bot 8 a trial run to see if he behaves properly. We should end up with a 2 robot MB in which they both face directly away from each other.


Go back and change the 628 .fixang store line to 628 51 store. Now we are just programming memory location 51 in both robots so they will both rotate in the following cycle Try it both ways if you like but only the latter will work properly. Why is that? you ask.


(Anyway, a working version is available as Multi-Bot 8.txt)


Here is what we are going to do.


Add this gene somewhere in the middle of the genome. It will need to go before the feeding gene or the feeding mechanism will be overwritten by the move control.

' Move the multi-Bot cond

  • .multi 1 =
  • 50 4 =
  • .eye5 35 <
  • 51 0 =

start 1 .tienum store .up .tieloc store -2 .tieval store stop


This one is known as Multi-Bot 9.txt


And another thing is that the head seems to be getting all the food while the poor little tail who is actually doing all the work, gets pretty much nothing.


cond

  • .multi 1 =
  • .nrg *.trefnrg !%=

start 50 .sharenrg store stop


1 .readtie store

Or load up Multi-Bot 10.txt



  • .numties 1 =

That should disable sharing while Multi-Bot is feeding but still allow the other end to take a little of the energy as soon as their levels are uneven. And another thing! Have you noticed that sometimes there will be a single Multi-Bot unit floating around and not actively moving, hunting or anything for that matter? Sometimes it is inevitable that one end of the MB is going to die or the reproduction process will fail.. or something. In such a case it is easy to get a disembodied head or tail that simply has nowhere to go. So how can we fix that then? Try adding this gene.

' Resets lonely MB parts to juveniles cond

  • .numties 0 =
  • 50 1 >

start 0 50 store stop

We have to use a condition in which *50 is greater than 1 due to the fact that it takes a full cycle for *.numties to register anything. If we make the line read *50 0 > then we will get a load of juveniles tying together and pulling like heck on a bright yellow (sharing) tie. Try it and see. A working version of Multi-Bot 12.txt is included and will demonstrate this next stage of our MB



  • .vel 20 <

aught to do it.

We also have to address reproduction at some point too. How are we going to do that I wonder? Our young robots automatically attach themselves to the parent for one thing ,and secondly only a juvenile is able to reproduce right now.


First up we need a gene to allow a tail to reproduce as soon as it reaches a total energy level of about 8000 or so. That should be easy enough to do.

Just add these two genes to the robot and save it as Multi-Bot 13 ' Reproduce as a tail cond

  • .nrg 10000 >
  • .numties 1 =
  • 50 3 =

start 30 .repro store stop

' Delete tie as a new juvenile cond

  • .tiepres 1 =
  • 50 0 =
  • .robage 5 =

start 1 .deltie store stop

Or just load up Multi-Bot 13.txt

Give him a run and see how cool he is now.


One last improvement that we could make is stop that stretching and shrinking that he does. The way to do that is to put a value into the command .stifftie. This is a brand new control for version 2.31. It has a range of 0 to 40 and only has to be entered once. The DarwinBot will remember it for the rest of his life, or at least until it is overwritten. Go ahead and place this line into the initialization gene..

30 .stifftie store

or load up Multi-Bot 14.txt if you prefer.

Do you like that any better. They move a little slower now but at least they are much more controllable

Now why not see if you can figure out how to make an MB yourself?





APPENDIX 1 The system variables.

Function means that it read back a value and cannot be permanently changed from DNA Command means that a value must be stored into this location in order to make the robot do something.

Memory position Variable name Other information 1 up Command 2 dn Command 3 sx Command 4 dx Command 5 aimdx Command 6 aimsx Command 7 shoot Command 8 shootval Command 9 robage Function. Always renewed 10 mass Function. Always renewed 11 maxvel Function. Always renewed 18 aim Function. Always renewed 501 eye1 Function. Always renewed 502 eye2 Function. Always renewed 503 eye3 Function. Always renewed 504 eye4 Function. Always renewed 505 eye5 Function. Always renewed 506 eye6 Function. Always renewed 507 eye7 Function. Always renewed 508 eye8 Function. Always renewed 509 eye9 Function. Always renewed 200 vel Function. Always renewed 203 pain Function. Always renewed 204 pleas Function. Always renewed 205 hitup Function. Always renewed 206 hitdn Function. Always renewed 207 hitdx Function. Always renewed 208 hitsx Function. Always renewed 210 shup Function. Always renewed 211 shdn Function. Always renewed 212 shdx Function. Always renewed 213 shsx Function. Always renewed 214 edge Function. Always renewed 215 fixed Function. Always renewed 216 fixpos Command 217 depth, ypos Function. Always renewed 218 daytime Function. Always renewed 219 xpos Function. Always renewed 300 repro Command 301 mrepro Command 302 sexrepro Command 310 nrg Function. Always renewed 311 body Function. Always renewed 312 fdbody Command 313 strbody Command 314 setboy Command 315 rdboy Function. Always renewed 330 tie Command 331 stifftie Command 701 refup Function. Conditionally renewed 702 refdn Function. Conditionally renewed 703 refsx Function. Conditionally renewed 704 refdx Function. Conditionally renewed 705 refaimdx Function. Conditionally renewed 706 refaimsx Function. Conditionally renewed 707 refshoot Function. Conditionally renewed 708 refeye Function. Conditionally renewed 709 refnrg Function. Conditionally renewed 710 refage Function. Conditionally renewed 711 refaim Function. Conditionally renewed 712 reftie Function. Conditionally renewed 713 refpoison Function. Conditionally renewed 714 refvenom Function. Conditionally renewed 721 myup Function. Fixed at birth 722 mydn Function. Fixed at birth 723 mysx Function. Fixed at birth 724 mydx Function. Fixed at birth 725 myaimdx Function. Fixed at birth 726 myaimsx Function. Fixed at birth 727 myshoot Function. Fixed at birth 728 myeye Function. Fixed at birth 729 myties Function. Fixed at birth 730 mypoison Function. Fixed at birth 731 myvenom Function. Fixed at birth 800 out1 Function. Conditionally renewed 801 out2 Function. Conditionally renewed 810 in1 Memory storage location 811 in2 Memory storage location 820 mkslime Command 821 slime Function. Always renewed 822 mkshell Command 823 shell Function. Always renewed 824 strvenom Command 825 venom Function. Always renewed 826 strpoison Command 827 poison Function. Always renewed 828 waste Function. Always renewed 829 pwaste Function. Always renewed 830 sharenrg Command 831 sharewaste Command 832 shareshell Command 833 shareslime Command 400 sun Function. Always renewed 450 tieang Command 451 tielen Command 452 tieloc Command 453 tieval Command 454 tiepres Function. Conditionally renewed 455 tienum Command 456 trefup Function. Conditionally renewed 457 trefdn Function. Conditionally renewed 458 trefsx Function. Conditionally renewed 459 trefdx Function. Conditionally renewed 460 trefaimdx Function. Conditionally renewed 461 trefaimsx Function. Conditionally renewed 462 trefshoot Function. Conditionally renewed 463 trefeye Function. Conditionally renewed 464 refnrg Function. Conditionally renewed 465 trefage Function. Conditionally renewed 466 numties Function. Always renewed 467 deltie Command 468 fixang Command 469 fixlen Command 470 multi Function. Always renewed 471 readtie Command 472 trefbody Function. Conditionally renewed 473 memval Function. Conditionally renewed 474 memloc Command 475 tmemval Function. Conditionally renewed 476 tmemloc Command 477 reffixed Function. Conditionally renewed 478 treffixed Function. Conditionally renewed 900 backshot Command








APPENDIX 2 How the eye cells really work.



He is obviously facing to the right and as you can see, eye5 is pointing directly along the axis of his aim. Each of the eyes covers an arc of 10 degrees giving him a total vision angle of 90 degrees. In the program, robots that are far away only take up a single eye-cell while robots that are closer than about 2 robot widths away, take up 3 eye-cells.

Table 1, below shows the approximate angle of each eye cell away from the central axis.

Table 1




APPENDIX 3 The full explanations.

In this section, we take each command and function then fully explain their use within the DarwinBot DNA language. Each of the commands or functions relates directly to a specific memory location within the DarwinBot. The total memory consists of 1000 different locations. Think of the commands or functions as convenient, but unnecessary labels. You could just use the numbers if you wanted to. A full list of the DNA commands and functions can be found in Appendix 1.


The movement commands .up .dn .sx .dx

Description: The movement commands are part of the heart of the DarwinBots DNA language. Without these, there could be no movement. The movement commands are simple to implement but even these can take a little understanding to use properly. All four relate to vector acceleration rather than actual movement. The direction of the vector acceleration is defined by the direction in which the DarwinBot is facing when the command is carried out.

.up accelerates the robot forward in the direction that he is facing. .dn accelerates the robot backward from the direction he is facing.


Example:

cond start 10 .up store stop

A robot with this gene would constantly accelerate forward at a rate of 10 per turn. That is to say that his forward velocity would increase by a value of 10. If he should rotate then the direction in which the acceleration takes place would also change.

Input values:

Prior to actual movement of the DarwinBot the values in .up .dn .sx and .dx are all added together such that a negative .up and a positive .dn will add to make a larger acceleration in the .dn direction and a positive .up and a positive .dn, of equal magnitude, will cancel each other out. Next, these accelerations are added to any existing accelerations due to the actions of ties and repulsion fields (when robots get too close together). Finally, the accelerations are converted to X and Y vectors and applied to the DarwinBot by adding them to existing velocities in the X and Y directions. The total velocity cannot exceed 40 units per cycle so any excess is then lost.

Costs: Energy costs to the DarwinBot are calculated based on the input values. These vary with robot mass and applied acceleration but cannot exceed 100 energy points per vector per cycle.

Activation hierarchy: Movement commands are executed after rotation commands

Associated Keywords: .aimsx .aimdx .vel


Rotation Commands: .aimsx .aimdx

Description: These commands change the orientation angle of the DarwinBot. When a value is stored into either of these memory locations, the DarwinBot rotates on his own axis through an angle proportional to the input value.

.aimsx rotates the DarwinBot anti-clockwise while .aimdx rotates the DarwinBot clockwise. One full rotation is equal to 1256 units in either direction. One half rotation is equal to 628 units in either direction. One quarter turn is equal to 314 units.

Example:

Cond

  • .eye5 0 =

start 100 .aimdx store stop

A DarwinBot using this gene will continuously rotate clockwise as long as he never sees anything in front of him. As soon as he does see something right in front of him, he will cease to rotate.

Costs:


Activation hierarchy: The rotate commands are among the first things done during each cycle. They are carried out before movement, ties and shots. You need to be aware of this while programming a robot. If it should turn and fire in the same cycle, it will probably miss its target.

Associated Keywords: .up .dn .sx .dx .aim .refaim .fixang .tieang


Information about self (functions): This is a large group of very useful read-backs that allow the robot to act based on information about his own health, orientation etc. The complete list of these commands is as follows

.robage, .aim, .vel, .pain, .pleas, .hitup, .hitdn, .hitsx, .hitdx, .shup, .shdn, .shsx, .shdx, .edge, .fixed, .depth, .daytime, .nrg, .body, .rdboy, .slime, .shell, .venom, .poison, .waste, .pwaste, .myaimsx, .myaimdx, .myshoot, .myties, .myup, .mydn, .mysx, .mydx, .myeye, .mypoison, .myvenom

These functions give the robot a sometimes-bewildering array of things that he can sense about himself. Each of them will be addressed individually over the next few pages.

.robage: Description:


Example: cond

 *.robage 0 =

start

 1 .tie store

stop


Costs: No cost is involved with reading .robage.

Activation hierarchy: Function are invoked at the end of each cycle. They are the last things done other than reproduction.

Associated keywords: .refage


.aim: Description:

0 = facing to the right 314 = facing straight up 628 = facing to the left 942 = facing straight down 1255 = facing (almost) to the right

Example: cond

 *.aim 942 %=

start

 628 .aimdx store

stop

This example could be used in a DarwinBot to stop him from heading downward too much in the pond. As soon as he finds himself heading almost downward he will do an about turn and head up again. Very useful if the veggies are floating at the top of the pond.

Cost: No cost is involved with reading .aim.

Activation hierarchy: Function are invoked at the end of each cycle. They are the last things done other than reproduction.

Associated keywords: .refaim, .aimdx, .aimsx, .refaimdx, .refaimsx, .ownaimdx, .ownaimsx


.vel: Description:


Example: cond

 *.vel 20 <

start

 5 .up store

stop

In this example the DarwinBot checks to see how fast he is traveling and if it is found to be less than 20, he accelerates forward by 5 points. If he finds himself moving at a velocity of 20 or more then he will do nothing. This kind of gene can be extremely useful to conserve energy, especially in Kinetic Energy mode the cost of moving at higher speeds rises exponentially.

Cost: No cost is involved with reading .vel.

Activation hierarchy: Function are invoked at the end of each cycle. They are the last things done other than reproduction.

Associated keywords: .up, .dn, .dx, .sx

.pain, .pleas: Description:


Example: cond

 *.pleas 100 >

start

 80 .repro store

stop

In this example the DarwinBot checks to see if he is currently gaining energy. If he has gained more than 100 points then he assumes that food must be plentiful so he reproduces and gives a large chunk of his energy to his offspring.

Cost: No cost is involved with reading .pain or .pleas.

Activation hierarchy: Function are invoked at the end of each cycle. They are the last things done other than reproduction.

Associated keywords: .nrg, .refnrg


.hitup, .hitdn, .hitdx, .hitsx: Description: These functions only return a value when the DarwinBot collides with something. .hitup returns a 1 when the DarwinBot is hit from the front. .hitdn returns a 1 when he is hit from the back. .hitsx returns a 1 when he is hit from the left and .hitdx returns a 1 when he is hit from the right.

Example: cond

 *.hitdn 1 =

start

 628 .aimdx store

stop

In this example the DarwinBot checks to see if he has been hit from behind. If he has then he will spin to face his attacker.

Cost: No cost is involved with reading .hitup, .hitdn, .hitsx or .hitdx.

Activation hierarchy: Function are invoked at the end of each cycle. They are the last things done other than reproduction.

Associated keywords: .shup, .shdn, .shsx, .shdx.


.shup, .shdn, .shdx, .shsx: Description: These functions only return a value when the DarwinBot is shot by something. .shup returns a value when the DarwinBot is shot from the front. .shdn returns a value when he is shot from the back. .shsx returns a value when he is shot from the left and .shdx returns a value when he is shot from the right. The main difference from the collision checks is that these functions return the value of the shot that hits the DarwinBot.

Example: cond

 *.shdn -1 =

start

 628 .aimdx store

stop


Cost: No cost is involved with reading .hitup, .hitdn, .hitsx or .hitdx.

Activation hierarchy: Function are invoked at the end of each cycle. They are the last things done other than reproduction.

Associated keywords: .hitup, .hitdn, .hitsx, .hitdx.




To be completed later I figured it was better to put an incomplete tutorial our rather than make everyone wait for ages without one.