예제 #1
0
 public ColumnasAER(String accion, Bloque estado, int frecuencia, float valor)
 {
     this.accion     = accion;
     this.estado     = estado;
     this.frecuencia = frecuencia;
     this.valor      = valor;
 }
예제 #2
0
        // --- funcion evaluarRecompensa
        private float evaluarRecompensa(TablaAER Q, String accion, Bloque estado)
        {
            // recompensa por morir.
            if (life <= 0)
            {
                return(-10f);
            }
            ColumnasAER tupla = Q.getTupla(accion, estado);

            if (tupla != null)
            {
                return(tupla.valor);
            }

            float Out = -1f;

            // recompensa para avanzarDer, avanzarIzq, saltar es de -0.03
            if ((accion.Equals("avanzarDer")) || (accion.Equals("avanzarIzq")))
            {
                Out = -3f;
            }
            // recompensa para saltarIzq, saltarDer es de -0.02
            if ((accion.Equals("saltarDer")) || (accion.Equals("saltarIzq")) || (accion.Equals("saltar")))
            {
                Out = -2f;
            }
            return(Out);
        }
예제 #3
0
        // retorna la tupla con mayor valor
        public ColumnasAER getActionMaxQ(String accion, Bloque estado, float recompensa)
        {
            ColumnasAER tupla = new ColumnasAER(accion, estado, 0, recompensa);

            foreach (var fila in filas)
            {
                // verifica estados iguales
                if (fila.estado.IsEquals(tupla.estado))
                {
                    // verifica accion igual
                    if (fila.accion == tupla.accion)
                    {
                        if (tupla.valor <= -5)
                        {
                            foreach (var item in Movimientos)
                            {
                                if (item != tupla.accion)
                                {
                                    tupla.accion = item;
                                    return(tupla);
                                }
                            }
                        }
                    }
                }
            }
            return(tupla);
        }
예제 #4
0
        public acciones Regla(Bloque area, reglas r)
        {
            acciones nuevasAcciones = new acciones();

            nuevasAcciones.accion = new List <string>();
            int cond = 0, sectores = 0;

            foreach (var r_cond in r.regla)                   // lista de condiciones
            {
                foreach (var r_bloq in r_cond.bloque)         // lista de bloques regla
                {
                    foreach (var r_sector in r_bloq.sector)   // sectores de cada bloque regla
                    {
                        foreach (var e_sector in area.sector) // lista de sectores del sensor
                        {
                            //Debug.Write(e_sector.posicion + " ");
                            if ((r_sector.posicion == e_sector.posicion) && (r_sector.value == e_sector.value))
                            {
                                sectores++;
                            }
                        }
                    }
                    if (sectores == r_bloq.sector.Count)
                    {
                        cond++;
                    }
                    sectores = 0;
                }
                if (cond == r_cond.bloque.Count)
                {
                    nuevasAcciones.accion.Add(r_cond.accion); cond = 0;
                }
            }
            return(nuevasAcciones);
        }
예제 #5
0
 // --- funcion sensor -- crea hilos
 public override void Sensor(Bloque area)
 {
     this.area = area;
     // crea un hilo para calcular el camino optimo
     //Thread cal = new Thread(new ThreadStart(CalcularCaminoThread));
     //Thread cal = new Thread(new ThreadStart(SensorAgente));
     //cal.Start();
     SensorAgente();
 }
예제 #6
0
 public AgenteObjetivo(Microsoft.Xna.Framework.Game game, Vector2 tamano, Vector2 posicion, String nombreImagen)
     : base(game, tamano, posicion, nombreImagen)
 {
     NombreImagen = nombreImagen;
     ColorImagen  = Color.White;
     posPlayer    = new Vector2(-1, -1);
     posAgent     = new Vector2(-1, -1);
     area         = new Bloque();
     life         = 1;
     LoadContent();
 }
예제 #7
0
 public BusquedaAestrella(Bloque mapa, int profundidad)
 {
     this.mapa        = mapa;
     this.profundidad = (profundidad * 2) + 1;
     foreach (var item in mapa.sector)
     {
         if (item.name.Equals("player"))
         {
             posFinal = item.posicion;
         }
     }
     posInicial = mapa.obtenerSector(new Vector2(profundidad, profundidad)).posicion;
 }
