Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Problemas raros con una IA muy basica

Iniciado por _16BITGuy_, 16 de Febrero de 2007, 06:58:32 PM

« anterior - próximo »

_16BITGuy_

Muy buenas, al fin me presento aqui en stratos, soy _16BITGuy_ como ya pone el nick xD tengo 16 años y me tendreis por aqui durante un buen rato jeje, bueno, el caso de por que posteo esto es que tengo un problema raro..

vereis, estoy desarrollando mi primer videojuego desde cero, con C y Allegro, un pong bastante simplon, pero para empezar me sirve ¿no? :P

El caso es que he desarrollado una IA, bueno casi ni es ia, es muy muy basica, simplemente se comprueba la posicion de la bola en eje y y si esta mas arriba que la raqueta del cpu, se asigna una velocidad vertical de -2, y si es al contrario (esta mas abajo) pues 2, en el caso de poder colisionar con la raqueta pues la velocidad es 0, de esta forma:
(sBola es la estructura de tipo OBJETO que contiene informacion de la bola, que es x,y,vx,vy. sPaddle1 y sPaddle2 son de las raquetas, de tipo OBJETO tambien, siendo sPaddle2 la estructura de la raqueta que controla el CPU)

//--Inteligencia artificial de CPU
   if(eJuego.modo == MOD_JUGVSCPU)//Si estamos en modo contra cpu
   {
       if(sBola.y > sPaddle2.y + bPaddle->h && sBola.x + bBola->w > SCREEN_W/3)
       {
           sPaddle2.vy = 2;
       }
       if(sBola.y < sPaddle2.y && sBola.x + bBola->w > SCREEN_W/3)
       {
           sPaddle2.vy = -2;
       }
       if(sBola.y > sPaddle2.y && sBola.y < sPaddle2.y + bPaddle->h && sBola.x + bBola->w > SCREEN_W/3)
       {
           sPaddle2.vy = 0;
       }
   }

Esto, pienso yo que deberia hacerlo sin problemas, pero lo que ocurre, es que cuando la raqueta de la cpu no llega a la bola, esta aumenta de velocidad, y yo para nada he programado eso! ¿como es posible?
Ojalá podais ayudarme, un saludo!

Yoshi.css

Deberías usar else if en lugar de if a secas cuando hay diferentes opciones.

También deberías utilizar paréntesis cuando las sentencias condicionales son un poco rebuscadas. Ahora no me acuerdo de las preferencias de los operadores, pero es posible que te falle por eso (que la comparación && se haga antes que la suma, por ejemplo).
Tu código debería quedar más o menos como ésto:

if(eJuego.modo == MOD_JUGVSCPU)//Si estamos en modo contra cpu
   {
       if((sBola.y > (sPaddle2.y + bPaddle->h)) && (sBola.x + bBola->w) > SCREEN_W/3))
       {
           sPaddle2.vy = 2;
       }
       else if((sBola.y < sPaddle2.y) && ((sBola.x + bBola->w) > SCREEN_W/3))
       {
           sPaddle2.vy = -2;
       }
       else if((sBola.y > sPaddle2.y) && (sBola.y < (sPaddle2.y + bPaddle->h)) && ((sBola.x + bBola->w) > SCREEN_W/3))
       {
           sPaddle2.vy = 0;
       }
   }

_16BITGuy_

pues no me resuelve el problema :S, de todas formas si hubiese sido de algo de eso, no hubiera aumentado la velocidad puesto k lo k se hace si se cumple la condicion es uan asignacion de velocidad no un aumento.

Un Saludo!

_16BITGuy_

dejo el codigo entero del procedimiento logico del juego, esto se ejecuta por cada ciclo del juego.

