This is the project I did in VB.NET because doing visuals in a console application wouldn’t work too well, I knew VB.NET, and VB.NET has some simple and easy to use drawing capabilities. I say simple because I’m not an artist and not much beyond circles is needed to illustrate the point of the project. For the code, I include the class and code behind I used for the project.
Ant Food Gathering Code
This program is a very simple representation involving a drawing plane and different colored circles. So the GUI of this program is a picturebox, some text boxes to change the properties, and a start button. What is being used is fairly simple and can be easily picked out of the code (I hope), so I’m not going to go into detail on any of that since this is about programming.
So in the worddoc, the first section of code is the code behind of the form in the program. I setup my global variables for the brushes and initialize the drawing surfaces in the AntSim_Load function. In the code for the Start button click event, it is simply pulling the input for the different properties from the GUI text boxes and then starting the timer. The timer goes off at a set interval which updates our little ant world.
Every time we update, the ant world gets updated through the world class and then everything is drawn to the picturebox. The food, ant’s and home base are straight forward, we just see the x and y coordinates where they are located and draw them. If the ant has food, we draw a colored circle to show this. If the food mounds are out of food, we stop drawing them. The pheromone sprays are the same, except scaled down. So if our picturebox is 100×100, the pheromone bounds are 25×25 and I just multiply by 4. This cuts down on processing while looping through and checking which pheromone cells are active. It also keeps everything in a nice grid so pheromones don’t overlap and look like a giant blob and there is no need to create or delete pheromones, simply setting them to active or invisible. This was an easier transition from the previous artificial life projects which involved cells.
Next is the world class. This class takes care of everything within the ant world so that from the form code behind we only have to call one function and draw the results. The class constructor takes input of the length and width of the picturebox being used, the number of ants we want, the number of food nodes, and how much food is in each food node, then initializes all of these elements. The NextStep does just that, takes the world of ants to the next generation. All this function does is do the NextStep functions for each ant, pheromone, and food node. Then the class has get and set properties for each variable that might need to be accessed.
The ant class is where most of the action takes place, with each ant being his own agent in the world. The ant class has 2 enums, the AntState and Directions, defining which states the ant can be in and directions it is possible to move. Then there are the various variables used for the class, the most interesting being the hisWorld variable. This is the only value passed into the constructor, allowing the ant to store and be aware of the world he is in by a World class reference value. Of course this is passed by reference so he is seeing the world he is actually in all the time, rather than a copy of the world if we used by value. All ants in this world begin their life searching for food.
In the NextStep function, we see which state the ant is in and do certain actions for each and at the end, move the ant. In the Search state, we randomly decide of the ant should change which direction he is moving, which allows the ant to move in straight lines rather than turning all the time. Next we check for food and pheromone in the current cell he is in to see if he should head home with his food or chase the pheromones. If the ant is heading home with food he has, he should lay a pheromone trail for other ants to follow. When he reaches home, he drops the food and continues searching. If he has found some pheromones, then he chases that to the food.
In order to find food, the ant has to be aware of his world. In the FindFood function, he looks around the world and sees if any of the food nodes are near enough for him to take a chunk of the food home. When he takes the food, he sets off a pheromone burst to mark the food and because he is so excited he found food. We use functions to check the distance to the food, remove some food from the food node, set his new X, Y cooridates for his target destination, and then trigger the pheromone burst. I think these are fairly self explanatory functions and variable changes.
The FindPhero function is how the ant looks for nearby pheromones. First a search range is set, which is the ants current location +-5 in each direction, divided by 4 to fall within the pheromone grid range and makes sure the values fall within a valid range. Then it checks the pheromone grid for active pheromones within that range, converts it back to the normal grid size, and checks to see if the ant is actually within range of the active pheromone. Then it stores the first and second strongest pheromones in order to move the ant towards the food, rather than randomly following the pheromone either to home or the food. Now, in my program, I made it so that the ants might not detect the pheromone. He might not pick up the smell, so I gave a random chance to not detect the pheromone if the pheromone strength was below a certain threshold. Then the ant takes actions to either chase the pheromone towards the food or keep searching. And if the ant is near food, he should just go for it.
The move function is fairly simple at this point. If the ant move state is Self, it means it isn’t moving, so we use the same searching as the nextStep function. Any other move state, we simple move the X or Y coordinates 1 space in the proper direction. Then we make sure the ant is still within the world and correct it as needed.
The TargetDir function gets which direction the current target is located. So it does coordinate comparisons from the ant and target to find the needed direction.
Finally is the Distance function which is the good ol’ math distance formula and some properties to be used from the World class as needed.
Now the Pheromone class is similar to the Ant class, with variables, get and set methods, etc. The class only has 3 unqiue functions starting with the nextStep function. This nextStep function just increments a ticker which represents the amount of time the pheromone has been active. If the pheromone has been active too long, it fades away. I added a chance for the pheromone to linger after its time so that all the pheromones set at the same time don’t all disappear at the same time.
The InitialBurst function is what happens when the ant first finds food. It gets excited and kinda goes crazy to let his buddies know where some food is located. We setup the pheromone strength max and radius of the burst, making sure the radius is within our world limits. Then we set all the pheromones within the burst radius, setting each range of pheromones separately. The pheromones closest to the food are the strongest, but don’t last as long due to their strength. The strength fades the farther away, but the duration increases.
Finally is the trail function. This function activates the pheromones along the way back to home base. The trail pheromones all last the same amount of time, so the first created is the first to disappear. The strength of the pheromone uses the ant’s trail tick value, which increases as it moves along, in order to create a trail that can be followed. So the trail tick value is subtracted from the strength value each time, so that as the trail time increases, the strength of the pheromone decreases. This makes sure that the trail will lead other ants to the food rather than back home.
Last is the Food class, which really doesn’t do much on its own other than sit there. When an ant collects some food from it, it decreases its food amount. That is it.
Artificial Life programming was one of the most interesting and enlightening classes I took while getting my degree. I just want to thank my teacher Phil for presenting the subject in an easy-to-learn fashion and teaching the class in the first place. This post finishes all I wanted to post about artificial life programming at the moment, but I may come back to it later.