예제 #8
0
 public bool IsEquals(Bloque Input)
 {
     for (int i = 0; i < Input.sector.Count; i++)
     {
         if ((Input.sector[i].name.Equals(sector[i].name)) && ((Input.sector[i].posicion == sector[i].posicion)) && (Input.sector[i].value == sector[i].value))
         {
             continue;
         }
         else
         {
             return(false);
         }
     }
     return(true);
 }
예제 #9
0
 // --- funcion SensorAgente que aprende
 private void SensorAgente()
 {
     foreach (var item in area.sector)
     {
         //Debug.Write(item.name+":"+item.value+" ");
         if (item.name.Equals("player"))
         {
             String accion = CaminoActualizado(area);
             Bloque estado = disminuirArea(3);  // EJ: escala 1 : 1 un bloque por cada lado adyacente // matriz de 3x3
             accion = funcionQ(accion, estado); // algoritmo que aprende
             // - Debug.WriteLine(accion);
             Comportamiento(accion);
         }
     }
     //Debug.WriteLine("");
 }
예제 #10
0
        // --- funcion evaluarRecompensa2
        private float evaluarRecompensa(String accion, Bloque estado)
        {
            float Out = -1f;

            // recompensa para avanzarDer, avanzarIzq, saltar es de -0.03
            if ((accion.Equals("avanzarDer")) || (accion.Equals("avanzarIzq")))
            {
                Out = -3f;
            }
            // recompensa para saltarIzq, saltarDer es de -0.02
            if ((accion.Equals("saltarDer")) || (accion.Equals("saltarIzq")) || (accion.Equals("saltar")))
            {
                Out = -2f;
            }
            return(Out);
        }
예제 #11
0
 // retorna la tupla
 public ColumnasAER getTupla(String accion, Bloque estado)
 {
     if (filas == null)
     {
         return(null);
     }
     foreach (var fila in filas)
     {
         if ((accion.Equals(fila.accion)) && (estado.IsEquals(fila.estado)))
         {
             // - Debug.WriteLine("fila encontrada --------------------------------");
             return(fila);
         }
     }
     // - Debug.WriteLine("fila no encontrada");
     return(null);
 }
예제 #12
0
        public Bloque Suma(List <Bloque> input, int profundidad)
        {
            Bloque        output = new Bloque();
            List <Sector> swap = new List <Sector>();
            int           k = profundidad;
            int           m = 0, p = 0;

            for (int y = -k; y < k + 1; y++)
            {
                for (int x = -k; x < k + 1; x++)
                {
                    Sector aux = new Sector();
                    aux.name     = "empty";
                    aux.value    = false;
                    aux.posicion = new Vector2(p, m);
                    swap.Add(aux);
                    p++;
                }
                m++; p = 0;
            }
            // comparacion
            foreach (var bloque in input)
            {
                foreach (var s in swap)
                {
                    foreach (var o in bloque.sector)
                    {
                        if ((s.posicion == o.posicion) && (o.value == true))
                        {
                            s.value = true;
                            s.name  = o.name;
                        }
                    }
                }
            }

            output.sector = swap;

            return(output);
        }
예제 #13
0
        public override void Sensor(Bloque area)
        {
            //asigna los estados
            //estados e = Percepciones(sprite);
            // acciones necesitan reglas
            reglas r = new reglas();

            //// ---------------------------------------------------------------------
            //r.regla = new List<condiciones>();
            //// condiciones
            //// condicion 1
            //condiciones cond = new condiciones(); // tecnicamente esto es una regla
            //cond.bloque = new List<Bloque>();
            //Bloque bA = new Bloque();
            //bA.sector = new List<Sector>();
            //Sector sA = new Sector();
            //Sector sB = new Sector();
            //Sector sC = new Sector();
            //cond.accion = "avanzar";
            //sA.value = false;
            //sA.name = "wall";
            //sA.posicion = new Vector2(1,0);
            //sB.value = false;
            //sB.name = "wall";
            //sB.posicion = new Vector2(1,2);
            //bA.sector.Add(sA); // agrega sector 1,0
            //bA.sector.Add(sB); // agrega sector 1,2
            //cond.bloque.Add(bA); // agrega bloque a la lista de bloques.
            //r.regla.Add(cond); // agrega la condicion a la regla.
            //r.regla.Add(cond); // agrega la condicion a la regla.
            //// fin condiciones
            //  ---------------------------------------------------------------------
            //XML.Serialize(r, "reglas.dat");
            r = XML.Deserialize <reglas>("reglas.dat");
            acciones action = new acciones();

            action = Regla(area, r);
            //
            Comportamiento(action);
        }