void logica()
{
   if(eJuego.j1puntos == 10 || eJuego.j2puntos == 10)
   {
       if(key[KEY_ENTER])eJuego.estado = EST_TERMINANDO;
       return;
   }
   
   if(eJuego.estado == EST_ESPERANDO_RESPUESTA)
   {
       if(key[KEY_SPACE])
       {
          sBola.vx = -4;
          sBola.vy = 0;
          eJuego.estado = EST_JUGANDO;
       }
   }
   if(eJuego.estado == EST_PUNTO_J1)
   {
       if(key[KEY_ENTER])
       {
           eJuego.estado = EST_JUGANDO;
           sBola.vx = -4;
           sBola.vy = 0;
       }
   }
   if(eJuego.estado == EST_PUNTO_J2)
   {
       if(key[KEY_ENTER])
       {
           eJuego.estado = EST_JUGANDO;
           sBola.vx = 4;
           sBola.vy = 0;
       }
   }
           
             
   //Recojer pulsaciones de teclado y ajustar la velocidad segun cada caso
   if(key[KEY_W]) sPaddle1.vy = -2;    
   if(key[KEY_S]) sPaddle1.vy = 2;
   if(eJuego.modo == MOD_DOSJUG)
   {
       if(key[KEY_O]) sPaddle2.vy = -2;
       if(key[KEY_L]) sPaddle2.vy = 2;
   }
   
   //INTELIGENCIA ARTIFICIAL DE CPU
   if(eJuego.modo == MOD_JUGVSCPU)//Si estamos en modo contra cpu
   {
       if((sBola.y > (sPaddle2.y + bPaddle->h)) && ((sBola.x + bBola->w) > SCREEN_W/3))
       {
           sPaddle2.vy = 2;
       }
       else if((sBola.y < sPaddle2.y) && ((sBola.x + bBola->w) > SCREEN_W/3))
       {
           sPaddle2.vy = -2;
       }
       else if((sBola.y > sPaddle2.y) && (sBola.y < (sPaddle2.y + bPaddle->h)) && ((sBola.x + bBola->w) > SCREEN_W/3))
       {
           sPaddle2.vy = 0;
       }
   }
   

   //Crear Movimiento
   //-Calcular vx y vy
   //--Para los Paddles(Raquetas)
   if(sPaddle1.y > (SCREEN_H - bPaddle->h) || sPaddle1.y < 0){
      if(sPaddle1.y > (SCREEN_H - bPaddle->h))
      {
           if(sPaddle1.vy == 2) sPaddle1.vy = 0;
      }
      if(sPaddle1.y < 0)
      {
           if(sPaddle1.vy == -2) sPaddle1.vy = 0;
      }
       
   }
   
   if(sPaddle2.y > (SCREEN_H - bPaddle->h) && sPaddle2.y < 0){
      if(sPaddle2.y > (SCREEN_H - bPaddle->h))
      {
           if(sPaddle2.vy == 2) sPaddle2.vy = 0;
      }
      if(sPaddle1.y < 0)
      {
           if(sPaddle2.vy == -2) sPaddle2.vy = 0;
      }
       
   }    
   
   //--Para la bola
   
   //--bola--eje x
   if(sBola.x >= SCREEN_W)
   {
       eJuego.j2puntos = eJuego.j2puntos + 1;
       eJuego.estado = EST_PUNTO_J1;
       nuevo_saque();
   }
   if(sBola.x + bBola->w <= 0)
   {
       eJuego.j1puntos = eJuego.j1puntos + 1;
       eJuego.estado = EST_PUNTO_J2;
       nuevo_saque();
   }
   //--bola--eje y
   if(sBola.y >= SCREEN_H - bBola->h)
   {
        sBola.vy = sBola.vy * -1;
   }
   if(sBola.y <= 0)
   {
        sBola.vy = sBola.vy * -1;
           
   }
   //COLISIONES
   //-Choque bola con Paddle 1
   
   
   if(sBola.x >= sPaddle1.x && sBola.x <= sPaddle1.x + bPaddle->w && sBola.y + bBola->h >= sPaddle1.y && sBola.y <= sPaddle1.y + bPaddle->h)
   {
       if(sBola.toque == 0)
       {
           sBola.vx = sBola.vx * -1;
           if(sBola.y + bBola->h >= sPaddle1.y && sBola.y <= sPaddle1.y + (bPaddle->h/3))
           {
               sBola.vy = -1;
           }
           if(sBola.y + bBola->h >= sPaddle1.y + (bPaddle->h/3) && sBola.y <= sPaddle1.y + 2*(bPaddle->h))
           {
               sBola.vy = 0;
           }
           if(sBola.y + bBola->h >= sPaddle1.y + 2*(bPaddle->h/3) && sBola.y <= sPaddle1.y + bPaddle->h)
           {
               sBola.vy = 1;
           }
           sBola.toque = 1;
       }
   }
   else{
       sBola.toque = 0;
   }
   //-Choque bola con Paddle 2
   
   if(sBola.x + bBola->w >= sPaddle2.x && sBola.x <= sPaddle2.x + bPaddle->w && sBola.y + bBola->h >= sPaddle2.y && sBola.y <= sPaddle2.y + bPaddle->h)
   {
       if(sBola.toque == 0)
       {
           sBola.vx = sBola.vx * -1;
           if(sBola.y + bBola->h >= sPaddle2.y && sBola.y <= sPaddle2.y + (bPaddle->h/3))
           {
               sBola.vy = -1;
           }
           if(sBola.y + bBola->h >= sPaddle2.y + (bPaddle->h/3) && sBola.y <= sPaddle2.y + 2*(bPaddle->h))
           {
               sBola.vy = 0;
           }
           if(sBola.y + bBola->h >= sPaddle2.y + 2*(bPaddle->h/3) && sBola.y <= sPaddle2.y + bPaddle->h)
           {
               sBola.vy = 1;
           }
           sBola.toque = 1;
       }
   }
   else{
       sBola.toque = 0;
   }
   //-Aplicar la velocidad a la posicion
   // Movemos la pelota con la velocidades vx y vy calculadas
   sBola.y = sBola.y + sBola.vy;
   sBola.x = sBola.x + sBola.vx;
   //--Para las raquetas
   if(sPaddle2.vy > 2) sPaddle2.vy = 2;
   if(sPaddle2.vy < -2) sPaddle2.vy = -2;
   sPaddle1.y = sPaddle1.y + sPaddle1.vy;
   sPaddle2.y = sPaddle2.y + sPaddle2.vy;
   //Reestableciendo el dato de velocidad una vez movidos los objetos
   /*
       Esto hace que al soltar los botones de direccion de las raquetas,
       las raquetas se paren, de lo contrario la velocidad segura siendo
       la misma aun soltando los botones
   */
       
   sPaddle1.vy = 0;
   sPaddle2.vy = 0;
   
   
   
}


