public ColumnasAER(String accion, Bloque estado, int frecuencia, float valor) { this.accion = accion; this.estado = estado; this.frecuencia = frecuencia; this.valor = valor; }
// --- 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); }
// 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); }
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); }
// --- 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(); }
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(); }
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; }
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); }
// --- 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(""); }
// --- 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); }
// 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); }
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); }
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); }
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(); }
// --- 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); }
// --- 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); }
//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); }
// --- 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); } }
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>(); } }
public abstract void Sensor(Bloque area);
// --- 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); }
// --- 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); }