예제 #14
0
        public AgenteAprende(Microsoft.Xna.Framework.Game game, Vector2 tamano, Vector2 posicion, String nombreImagen)
            : base(game, tamano, posicion, nombreImagen)
        {
            NombreImagen   = nombreImagen;
            ColorImagen    = Color.White;
            posPlayer      = new Vector2(-1, -1);
            posAgent       = new Vector2(-1, -1);
            area           = new Bloque();
            accionAnterior = new ColumnasAER();
            life           = 1;
            try
            {
                Q = XML.Deserialize <TablaAER>("memoria");
            }
            catch (Exception)
            {
                nomemory = true;
                Q        = new TablaAER();
            }

            LoadContent();
        }
예제 #15
0
        // --- funcion evalua cada accion, estado y recompensa. Retorna la accion a tomar
        private String funcionQ(String aA, Bloque eA) // valores Actuales : accionActual, estadoActual, recompensaActual
        {
            String accion = "nada";

            if (nomemory)
            {
                Q.FilasAER    = new List <ColumnasAER>();
                Q.Movimientos = new List <string>();
                float       rA    = evaluarRecompensa(aA, eA);
                ColumnasAER tupla = new ColumnasAER(aA, eA, 0, rA);
                // agrega la tupla directo en la tabla
                Q.addTupla(tupla);
                accion   = tupla.accion;
                nomemory = false;
                return(accion);
            }
            if (Q.getTupla(aA, eA) != null) // busca la tupla en la tabla
            {
                float       rA    = evaluarRecompensa(Q, aA, eA);
                ColumnasAER tupla = Q.getActionMaxQ(aA, eA, rA);
                // agrega la tupla en la tabla
                Q.addTupla(tupla);
                accionAnterior = tupla;
                accion         = tupla.accion;
                // - Debug.WriteLine("La tupla si esta");
            }
            else
            {
                float       rA    = evaluarRecompensa(Q, aA, eA);
                ColumnasAER tupla = new ColumnasAER(aA, eA, 0, rA);
                // agrega la tupla directo en la tabla
                Q.addTupla(tupla);
                accion = tupla.accion;
            }
            return(accion);
        }
예제 #16
0
        // --- disminuye el area de hxh a 3x3
        private Bloque disminuirArea(int escala)
        {
            //Vector2 centro = new Vector2(profundidad, profundidad); // centro del area
            //Bloque Out = new Bloque();
            Sector swap = new Sector();
            // crea un bloque de dimension hxh vacio
            Bloque In = new Bloque(escala);
            // asigna el area en un bloque para manipular
            Bloque Inter = this.area;
            // asigna los valores del Area actual al bloque
            int h          = (escala * 2) + 1;
            int cuadrarX   = escala;
            int cuadrarY   = escala;
            int progresion = 0;

            for (int j = 0; j < h; j++)     // para Y
            {
                for (int k = 0; k < h; k++) // para X
                {
                    swap = Inter.obtenerSector(new Vector2(profundidad - cuadrarX, profundidad - cuadrarY));
                    In.sector[progresion].name     = swap.name;
                    In.sector[progresion].value    = swap.value;
                    In.sector[progresion].posicion = new Vector2(k, j);
                    progresion++;
                    cuadrarX--;
                    //Debug.Print();
                    //Debug.Write("[" + swap.name + "]");
                }
                cuadrarX = escala;
                cuadrarY--;
                //Debug.WriteLine("");
            }
            //Debug.WriteLine("");

            return(In);
        }