Fijaros que hago una limitacion de la velocidad antes de aplicarsela a la posición de la paleta (sPaddle2.y), y nisiquiera eso funciona, da que pensar...

1cacalvo

Umm un apuntecillo.. Has probado a debuguear (o como se escriba) y ver en cual de los ifs se mete el programa...

Algo esencial para un programador es saber utilizar a la perfeccion todas las herramientas para el debug..

     Suerte con el pong!!!

hano

Cita de: "1cacalvo"Umm un apuntecillo.. Has probado a debuguear (o como se escriba) y ver en cual de los ifs se mete el programa...

debugear --> http://buscon.rae.es/draeI/SrvltConsulta?TIPO_BUS=3&LEMA=debug
La verdad es que en el trabajo debugear lo utilizamos mucho, :P

Apoyo la moción, es muy importante eso de depurar.
El código lo veo muy complejo para estar en un único método y lo hace lioso de seguir; además, tiene muchas variables incrustadas (hardcodeadas, ya que hablamos en spanglish) que no tienen por qué tener sentido para un programador externo, es decir, hay valores que asignas 0, 1, -1, 2,... que no tienen por qué ser intuitivos.

Lo que yo haría, conservar este código (comentándolo, copiándolo, o cambiando simplemente su nombre) y lo reescribiría desde el principio, poco a poco y probando cada paso.

_16BITGuy_

ya me di cuenta del fallo, la verdad es que e estado conjfundido con una cosa, la velocidad nunca habia aumentado, me parecia Asi, por que a la velocidad como normalmente se movia parecia la programada, y luego aumentaba, en realidad cuando aumentaba iba a su velocidad, el probrema era de reduccion de velocidad, por algun problema de la condicion en los if que le puse, creo que es por que la bola nunca llega a estar dentro del espacio del eje "y" que ocupa la raqueta en ciertos momentos y cuando esta se para, cuando no lo esta sigue y cuando esta de nuevo vuelve a pararse, produciendo esa reduccion de velocidad.
Tendre que pensar en otra formula, otra condicion me refiero, para que esto no ocurra.

Sobre lo de "debugear" o depurar, uso el DevC++ como IDE y lleva un depurador, pero este no me deja ver las variables cuando el programa esta en ejecucion, sino que solo me deja verlo cuando llego a un "break point" de esos, o pongo el modo paso por paso,pero asi no podre ver lo que realmente pasa por que no puedo ir jugando, o ir moviendo las raquetas para que vea que ocurre en cada caso. ¿Como podira hacer esto?

burb

Pasate a Codeblocks, o incluso a Visual C++, o C++ Builder que tienen versiones gratuitas. El Dev prometía pero pasan los años y sigue casi igual que siempre

hano

Cita de: "_16BITGuy_"
Sobre lo de "debugear" o depurar, uso el DevC++ como IDE y lleva un depurador, pero este no me deja ver las variables cuando el programa esta en ejecucion, sino que solo me deja verlo cuando llego a un "break point" de esos, o pongo el modo paso por paso,pero asi no podre ver lo que realmente pasa por que no puedo ir jugando, o ir moviendo las raquetas para que vea que ocurre en cada caso. ¿Como podira hacer esto?

Puedes hace un clásico, un printf que te muestre el valor de las variables.

1cacalvo

Como te comentan por ahi, en estos casos puedes sacar por consola los valores de las variables con un "cout", o incluso si el programa va cogiendo bastante consistencia te puedes hacer un fichero de trazas (log) y vas sacando los valores y estados que en cada caso te hagan falta...


Citar(hardcodeadas, ya que hablamos en spanglish)
No se porque pero parece que eres mejor si en vez de ser programador eres un coder, controlas mas si en vez de depurar debugeas, y no se ponen puntos de control en los programas si no que tenemos breakpoints...

Me imagino que sera por toda la documentación que leemos en Ingles, y que tengamos los entornos de desarrollo la mayoria de nosotros en la lengua de Shakespeare...






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.