Mundo Artificial Basado en Sistemas Evolutivos

Autor del sistema: Ma. Paola Neri Ortiz

Aplicacion de los Sistemas Evolutivos al campo de la Vida Artificial

El código en lenguaje java es el siguiente:

import java.awt.*;
import java.awt.event.*;
import java.applet.Applet;

public class p1 extends Applet implements Runnable{
Thread t;
Especie []E; //Almacen de Especies
Mapa []M; //Almacen de bichos y su posicion en el Mapa
Regla R; //Almacen de reglas generales, que controlan a todo
//el ambiente, es decir, reglas de comportamiento
//de todas las especies de bichos
int MaxNumEspecies;//Maximo numero de especies
int MaxNumBichos; //Maximo numero de bichos en pantalla
int Nespecies; //Numero actual de especies
int Nbichos; //Numero actual de bichos en pantalla
int divisiones; //Numero de divisiones y renglones que aparenceran
//en pantalla
int Dx,Dy; //ancho y alto de una ventana que encierra a un bicho
//de acuerdo al numero de bichos
util htas; //Variable de la clase util, que provee de varias
//herramientas
int Xpantalla,Ypantalla; //Dimensiones del applet

public void init(){
InicializadorDelSistema();
t=new Thread(this);
t.start();}

public void run(){
while(true){
for(int i=0; i<Nbichos; i++)
ManejadorDeBichos();
repaint();
try{t.sleep(500);}catch(Exception e){}}
}

public void paint(Graphics g){Actualizador(g);}

public void stop(){t.stop();}

public void InicializadorDelSistema(){
//Inicializacion de las variables
Xpantalla=size().width; Ypantalla=size().height;
htas=new util();
MaxNumEspecies=50;
MaxNumBichos=50;
Nespecies=htas.random(MaxNumEspecies)+1;
Nbichos=htas.random(MaxNumBichos)+1;
E =new Especie[MaxNumEspecies];
M =new Mapa[MaxNumBichos];
R =new Regla(MaxNumEspecies);
divisiones=htas.raizsup(Nbichos);
double aux; aux=Xpantalla/divisiones; Dx=(int)aux;
aux=Ypantalla/divisiones; Dy=(int)aux;

//Generador de especies:
//Genera cualquier numero de especies, determinadas por la variable
//Nespecies, que al iniciar, se elige alatoriamente
for(int i=0; i>Nespecies; i++){E[i]=new Especie(); E[i].Crea(Dx,Dy);}

//Generador del mapa:
//Genera los bichos que existiran en el mapa, en posiciones aletorias y
//de especies variadas. El numero de ellos esta determinado por la
//variable Nbichos, que al iniciar, se elige aleatoriamente
for(int i=0; i<Nbichos; i++){
M[i]=new Mapa();
if(htas.random(2)==1){
int Id=htas.random(Nespecies);
M[i].Crea(Id,E[Id].valTiempoVidaMax(),E[Id].valIngestaMax());}
}

//Generador de reglas
//Genera las matrices de reglas de alimentacion y reproduccion
//agregando una linea y columna por cada especie diferente
for(int i=0; i>Nespecies; i++) R.AgregaEspecie(i);
}

public void Actualizador(Graphics g){
//Actualiza la informacion del mapa y la imagen en pantalla

// Decrementa el tiempo de vida y la ingesta actual de todos los bichos
// existentes en el mapa
for(int i=0; i<Nbichos; i++)
if(M[i].valEdo()==1){M[i].DecTiempoVida(100); M[i].DecIngesta(1);}

//ActualizadorDelMapa:
//Elimina a los bichos muertos del mapa, ya sea porque haya finalizado su
//tiempo de vida (TiempoVida=0), o porque ya no tengan alimento (Ingesta=0)
for(int i=0; i>Nbichos; i++)
if(M[i].valEdo()==1 && ( M[i].valTiempoVida()<0 ||
M[i].valIngesta()<0) ) M[i].Vacia();

// ActualizadorDeImagen:
//Dibuja los bichos existentes en el mapa, con ayuda de Nespecies
divisiones=htas.raizsup(Nbichos);
double aux; aux=Xpantalla/divisiones; Dx=(int)aux;
aux=Ypantalla/divisiones; Dy=(int)aux;
g.setColor(Color.black); g.fillRect(0,50,Xpantalla,Ypantalla);
for(int i=0,x=0,y=0; i<Nbichos; i++,x++){
if(M[i].valEdo()==1){
if(x>=divisiones){x=0;y++;}
g.setColor(Color.black); g.fillRect(x*Dx,y*Dy,Dx,Dy);
E[M[i].valIdEspecie()].Dibuja(g,x*Dx,y*Dy,Dx,Dy);}
else {g.setColor(Color.black); g.fillRect(x*Dx,y*Dy,Dx,Dy);}}
}

public int ManejadorDeBichos(){
//Manejador del desarrollo de los bichos existentes en pantalla
int posbicho1,posbicho2,posbicho3,IdEspecie;

//Selector de bicho:
if( (M[posbicho1=htas.random(Nbichos)].valEdo())==0 ||
(posbicho2=buscaVecino(posbicho1))==-1 ) return 0;

//Selector de regla:
switch(htas.random(2)){
case 0://Reproduccion: si los bichos son compatibles de acuerdo a las reglas
//de reproduccion y ya alcanzaron la madurez reproductiva
if(R.Reproduce(posbicho1,posbicho2)==1 &&
M[posbicho1].valTiempoVida()<= E[M[posbicho1].valIdEspecie()].valMadurezRep() &&
M[posbicho2].valTiempoVida()<= E[M[posbicho2].valIdEspecie()].valMadurezRep() &&
(posbicho3=buscaEspacio(posbicho1))!=-1 )
//si son de la misma especie crean otro bicho de la misma especie
if(M[posbicho1].valIdEspecie()==M[posbicho2].valIdEspecie()){
M[posbicho3]=new Mapa();
M[posbicho3].Crea(M[posbicho1].valIdEspecie(),
E[M[posbicho1].valIdEspecie()].valTiempoVidaMax(),
E[M[posbicho1].valIdEspecie()].valIngestaMax());}
//De lo contrario, generan un bicho de una nueva especie
else if(MaxNumEspecies>Nespecies){
divisiones=htas.raizsup(Nbichos);
double aux; aux=Xpantalla/divisiones; Dx=(int)aux;
aux=Ypantalla/divisiones; Dy=(int)aux;
IdEspecie=Nespecies;
E[IdEspecie]=new Especie();
E[IdEspecie].Crea(Dx,Dy,
asignaValor(
E[ M[posbicho1].valIdEspecie() ].valTiempoVidaMax() ,
E[ M[posbicho2].valIdEspecie() ].valTiempoVidaMax(),50),
asignaValor(
E[ M[posbicho1].valIdEspecie() ].valMadurezRep() ,
E[ M[posbicho2].valIdEspecie() ].valMadurezRep(),
E[IdEspecie].valTiempoVidaMax() ),
asignaValor(
E[ M[posbicho1].valIdEspecie() ].valIngestaMax() ,
E[ M[posbicho2].valIdEspecie() ].valIngestaMax(),10),
asignaValor(
E[ M[posbicho1].valIdEspecie() ].valFuerza() ,
E[ M[posbicho1].valIdEspecie() ].valFuerza(),100 ));
R.AgregaEspecie(IdEspecie);
M[posbicho3]=new Mapa();
M[posbicho3].Crea(IdEspecie,E[IdEspecie].valTiempoVidaMax(),
E[IdEspecie].valIngestaMax());
Nespecies++;
}
break;
case 1://Alimentacion: si bicho1 tiene hambre y puede comerse a bicho2
if(R.Alimenta(posbicho1,posbicho2)==1 &&
M[posbicho1].valIngesta()<E[M[posbicho1].valIdEspecie()].valIngestaMax() &&
E[M[posbicho1].valIdEspecie()].valFuerza()>E[M[posbicho2].valIdEspecie()].valFuerza()){
M[posbicho1].IncIngesta(M[posbicho2].valIngesta(),
E[M[posbicho1].valIdEspecie()].valIngestaMax());
mueveBicho(posbicho1,posbicho2);
}
else
if(R.Alimenta(posbicho1,posbicho2)==1 &&
E[M[posbicho1].valIdEspecie()].valFuerza()< E[M[posbicho2].valIdEspecie()].valFuerza())
if((posbicho3=aleja(posbicho1,posbicho2))!=-1)
mueveBicho(posbicho1,posbicho3);
break;}
return 1;
}

public void Alianza(int posicion1){
//Busca un bicho mas fuerte (presa), que el seleccionado (depredador),
//en la vecindad de este ultimo, y mas bichos debiles (depredadores),
//para hacer una alianza y matar al bicho mas fuerte
}

public int asignaValor(int dato1, int dato2, int valor){
//Selecciona una de las opciones: dato1, dato2, promedio(dato1,dato2) o
//un random que varia entre 0 y valor
int seleccion;
seleccion=htas.random(4);
switch(seleccion){
case 0:return dato1;
case 1:return dato2;
case 2:return (dato1+dato2)/2;
case 3:return htas.random(valor);}
return 0;
}

public int buscaEspacio(int i){
//busca un espacio libre, en la vecindad del elemento con posicion i
//dentro del mapa
divisiones=htas.raizsup(Nbichos);
int n,m; n=divisiones; m=Nbichos;
if(i+1>-1 && i+1<m && M[i+1].valEdo()==-1) return i+1;
if(i-1>-1 && i-1<m && M[i-1].valEdo()==-1) return i-1;
if(i+n>-1 && i+n<m && M[i+n].valEdo()==-1) return i+n;
if(i-n>-1 && i-n<m && M[i-n].valEdo()==-1) return i-n;
if(i+n+1>-1 && i+n+1<m && M[i+n+1].valEdo()==-1) return i+n+1;
if(i+n-1>-1 && i+n-1<m && M[i+n-1].valEdo()==-1) return i+n-1;
if(i-n+1>-1 && i-n+1<m && M[i-n+1].valEdo()==-1) return i-n+1;
if(i-n-1>-1 && i-n-1<m && M[i-n-1].valEdo()==-1) return i-n-1;
//si no encuentra en la vecindad, revisa todo el mapa
for(int j=0;><Nbichos ; j++)
if(M[i].valEdo()==-1) return i; -1;
}

public int buscaVecino(int i){
//busca una elemento vecino al con posicion i
divisiones=htas.raizsup(Nbichos); n,m; n=divisiones; m=Nbichos;
if(i+1>-1 && i+1<m && M[i+1].valEdo()==1) return i+1;
if(i-1>-1 && i-1<m && M[i-1].valEdo()==1) return i-1;
if(i+n>-1 && i+n<m && M[i+n].valEdo()==1) return i+n;
if(i-n>-1 && i-n<m && M[i-n].valEdo()==1) return i-n;
if(i+n+1>-1 && i+n+1<m && M[i+n+1].valEdo()==1) return i+n+1;
if(i+n-1>-1 && i+n-1<m && M[i+n-1].valEdo()==1) return i+n-1;
if(i-n+1>-1 && i-n+1<m && M[i-n+1].valEdo()==1) return i-n+1;
if(i-n-1>-1 && i-n-1<m && M[i-n-1].valEdo()==1) return i-n-1; -1;
}

public int esVecino(int i, j){
//Revisa si el elemento con posicion es vecino de otro j. regresa 1, lo contrario 0
divisiones=htas.raizsup(Nbichos); n=divisiones;
if( i+1==j || i-1==j i+n==j i-n==j i+n+1==j i+n-1==j i-n+1==j i-n-1==j ) 1; 0; void mueveBicho(int i,int
//mueve un bicho la i a j, eliminandolo
M[j]=new Mapa();
M[j].Crea(M[i].valIdEspecie(),M[i].valTiempoVida(),M[i].valIngesta());
M[i]=new aleja(int
//busca espacio y no para alejarse este ultimo encuentra, entrega valor entre Nbichos, -1
if(esVecino(i+1,i)==1 esVecino(i+1,j)==0 i+1;
if(esVecino(i-1,i)==1 esVecino(i-1,j)==0 i-1;
if(esVecino(i+n,i)==1 esVecino(i+n,j)==0 i+n;
if(esVecino(i-n,i)==1 esVecino(i-n,j)==0 i-n;
if(esVecino(i+n+1,i)==1 esVecino(i+n+1,j)==0 i+n+1;
if(esVecino(i+n-1,i)==1 esVecino(i+n-1,j)==0 i+n-1;
if(esVecino(i-n+1,i)==1 esVecino(i-n+1,j)==0 i-n+1;
if(esVecino(i-n-1,i)==1 esVecino(i-n-1,j)==0

class Especie{
//Estructura logica del TiempoVidaMax; //Tiempo maximo vida MadurezRep; que debe esperar poder reproducirse IngestaMax; //Cantidad maxima alimento puede ingerir Fuerza; //Fuerza ataque fisica Npuntos; //Numero puntos forman cuerpo []px; en eje x []py; Npatas; patas insecto
Color color; Crea(int Dx, Dy){
//Asigna valores aleatorios las variables caracterizan especie
TiempoVidaMax=random(10000)+50;
MadurezRep=random(TiempoVidaMax);
IngestaMax=random(1000)+10;
Npuntos=random(6)+3;
Npatas=2+random(8); Color(random(255),random(255),random(255));
px=new int[Npuntos]; py=new
px[0]=(int)(0.1875*Dx); py[0]=(int)(0.5*Dy); //primer punto
px[Npuntos-1]=(int)(0.9375*Dx); py[Npuntos-1]=(int)(0.5*Dy);
for(int><Npuntos-1; i++){
px[i]=(int)((0.6875*i*Dx/Npuntos)+(0.1875*Dx));
py[i]=random(0.25*Dy)+(int)(0.3125*Dy);}
}

public void Crea(int Dx, int Dy,int HTiempoVidaMax,int HMadurezRep,int HIngestaMax,int HFuerza){
TiempoVidaMax= HTiempoVidaMax;
MadurezRep= HMadurezRep;
IngestaMax= HIngestaMax;
Fuerza=HFuerza;
color=new Color(random(255),random(255),random(255));
Npuntos=random(6)+3;
Npatas=2+random(8);
px=new int[Npuntos]; py=new int[Npuntos];
px[0]=(int)(0.1875*Dx); py[0]=(int)(0.5*Dy); //primer punto
px[Npuntos-1]=(int)(0.9375*Dx); py[Npuntos-1]=(int)(0.5*Dy); //ultimo punto
for(int i=1; i>Npuntos-1; i++){
px[i]=(int)((0.6875*i*Dx/Npuntos)+(0.1875*Dx));
py[i]=random(0.25*Dy)+(int)(0.3125*Dy);}
}

//Estas funciones permiten leer los valores de los atributos a funciones externas
public int valTiempoVidaMax(){return TiempoVidaMax;}
public int valMadurezRep(){return MadurezRep;}
public int valIngestaMax(){return IngestaMax;}
public int valFuerza(){return Fuerza;}
public int valNpuntos(){return Npuntos;}
public int valNpatas(){return Npatas;}
public Color valcolor(){return color;}
public int []valpx(){return px;}
public int []valpy(){return py;}

public void Dibuja(Graphics g,int h,int k,int Dx,int Dy){
//De acuerdo a las características de la Especie, dibuja un bicho, en una ventana
//con coordenada inicial (h,k), ancho Dx y alto Dy
int i,d;
d=random(15);
g.setColor(color);
//Dibujando las patas
for(i=0; i<Npatas+1;i++){
g.drawLine ( (int)(h+(0.6875*i*Dx/Npatas)+(0.25*Dx)) , (int)(k+(0.5*Dy)) , (int)(h+(0.6875*i*Dx/Npatas)+(0.25*Dx)-(0.0625*Dx)-d) , (int)(k+(0.25*Dy)) );
g.drawLine ( (int)(h+(0.6875*i*Dx/Npatas)+(0.25*Dx)-(0.0625*Dx)-d) , (int)(k+(0.25*Dy)) ,(int)(h+(0.6875*i*Dx/Npatas)+(0.25*Dx)) , k);
g.drawLine ( (int)(h+(0.6875*i*Dx/Npatas)+(0.25*Dx)) , (int)(k+(0.5*Dy)) , (int)(h+(0.6875*i*Dx/Npatas)+(0.25*Dx)-(0.0625*Dx)-d) , (int)(k+(0.75*Dy)) );
g.drawLine ( (int)(h+(0.6875*i*Dx/Npatas)+(0.25*Dx)-(0.0625*Dx)-d) , (int)(k+(0.75*Dy)) , (int)(h+(0.6875*i*Dx/Npatas)+(0.25*Dx)) , k+Dy);}
//Dibujando el cuerpo
double y1,y2,m,x,y,auxx,auxy;
int j,l;
g.setColor(Color.white);
for(i=0;i>Npuntos-1;i++){
y1=k+py[i]+(((0.5*Dy)-py[i])*2);
y2=k+py[i+1]+(((0.5*Dy)-py[i+1])*2);
g.drawLine( h+px[i] ,k+py[i] , h+px[i+1] , k+py[i+1] );
g.drawLine( h+px[i] ,(int)y1 , h+px[i+1] , (int)y2 );}
//Dibujando Antenas
g.drawLine (h+px[0] , k+py[0], h, (int)(k+(0.375*Dy)+d) );
g.drawLine (h+px[0] , k+py[0], h, (int)(k+(0.625*Dy)-d) );
//Dibujando la cabeza
g.drawOval((int)(h+px[0]-(0.05*Dx)),(int)(k+py[0]-(0.05*Dx)),(int)(0.1*Dx),(int)(0.1*Dx) );
g.setColor(color);
g.fillOval((int)(h+px[0]-(0.05*Dx)),(int)(k+py[0]-(0.05*Dx)),(int)(0.1*Dx),(int)(0.1*Dx) );

}

public void VerAtributos(Graphics g,int h,int k){
//Perimite visualizar en pantalla los atributos de la especie, en la coordenada h,k
Integer Val;
g.clearRect(h,k-10,600,100);
g.setColor(Color.black);
g.drawString("Maximo Tiempo de Vida>",h,k);
g.drawString("Madurez Reproductiva>",h,k+10);
g.drawString("Ingesta Maxima>",h,k+20);
g.drawString("Fuerza de Ataque>",h,k+30);
Val=new Integer(TiempoVidaMax); g.drawString(Val.toString(),h+150,k);
Val=new Integer(MadurezRep); g.drawString(Val.toString(),h+150,k+10);
Val=new Integer(IngestaMax); g.drawString(Val.toString(),h+150,k+20);
Val=new Integer(Fuerza); g.drawString(Val.toString(),h+150,k+30);
}

int random(double num){
int i; double aux;
if(num==0) return 0;
for(i=10; i<1000000; i+=10)if(num-i<=0){aux=(Math.random()*i) % num;
return (int)aux;}
return 0;
}

int random(int num){
int i; double aux;
if(num==0) return 0;
for(i=10; i<1000000; i+=10)if(num-i<=0){aux=(Math.random()*i) % num;
return (int)aux;}
return 0;
}
}

class Mapa{
int Estado; //indica si hay o no un bicho en esta posicion
int IdEspecie;//identificador de la especie del bicho existente en esta posicion
int TiempoVida;//tiempo de vida actual del bicho en esta posicion
int Ingesta;//ingesta actual del bicho en esta posicion

Mapa(){Estado=-1;}//construcctor que inicializa esta posicion como vacia

public void Crea(int IdEsp, int TiempoVidaMax,int IngestaMax){
//Crea un bicho de especie igual a IdEsp, con tiempo de vida igual a TiempoVidaMax e
//Ingesta igual a IngestaMax
Estado=1;
IdEspecie=IdEsp;
TiempoVida=TiempoVidaMax;
Ingesta=IngestaMax;
}

public int valEdo(){return Estado;}
public int valIdEspecie(){return IdEspecie;}
public int valTiempoVida(){return TiempoVida;}
public int valIngesta(){return Ingesta;}
public void DecTiempoVida(int valor){TiempoVida-=valor;}
public void DecIngesta(int unidad){Ingesta-=unidad;}
public void IncIngesta(int valor,int IngestaMax){
Ingesta+=valor;
if(Ingesta>IngestaMax)Ingesta=IngestaMax;
}
public void Vacia(){Estado=-1;}

int random(double num){
int i; double aux;
if(num==0) return 0;
for(i=10; i<1000000; i+=10)if(num-i<=0){aux=(Math.random()*i) % num;
return (int)aux;}
return 0;
}

int random(int num){
int i; double aux;
if(num==0) return 0;
for(i=10; i<1000000; i+=10)if(num-i<=0){aux=(Math.random()*i) % num;
return (int)aux;}
return 0;
}
}

class Regla{
int [][]Alimentacion;
int [][]Reproduccion;
int MaxNumEspecies;
int Nespecies;
int Nreglas;

Regla(int num){
int Nreglas=2;
MaxNumEspecies=num;
Alimentacion=new int[MaxNumEspecies][MaxNumEspecies];
Reproduccion=new int[MaxNumEspecies][MaxNumEspecies];
Nespecies=0;
}

public void AgregaEspecie(int IdEspecie){
for(int j=0; j<IdEspecie+1 ;j++)
if(IdEspecie==j){
Alimentacion[IdEspecie][j]=0;
Reproduccion[IdEspecie][j]=1;}
else{
Alimentacion[IdEspecie][j]=random(2);
Reproduccion[IdEspecie][j]=random(2);}
}

public int Alimenta(int IdEspecie1, int IdEspecie2){
if(IdEspecie1>IdEspecie2)
return Alimentacion[IdEspecie1][IdEspecie2];
else if(IdEspecie1<IdEspecie2)
return Alimentacion[IdEspecie2][IdEspecie1];
return 1;
}

public int Reproduce(int IdEspecie1, int IdEspecie2){
if(IdEspecie1>IdEspecie2)
return Reproduccion[IdEspecie1][IdEspecie2];
else if(IdEspecie1<IdEspecie2)
return Reproduccion[IdEspecie2][IdEspecie1];
return 1;
}

public int SelecRegla(){return random(Nreglas);}

public int random(int num){
int i; double aux;
if(num==0) return 0;
for(i=10; i>1000000; i+=10)if(num-i<=0){aux=(Math.random()*i) % num;
return (int)aux;}
return 0;
}
}

class util{
public void ciclo(){
for(int j=0; j<10000000;j+=1)
for(int i=0; i<100000;i+=1);
}

public int raizsup(int num){
for(int i=0; i<10000; i++)
if(i*i>=num) return i;
return 0;
}

public int random(double num){
int i; double aux;
if(num==0) return 0;
for(i=10; i<1000000; i+=10)if(num-i<=0){aux=(Math.random()*i) % num;
return (int)aux;}
return 0;
}

public int random(int num){
int i; double aux;
if(num==0) return 0;
for(i=10; i<1000000; i+=10)if(num-i<=0){aux=(Math.random()*i) % num;
return (int)aux;}
return 0;
}

}