Tutorial C++

Teniendo en cuenta que el desarrollo del código es en el lenguaje C++ y en base a un un Diseño Orientada a Objetos, se detallan a continuación los lineamientos generales de las clases que forman parte del programa de vida artificial.
Existe una clase a partir de la cual el concursante deberá desarrollar el método propio de supervivencia de sus microorganismos. Hay otras clases de las cuales se crearán objetos que serán de los organizadores del encuentro y que el concursante no podrá modificar. Algunos de estos objetos estarán accesibles para que los microorganismos pueden obtener datos útiles en el momento de tomar decisiones estratégicas.

Diseño

El siguiente diagrama simplificado de las clases muestra el modelo del “Competidor1” y del “Competidor2”, que son las clases de los microorganismos desarrollados por los competidores a partir de los cuales se realizarán las colonias. El método más importante es move. La energía o alimento para los MO es administrada por la clase Agar y la determinación de las relaciones entre los microorganismos las resuelve Petri.

DOO.jpg

La clase Microorganismo

Esta clase declara los métodos básicos del comportamiento, de la cual deberá heredar el MO concursante.

MO.jpg

En la clase descendiente que debe desarrollar el concursante, a través del método move le indicará a colonia a donde quiere moverse cuando sea su turno.
Cuando la colonia invoca el método mitosis del microorganismo, este indica si se quiere dividir en dos. El método update es desde donde recibe el identificador (id) con el cual está compitiendo, sus coordenadas y energía antes de pedir que devuelva el movimiento deseado, es decir que estos atributos del MO le son informados. Este método update es implementado únicamente en la clase madre Microorganismo por lo que no es necesario que el competidor lo redefina en su MO.

El siguiente código es un ejemplo simple de la clase de un microorganismo creado para la competencia. Se llamó BuscaN porque su estrategia simplemente consiste en moverse al casillero de su entorno que posea más nutrientes.

#ifndef BUSCAN_H
#define BUSCAN_H

#include "defs.h"
#include "microorg.h"
#include "agar.h"
class BuscaN: public Microorganismo
{ public:
    virtual string nombre();
    virtual string autor();
    virtual void move(Movimiento & mov);
    virtual void mitosis(bool & dup);
};
string BuscaN::nombre()
{ return("Busca Nutrientes"); }

string BuscaN::autor()
{ return("Compu2"); }

