Tie Feeder Tutorial
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
Available as Tie-Bot1.txt
You will notice pretty quickly that he doesn't actually fire ties yet. Come to that he doesn't do much of anything really.
I have made him this simple to demonstrate an alternative method of using the eye cells to search for food. Notice that all we do is compare the two eye cells either side of *.eye5 (straight ahead), then actually store the resulting difference into .aimsx (rotate left).
This method gives an almost infinitely variable rotation value rather than fixed amounts as used in Simplebot. If Tie Bot 1 is much closer to something in *.eye4 than he is to something in *.eye6 then he will turn much more sharply than he would if they were more similar in value. If the two values are the same then he won't turn at all. Just run a simulation with Tie Bot 1 to see how well he finds food with only a single search gene. If you want to keep him alive a little longer then just add a shoot gene to the end of his genome. (I have already done this for you in Tie-Bot2.txt)
Stays alive pretty good doesn't he? There are a couple of things wrong with him still though. I don't mean the obvious lack of any kind of reproduction gene. I mean in the way he searches for food. Watch closely and you will see a lot of large turns performed while he is close to the food. This is because a slight change in the direction he is heading could result in one of the two eye cells reading upwards of 100 while the other reads nothing. Remember that one eye cell sees an arc of approximately 30 degrees so when very close to another robot, that robot will fill approximately 3 eye cells. That is why Tie Bot doesn't rotate when *.eye4 and *.eye6 are equal. It is assumed that *.eye5 will also contain an identical value. Remember this fact for later reference. It will be found to be extremely important. So Tie Bot 1 'wibbles' about a bit when he is close to food. Is that a problem? It actually doesn't seem to be although you might think it would be. For the moment we will let him carry on that way. 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. Let's add another search gene to correct that. This time we will use *.eye2 and *.eye8 to widen the search pattern. You could use any pairing you like or any number of genes with a pair in each but for now we will just use 2 and 8 along with the first gene. 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.
That's right. It has to go before the other search gene. We can only have one value in .aimsx for each cycle so we need to look at wide angle first then gradually narrow the field of vision so that small turns for close food take precedence over larger turns for outlying food. Load up Tie-Bot3.txt and try it out. Note that I have also addressed the 'wibble' behavior by dividing the value of the eye cell difference by 2 before storing it into .aimsx.
Let's add a simple reproduction gene and some kind of conspecific avoidance routine then let Tie-Bot4 run for a while. You will notice that it has become a spinner again. I have also added a condition to the movement gene so that he won't waste energy on needless acceleration while he is spinning. Not bad. He reaches 150 robots pretty quickly. 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. Why not modify Tie-Bot4 a little to see what would happen if you were to do either of those things. Just play around a little before you come back to see how I plan to fix this.
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.
I guess the next thing to do will be to actually make Tie Bot into a Tie-Bot as the first 4 generation haven't even tried to use ties yet.
Add the following gene to 'Tie Bot 4' or simply load up 'Tie-Bot5.txt' then run the simulation again.
cond start 1 .tie store stop
This is a really stupid gene but demonstrates some of the difficulties associated with tie feeders.
'Tie-Bot5' actually makes a reasonable basis for a simple Multi-Bot (MB) but more on that later. Notice the way that he ends up collecting 3 vegs and then drags them around the screen while shooting other vegs for food. Did you notice that I said 'shooting'? That's right. He isn't firing ties any more. Well actually he is still firing them but they aren't becoming attached to anything. That is because a robot can only have 3 ties at any one time so additional ties cannot become attached to him. A possible defense technique against other tie feeders?
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 10 eye cells so you will also need to change the other instances of .refeye to 10 as well.
cond *.eye5 30 > *.refeye 10 != 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. .tieloc is the location in the target robot which we wish to address through the tie. In order to exchange energy in either direction we need to use a value of -1 here. 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. Now add this gene to Tie Bot and give him a try. This is also available as 'Tie-Bot6.txt'
cond *.numties 0 > start -1 .tieloc store -1000 .tieval store *.tiepres .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.
As you will soon see, Tie Bot 6 doesn't work very well. There are red ties everywhere. I wonder why? 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 10. Click in the input window (the line at the bottom) of the console window and type in:
Make sure that you don't leave too many spaces and that the period (.) is present.
The console output window should now read:
? .refeye 708-> 0
Zero? That is a little strange isn't it. We know that the young one should have 10 eye cells just like his parent. The trouble is that the parent doesn't see the value in the first cycle after birth. The young one doesn't either. It takes one full cycle before any of the Ref Variables begin to register anything at all, even though the eye cells begin to work immediately. Another bug? Maybe but it is one that we will just have to live with because of the difficulty in fixing it. Believe me. I have tried. 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? Both of these solutions are possible and both have advantages and disadvantages. Deleting a tie is easy enough. Providing we know the ID code (.tienum value) of the tie. We just store that number into .deltie and all instances of that tie number are deleted from the robot. Sometimes we don't know the value though. In the case of Tie Bot 6 it would be simple because all ties have a value of 1 but sometimes it is an advantage to use a random number to address the ties that a robot fires. This number would be stored in a memory location of the robot in the first cycle of its existence using a gene such as
cond *.robage 0 = start 3198 rnd 2 add 55 store stop
This gene randomizes a number from zero to 3198 adds two then stores it into memory location 55 for later reference. The value can be used later to create and address ties as many times as necessary throughout the robots lifetime. There are many advantages to such a system. Let's add this to Tie Bot right now then come back to the problem above.
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. A better option would be to add a condition that would prevent either robot from firing while one of the Ref Variable is equal to zero. Since they are all zero during the first cycle of the young one's life, we could just as easily use any one. Let's take a look at the options that we could add.
*.refeye 0 !=
Would this work in addition to the other conditions in the tie-firing gene? No not really. It would certainly stop the problem of ties being shot in the first cycle after birth but it would also prevent ties being fired at vegs since they have no eye cells. The same thing would be true of almost all the Ref Variables- except for one.
*.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? Actually it wouldn't since we won't be allowing any ties to be fired at any robot that has no .aimdx commands anyway. It would be a problem if we were facing another robot that uses no .aimdx commands though wouldn't it?
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 !=
That should work OK. It will prevent ties being fired during that critical first cycle and won't really cause any problems elsewhere. Let's give it a try. Load up 'Tie-Bot7.txt' and run the sim. Note that all of the *.refeye functions now use 11 rather than 10. Also the addition of an initialize gene to put a random value into memory location 55 to be used as the ID number for ties. Sorted!! No more robots fixed together by red ties. Now the feeding takes place only when and where we want it to. 'Tie Bot 7' reached over 350 units in 1000 cycles when I tested it just now. It also beats Simplebot 16 pretty easily.
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 les effective than robots such as Devincio Eversor (also included in the tutorial directory). Try running Tie Bot 7 against Devincio Eversor 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. The easiest way is to add this line to the 'Initialize' gene:
and then to add an entirely new gene to follow it..
cond *.robage 1 = start .deltie inc stop
This combination forces the newly born robot to tie to its parent with a number 1 tie, then in the following cycle, to delete it again. This is a similar method to that used in Simplebot. This version of Tie Bot can be found as 'Tie-Bot8.txt' in the tutorial directory.
Tie Bot 8 still isn't perfect though. Sometimes we still get a couple of them tied together and attempting to feed from each other. The only way this can actually happen though is if both the robots are using the same .tienum value and the chances of that are 50:1 against. If the numbers (tie phase) are different then one or the other of the two robots will successfully feed from the other. We won't see this very often as the loser in such a conflict will die very quickly. The fact that we do see a few robots fixed together by red ties is an indicator that there must be something wrong with the tie targeting routine. They must be hitting each other by accident.
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.
First we can improve targeting by making sure that we are facing the target directly when we fire the tie. As we know, when a robot gets extremely close to a target, it sees it in up to 5 of its eyes. The present targeting routine only requires *.eye5 to be greater than 30 so Tie Bot doesn't really need to facing directly towards the target in order for him to fire his tie. How can we improve this I wonder? 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 =
While we are at it lets also add an extra condition to the reproduction gene so that we don't waste energy trying to reproduce when there isn't sufficient room. Try adding this line to the conditions of the reproduction gene.
*.eye5 30 <
That should give us enough room to reproduce. Don't forget to change all of the .refeye conditions.. Again.. There are 14 of them now. I am getting a little fed up with doing that every time we change something. Lets fix that once and for all. First we will add the following line to the 'Initialize' gene.. '!!!rework to add in myeye references
14 56 store
Then we will go through the whole genome and replace all of the .refeye condition numbers with *56. That way we will only have to change one value from now on when we add any eye cells. You can find this version of Tie Bot as 'Tie-Bot9.txt' in the tutorial directory.
Well Tie Bot 9 seems to work pretty good but it still does the same thing as before. We need to delete those ties I think.
OK then. Let's start by adding this line to the tie-firing gene..
*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 *56 = start *55 .deltie store stop
This gene checks to see how many eye cells the robot that we are currently tied to, has. If that value equals its own then the robot will delete the tie. Load up 'Tie-Bot10.txt' and give it a run. Now they don't eat each other any more. It worked! The overall efficiency has also improved. The population reaches around 370 now.
Let's try a contest against Devincio Eversor to see just how good Tie Bot is getting now.
Not that good really. Eversor easily wins still. But then again, Eversor has something that Tie Bot doesn't.. Slime..
Slime is one of the newer features that protects a robot from being hit by a tie. If you can't fix a tie to your target, you can't feed from it. Maybe we should add a slime gene to Tie Bot and try again. Let's try this one..
cond *.slime 90 < start 100 .mkslime store stop
You will find the new version as Tie-Bot11.txt Let's try again. This time it is a bit of a different story. Tie Bot 11 wins 4 out of 5 battles.
Slime actually reduces the overall efficiency but gives a tie feeder a much better fighting chance when facing others of similar persuasion. We fan now only reach a population of around 320.
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 beat Devincio Eversor is quite good enough for a tutorial. There are many ways to create a tie-feeding robot as good as Tie Bot 11 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.