예제 #17
0
        //private List<estados> retorno = new List<estados>();

        public Bloque Percepciones(SpriteComponent agente, SpriteComponent sprite, int profundidad)
        {
            // lee las entradas (percepciones) y las compara para luego retornar un estado
            // 'jugador' son las percepciones del objetivo: Jugador.
            // 'agente' son las percepciones del objetivo: Agente.
            //estados nuevoEstado = new estados(); // inicializa los estados.
            //nuevoEstado.sector = new List<Sector>();
            Bloque nuevoBloque = new Bloque();
            //nuevoEstado.sector = new List<Sector>(); // inicializa el conjunto de estados.
            // verifica si es un jugador u otro objeto
            // calcula la distancia entre jugador y agente.

            /* nueva funcion de calculo
             * se crea una nueva posicion para el elemento verificando su posicion en celdas de 32*32px
             * Vector2 nPA = nueva Posicion Agente
             * Vector2 nPS = nueva Posicion Sprite
             * nivel de profundidad 1.
             * A, B, C, D, E, F, G y H son las posibles posiciones en las que se puede encontrar un elemento cercano al agente.
             * IF condiciones en que evalua si el sprite se encuentra en la matriz adyacente del agente.
             *      |A|B|C|
             *      |D|*|E|
             *      |F|G|H|
             * el agente "*" se encuentra en el centro.
             * A: X-1, Y-1     E: X+1, Y+0
             * B: X+0, Y-1     F: X-1, Y+1
             * C: X+1, Y-1     G: X+0, Y+1
             * D: X-1, Y+0     H: X+1, Y+1
             * nivel de profundidad 2.
             *      |A|B|C|D|E|
             *      |F|G|H|I|J|
             *      |K|L|*|M|N|
             *      |O|P|Q|R|S|
             *      |T|U|V|W|X|
             * nivel de profundidad 3...
             */
            Vector2 nPA = new Vector2((int)(agente.Posicion.X / 32), (int)(agente.Posicion.Y / 32));
            Vector2 nPS = new Vector2((int)(sprite.Posicion.X / 32), (int)(sprite.Posicion.Y / 32));
            Vector2 tPS = new Vector2((int)(sprite.Tamano.X / 32), (int)(sprite.Tamano.Y / 32));

            // comprueba la posicion del sprite con profundidadnivel1
            //nuevoBloque.sector = ProfundidadNivel1(nPA, nPS, tPS);


            // asignamos el nombre del sprite
            if (sprite is Jugador)
            {
                nuevoBloque.sector = Profundidad(nPA, nPS, tPS, profundidad, "player");
            }
            else if (sprite is Muro)
            {
                nuevoBloque.sector = Profundidad(nPA, nPS, tPS, profundidad, "wall");
            }
            else if (sprite is Agent)
            {
                nuevoBloque.sector = Profundidad(nPA, nPS, tPS, profundidad, "agent");
            }
            else if (sprite is Objeto)
            {
                nuevoBloque.sector = Profundidad(nPA, nPS, tPS, profundidad, "object");
            }

            return(nuevoBloque);
        }
예제 #18
0
        // --- funcion evalua cada accion, estado y recompensa. Retorna la accion a tomar
        private String funcionQ(String aA, Bloque eA) // valores Actuales : accionActual, estadoActual, recompensaActual
        {
            TablaAER Q      = new TablaAER();
            String   accion = "nada";

            // guardar
            // XML.Serialize(Q, "memoria");
            // cargar
            // XML.Deserialize<TablaAER>("memoria");
            // verificamos si existe el archivo memoria
            //if (contacto)
            //{
            //    rA = 1;
            //    contacto = false;
            //}
            if (File.Exists("memoria"))
            {
                // cargar memoria
                Q = XML.Deserialize <TablaAER>("memoria");
                if (Q.getTupla(aA, eA) != null) // busca la tupla en la tabla
                {
                    float       rA    = evaluarRecompensa(Q, aA, eA);
                    ColumnasAER tupla = Q.getActionMaxQ(aA, eA, rA);
                    // agrega la tupla en la tabla
                    Q.addTupla(tupla);
                    accion = tupla.accion;
                    // - Debug.WriteLine("La tupla si esta");
                }
                else // si no la encuentra
                {
                    float       rA    = evaluarRecompensa(Q, aA, eA);
                    ColumnasAER tupla = new ColumnasAER(aA, eA, 0, rA);
                    // agrega la tupla directo en la tabla
                    Q.addTupla(tupla);
                    accion = tupla.accion;
                    // - Debug.WriteLine("La tupla no esta");
                }
                XML.Serialize(Q, "memoria");
                return(accion);
            }
            // algoritmo que se ejecuta por defecto cuando no existe memoria
            else
            {
                // crear informacion
                Q.FilasAER = new List <ColumnasAER>();
                float       rA    = evaluarRecompensa(Q, aA, eA);
                ColumnasAER tupla = new ColumnasAER(aA, eA, 0, rA);
                Q.FilasAER.Add(tupla);
                // se agrega el moviemiento a su memoria
                Q.Movimientos = new List <String>();
                Q.Movimientos.Add(aA);
                // guardar informacion en memoria
                XML.Serialize(Q, "memoria");
                // cerrar archivo
                // asigna la accion actual como accion por defecto
                accion = aA;
                // retorna la accion
                // - Debug.WriteLine("No existe memoria");
                return(accion);
            }
        }