void BuscaN::move(Movimiento & mov)
{ se moverá a una de las 8 posiciones vecinas con más alimento

  int x_rel, y_rel; //posición relativa de prueba.
  int x_max, y_max; posición relativa con más nutrientes.

  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.nutrientes(pos.x+x_rel,pos.y+y_rel) > agar.nutrientes(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 BuscaN::mitosis(bool & dup)
{ if (ene>5000)
    dup=true;
  else
    dup=false;
}

#endif //BUSCAN_H

A través de agar.nutrientes() se pide colaboración al agar para conocer la cantidad de nutrientes que hay en cualquier posición de la cápsula de Petri.
En este caso se implementó una mitosis tan simple como: “si el MO tiene más de 5000 unidades de energía entonces pide dividirse”
Este MO es muy simple debido a que solamente considera la posición donde hay más nutrientes y no tiene en cuenta las posiciones de los enemigos, ni las de su propia colonia. Algoritmos más desarrollados podrán hacer uso de más información para conseguir estrategias más efectivas. Por ejemplo la de realizar mitosis de acuerdo a la cantidad de nutrientes disponibles, atacar a los MO contrarios, buscar y conservar copadas las regiones con más nutrientes, etc.

La clase Agar

Agar.jpg

Esta es una clase muy importante para el competidor. El agar es el medio de cultivo del que se alimentan los MO y sirve de intercambio de información (colaboraciones). Los MO pueden preguntarle al objeto agar alguna información de su interés de cualquier posición (como se vió en el ejemplo anterior). Para conocer algunos métodos puestos a disposición por la clase Agar, supongamos que algún MO quiera conocer datos en las coordenadas x=10, y=20.

  • Mensaje para obtener la cantidad de nutrientes:
agar.nutrientes(10,20);
  • Para obtener la energía del MO que ocupa esa posición:
agar.energia (10,20);

Hay que tener en cuenta que es agar quien administra la energía de cada MO y no cada MO internamente. A través del método update() del MO se actualiza el atributo ene (energía) en forma automática.
  • Mensaje para obtener la identidad (o tipo) de un MO:
agar.ocupacion (10,20);

Este método devuelve un identificador (número entero). El identificador del MO que está compitiendo es conocido a través del atributo id asignado por petri y comunicado a los MO a través del método update(). Si el identificado devuelto por ocupacion() es igual al ID propio entonces se trata de un MO de la misma colonia. Si el identificador es direfente entonces el MO que ocupa esa posición es de una colonia enemiga.
La posición y la energía actual del MO están siempre actualizadas en sus variables internas pos y ene (esto se hace siempre desde la clase Colonia antes de llamar al método move). Mediante el método move el competidor simplemente debe devolver, a través del parámetro por referencia mov, el movimiento relativo que quiere realizar.
Si por ejemplo se quiere desarrollar una estrategia que tenga en cuenta a los MO adversarios, se podrá hacer preguntas como las siguientes:

if (id != agar.ocupacion(miX+1,miY))
{ //tomará acción con el adversario que está a la derecha
  if (ene > agar.energia(miX+1,miY))
  { // tomará acción a partir de las energías, por ejemplo: luchar
  }
}

La clase Colony

Esta clase contendrá un conjunto de microorganismos de una misma especie o competidor. Se encarga de mover los microorganismos cuando el objeto petri lo requiera. El MO diseñado por el competidor no tiene acceso a esta clase pero está disponible su código fuente para conocer mejor el funcionamiento de la competencia.
Colony.jpg

La clase Petri

La competencia se desarrolla en la cápsula de Petri, que aplica las reglas de convivencia de los MO.
Para cada movimiento, los MO son ordenados al azar y luego se va solicitando a cada uno el movimiento deseado y si quiere dividirse (mitosis). Con cada movimiento se actualiza el agar, o sea que siempre van a esta viendo en agar lo que realmente va a haber al momento de realizar su movimiento.

Cuando la colonia solicita a cada MO que proponga su movimiento, la respuesta es analizada por Petri y entonces puede pasar que:
1) El lugar esté vacío y dentro de los límites de la cápsula: el movimiento será realizado por Petri.
2) El lugar esté ocupado por un MO de otra colonia: se origina una lucha. En una lucha gana el que tiene mayor energía pero el ganador no mata simplemente al perdedor sino que le quita una cantidad de energía igual a la diferencia de energía entre ambos. Si después de esto el perdedor quedara con energía menor a cero entonces sí se muere. Ambos quedan en el mismo lugar que estaban antes de la lucha y el ganador incrementa su energía en un 7.5% de la que tenga el perdedor.
En caso de que se solicite una división mediante mitosis, la reproducción tendrá éxito siempre que exista un lugar libre para poner al hijo en alguna de las 8 celdas adyacentes. Se busca un lugar vacío al rededor recorriendo las celdas con un orden al azar y si hay lugar se crea al hijo en ese lugar y ambos (padre e hijo) quedan con el 49% de la energía original del padre.

Otras reglas que se aplican siempre son:

  • De cada colonia nacen inicialmente 50 MO con 1000 unidades de energía cada uno y en posiciones al azar.
  • Todos los MO pierden 5 unidades de energía (por envejecimiento) en cada unidad de tiempo.
  • Cuando un MO se mueve pierde 10 unidades de energía (por el esfuerzo).
  • Todos los MO comen (incrementan su energía) en un 1% de los nutrientes que exista en su posición.

La distribución inicial de energía y la forma en que podrían variar los nutrientes en la superficie a medida que se desarrolla la competencia será elegida por los árbitros en cada encuentro. Hay varias distribuciones y habrá una batalla en cada una ellas.

Por ejemplo, en el gráfico siguiente se muestra una distribución de nutrientes con dos picos (distribución gaussiana bidimensional) donde en este caso en particular la conquista y permanencia de una colonia en las zonas de mayor energía otorgaría una importante ventaja.
Dibujo.bmp

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