C++ Tutorial

Given that the development of the code is in C++ and based on an Object Oriented Design, below are listed the general outlines of the classes that are part of the artificial life program.
There is a class from which the contestant must develop its own method of survival of their microorganisms. There are other classes which will create objects that will be own by the organizers and that the contestant cannot modify. Some of these objects will be accessible to microorganisms to obtain useful data when making strategic decisions.

Design

The following simplified class diagram shows "Competitor1" and "Competitor2" models, which are the kinds of microorganisms developed by competitors from which colonies are made. The most important method is move. The energy or food for the MO is managed by the class Agar and the relationships between microorganisms are identified by Petri.

DOO.jpg

The Microorganism class

This class declares the basic behavior methods, from which each competitor MO should inherit.

MO.jpg

In the descendant class that must develop each competitor, it indicates to the colony through the move method where it wants to move.
When the colony invokes the microorganism method mitosis, this indicates whether the MO wants to be split in two. The update method is from where its competing identifier (id) is recieved, its coordinates and energy before asking to return the desired movement, that is to say, these MO attributes are informed. This method is implemented only in the class Microorganism, therefore it is not necessary to be redefined by the competitor in its MO.

The next code is a simple example of a microorganism created for the contest. It is named "SearchN" because its strategy just consists in moving to the neighborhood cell that has more food.

#ifndef SEARCHN_H
#define SEARCHN_H

#include "defs.h"
#include "microorg.h"
#include "agar.h"
class SearchN: public Microorganism
{ public:
    virtual string name();
    virtual string author();
    virtual void move(Movement & mov);
    virtual void mithosis(bool & dup);
};
string SearchN::name()
{ return("Search for Nutrients"); }

string SearchN::author()
{ return("Compu2"); }

void SearchN::move(Movement & mov)
{ it goes to one of the 8 neighborhood cells having more food

  int x_rel, y_rel; //relative test position.
  int x_max, y_max; //relative position with more nutrients.

  x_max=0;
  y_max=0;

  for (x_rel=-1; x_rel<2; x_rel++)
    for (y_rel=-1; y_rel<2; y_rel++)
      if (agar.nutrients(pos.x+x_rel,pos.y+y_rel) > agar.nutrients(pos.x+x_max,pos.y+y_max))
      {
        x_max=x_rel;
        y_max=y_rel;
      };

  mov.dx=x_max;
  mov.dy=y_max;
}

void SearchN::mithosis(bool & dup)
{ if (ene>5000)
    dup=true;
  else
    dup=false;
}

#endif //SEARCHN_H

Through agar.nutrients () cooperation is asked to the agar to determine the amount of nutrients in any position of the Petri dish.
In this case, a simple mithosis was implemented: "if the MO has more than 5000 units of energy, then divide".
This MO is simple because it only considers the position where there are more nutrients and does not take into account the enemies positions, or those of their own colony. More developed algorithms may use more information to achieve more effective strategies. For example, performing mithosis according to the amount of available nutrients, attacking the enemy MOs, finding and maintaining occupated regions with more nutrients, etc.

The Agar class

Agar.jpg

This is a very important class for the competitor. Agar is the medium from which MOs are fed and serves for information exchange (partnerships). The MOs can ask the agar some information from any position (as shown in the example above). For example, suppose you want to know some data in the coordinates x = 10, y = 20.

  • Message for obtaining the nutrients amount in that position:
agar.nutrients(10,20);
  • To obtain the energy of the MO that is in that position:
agar.energy (10,20);

It has to be taken into account that agar manages each MO energy level. Though the update() method, each MO updates automatically the energy attribute.
  • Message to obtain the identity (or type) of a MO:
agar.ocupacion (10,20);

This method returns an identifier (integer). The MO identifier is known throughout the id attribute assigned by Petri and communicated to the MOs through the update () method. If the returned ID found by occupation () equals the own ID, then it is a MO from the same colony. If the identifier is the different, then that position is occiped by a enemy colony.
The current position and energy of the MO are always updated in its internal variables pos and ene (this is always done from the colony class before calling the move method). The mehtod move must return, through the reference parameter mov, the relative movement that it wants to do.
If for example you want to develop a strategy that takes into account the adversaries MOs, questions such as this one can be made:

if (id != agar.ocupacion(miX+1,miY))
{ //take action to an enemy at right position
  if (ene > agar.energia(miX+1,miY))
  { //take action from the energies, for example, to fight
  }
}

The Colony class

This class will have a set of organisms within a same species or competitor. It is responsible for moving organisms when the petri object requires it. The MO designed by a competitor does not have access to this class but its source code is available to better understand the competition functioning.
Colony.jpg

The Petri class

The MOs life takes place at a simulated Petri dish. This world model is defined as a container class Petri where the rules of life are applied. This set of rules verifies the validity of the movements required by every MO. The MOs are randomly ordered and then, from each of them, an action is requested and whether they want to reproduce themselves or not. After each agent action, the Agar is updated, therefore the MOs can “see”, during all the simulation, an updated version of the
environment, which is totally accessible for reading.

According to the rules of the artificial life simulation, the MOs may feed, fight or procreate. The main rules are the following:

1) The position is empty and it is inside the Petri dish: Petri allows it and moves the MO.
2) The position is occupied by a MO belonging to the opposite colony:: then the MOs fight and the one whose energy level is higher survives. The winner
does not simply kills the looser, but an amount of
energy is taken which is equal to the difference of
energy between them. If the looser remains with
an energy level minor to zero, it then dies. After
the fight, both MOs remain in the same previous
position and the winner increments its energy in a
7.5% level regarding the looser. If mithosis is requested: It could
take place if there is a free adjacent place in some of the 8 neighborhood cells to put the
new MO, and the father and the son remain with an
energy equal to the 49% of the father energy.

Other rules are:

  • Initially, 50 MOs of each colony are created, with 1000 energy units.
  • The MOs are all randomly positioned inside the Petri dish.
  • Every MO looses 5 energy units per time unit due to aging, and it wastes 10 energy units for each movement.
  • Every time step, all MOs increase their energy by feeding with 1% of the nutrients existing in their current position.

The initial energy distribution and how the nutrients vary in the surface as the competition takes place will be chosen by the referees in every meeting. There are many distributions and there will be a battle in each.

For example, the chart below shows a nutrients distribution with two peaks (two-dimensional Gaussian distribution) where in this particular case, the conquest and permanence of a colony in the areas of higher energy would provide a significant advantage.

Dibujo.bmp
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License