예제 #19
0
        public void Update(float deltaTime, float totalTime)
        {
            //List<estados> stat = new List<estados>();
            List <Bloque> stat      = new List <Bloque>();
            Bloque        outBloque = new Bloque();

            for (int i = 0; i < Sprites.Count; ++i)
            {
                Sprites[i].verificarMuerte();
                if (Sprites[i].died)
                {
                    RemoverSprite(Sprites[i]);
                    continue;
                    // game over
                }
                Sprites[i].Velocidad += gravedad * Sprites[i].Peso;
                Sprites[i].Mover((Sprites[i].Velocidad) * deltaTime);
                //redibuja las posiciones
                if (!(Sprites[i] is Jugador))
                {
                    Sprites[i].Mover(Desplazamiento * deltaTime);
                }
                //verificar colisiones
                for (int j = 0; j < Sprites.Count; ++j)
                {
                    if (Sprites[i] == Sprites[j])
                    {
                        continue;
                    }
                    Vector2 depth = CalcularMinimaDistanciaTraslacion(Sprites[i].Bound, Sprites[j].Bound);
                    if (depth != Vector2.Zero)
                    {
                        Sprites[i].Colision(Sprites[j], depth);
                    }
                    //if (( (Sprites[i].nombreSprite.Equals("Agente")) || (Sprites[i].nombreSprite.Equals("Player")) ) && ( (Sprites[j].nombreSprite.Equals("Agente")) || (Sprites[j].nombreSprite.Equals("Player")) ))
                    //{
                    //    //Debug.Print("---------"+Sprites[i].nombreSprite+"----------");
                    //    Sprites[i].direccionColision = ColisionEntreObjetos(Sprites[i].Bound, Sprites[j].Bound);
                    //    //Debug.Print(""+Sprites[i].life+" "+Sprites[i].direccionColision);
                    //}
                    //Sprites[i].Colision(Sprites[j], depth);
                }
            }
            for (int k = 0; k < Agentes.Count; k++)
            {
                if (Agentes[k].died)
                {
                    Agentes[k].muerte();
                    RemoverAgente(Agentes[k]);
                    continue;
                }
                for (int i = 0; i < Sprites.Count; ++i)
                {
                    stat.Add(new Sensores().Percepciones(Agentes[k], Sprites[i], Agentes[k].profundidad));
                }
                outBloque = new Bloque();
                outBloque = new Sensores().Suma(stat, Agentes[k].profundidad);
                Agentes[k].Sensor(outBloque);
                stat = new List <Bloque>();
            }
        }
예제 #20
0
 public abstract void Sensor(Bloque area);
예제 #21
0
        // --- funcion que calcula el camino que debe seguir el agente, retorna el camino completo
        public acciones Camino(Bloque area)
        {
            BusquedaAestrella cOp    = new BusquedaAestrella(area, profundidad); // instancia el algoritmo A*
            Vector2           final  = cOp.getPosicionPlayer;                    // obtiene la posicion del player
            acciones          camino = new acciones();

            camino.accion = new List <string>();

            /*
             *  verifica que el jugador haya cambiado de posicion.
             */
            if (final != posPlayer)
            {
                Vector2        reff       = cOp.getPosicionAgent; // obtiene la posicion del agente (posicion inicial)
                List <Vector2> posiciones = cOp.encontrarCamino();
                foreach (var item in posiciones)
                {
                    //Debug.WriteLine(item + " - " + reff);
                    //derecha
                    if ((item.X == reff.X + 1) && (item.Y == reff.Y))
                    {
                        camino.accion.Add("avanzarDer");
                    }
                    //izquierda
                    if ((item.X == reff.X - 1) && (item.Y == reff.Y))
                    {
                        camino.accion.Add("avanzarIzq");
                    }
                    //arriba
                    if ((item.X == reff.X) && (item.Y == reff.Y - 1))
                    {
                        camino.accion.Add("saltar");
                    }
                    //abajo
                    if ((item.X == reff.X) && (item.Y == reff.Y + 1))
                    {
                        // nose
                    }
                    //derecha-arriba
                    if ((item.X == reff.X + 1) && (item.Y == reff.Y - 1))
                    {
                        camino.accion.Add("saltarDer");
                    }
                    //derecha-abajo
                    if ((item.X == reff.X + 1) && (item.Y == reff.Y + 1))
                    {
                        camino.accion.Add("avanzarDer");
                    }
                    //izquierda-arriba
                    if ((item.X == reff.X - 1) && (item.Y == reff.Y - 1))
                    {
                        camino.accion.Add("saltarIzq");
                    }
                    //izquierda abajo
                    if ((item.X == reff.X - 1) && (item.Y == reff.Y + 1))
                    {
                        camino.accion.Add("avanzarIzq");
                    }
                    reff = item;
                }
                posPlayer = final;
                return(camino);
            }

            return(camino);
        }
예제 #22
0
        // --- funcion que calcula el camino que debe seguir el agente, retorna solo el siguiente movimiento.
        public String CaminoActualizado(Bloque area)
        {
            BusquedaAestrella cOp    = new BusquedaAestrella(area, profundidad); // instancia el algoritmo A*
            Vector2           final  = cOp.getPosicionPlayer;                    // obtiene la posicion del player
            Vector2           inicio = cOp.getPosicionAgent;                     // obtiene la posicion del agente (posicion inicial)
            String            Accion = "nada";
            Vector2           sucesion;                                          // item: posicion a alcansar

            if ((final != posPlayer) || (inicio != posAgent))                    // si la posicion del jugador cambia
            {
                camino   = cOp.encontrarCamino();
                sucesion = camino[1];
            }
            else
            {
                sucesion = camino[1];
            }

            //Debug.WriteLine(item + " - " + reff);
            //derecha
            if ((sucesion.X == inicio.X + 1) && (sucesion.Y == inicio.Y))
            {
                Accion = "avanzarDer";
            }
            //izquierda
            if ((sucesion.X == inicio.X - 1) && (sucesion.Y == inicio.Y))
            {
                Accion = "avanzarIzq";
            }
            //arriba
            if ((sucesion.X == inicio.X) && (sucesion.Y == inicio.Y - 1))
            {
                Accion = "saltar";
            }
            //abajo
            if ((sucesion.X == inicio.X) && (sucesion.Y == inicio.Y + 1))
            {
                // por definir
            }
            //derecha-arriba
            if ((sucesion.X == inicio.X + 1) && (sucesion.Y == inicio.Y - 1))
            {
                if ((area.obtenerSector(new Vector2(inicio.X + 1, inicio.Y)).value == true))
                {
                    Accion = "saltarDer";
                }
                else
                {
                    Accion = "avanzarDer";
                }
            }
            //derecha-abajo
            if ((sucesion.X == inicio.X + 1) && (sucesion.Y == inicio.Y + 1))
            {
                Accion = "avanzarDer";
            }
            //izquierda-arriba
            if ((sucesion.X == inicio.X - 1) && (sucesion.Y == inicio.Y - 1))
            {
                if ((area.obtenerSector(new Vector2(inicio.X - 1, inicio.Y)).value == true))
                {
                    Accion = "saltarIzq";
                }
                else
                {
                    Accion = "avanzarIzq";
                }
            }
            //izquierda abajo
            if ((sucesion.X == inicio.X - 1) && (sucesion.Y == inicio.Y + 1))
            {
                Accion = "avanzarIzq";
            }
            //reff = item;
            // asigna los valores de las posiciones al agente y al player
            posPlayer = final;
            posAgent  = inicio;

            return(Accion);
        }