/
Inicio :: Foros

 F.A.Q.F.A.Q.                  Conéctese para revisar sus mensajesConéctese para revisar sus mensajes   

Problema con el _kbhit()

 
      Índice del Foro elrincondelc.com -> Principiantes C/C++
Ver tema anterior :: Ver siguiente tema  
AutorMensaje
Kiba



Registrado: 30 Oct 2007
Mensajes: 1

MensajePublicado: 30/10/2007 10:41 am
Título: Problema con el _kbhit()

Estoy seguro de k tengo un error bastante estupido, pero no lo veo.
Estoy intentando acer un programa k es una praktika para acer un tetris (es una simulacion d una sola pieza, son las "preparaciones" para el proyekto final) y necesito meter la funcion _kbhit() para k la ficha baje sola. Esta ficha no es mas k un kuadrado k va bajando sin salirse de los limites del tablero con la posibilidad de chokar kon otra pieza al final.

Al parecer no se usar bien esa funcion pk no para de imprimir la misma posicion una y otra vez. Aquí os dejo el codigo, las teklas k funcionan kon el programa son las izquierda y derecha del kursor y la ESC
Código:

#include <stdio.h>
#include <math.h>
#include <time.h>
#include <stdlib.h>
#include <conio.h>

#define KEY_LEFT 75
#define KEY_RIGHT 77
#define KEY_ESC 27

#define max_files 10
#define max_colum 5

int NumAleatori(int max)
{
   int num;
   num=((int)ceil(((double)rand()/RAND_MAX)*(max+1)))%(max+1);
   return num;
}

void main()

{
   int F_final[max_colum];
    int tecla, i, pos_col, pos_fila, stop;
   char repetir;

   srand( (unsigned)time( NULL ) );
   
   do
   {
      for(i=0;i<max_colum;i++)
      {
         F_final[i]=NumAleatori(1); //col·loquem les altres posibles peces aleatoriament a la ultima fila.
      }

      fflush(stdin);
      pos_fila=1;
      stop=0;
      pos_col=NumAleatori(max_colum-1); // Manera de fer la crida de la funció numero aleatori: n = NumAleatori(100);
      do
      {
         printf("Posicio actual de la fitxa (fila-columna): %d, %d\n",pos_fila,pos_col);
         if(_kbhit())
         {
            tecla=_getch();
            switch (tecla)
            {         
               case 27:   stop=1;
                        break;

               case 75:   if (pos_col>0)
                           pos_col--;
                        break;    
      
               case 77:   if (pos_col<max_colum-1)
                           pos_col++;
                        break;    
      
               default:   printf(" Tecla desconeguda...\n");
                        break;
            }
            pos_fila++;

         }
      }while(pos_fila<max_files && stop==0);

      if(stop==1)
         printf("Has detingut el simulador abans d'arribar abaix\n");

      else if(F_final[pos_col]==1)
         printf("Has colisionat amb una fitxa. Posicio final: %d, %d\n", pos_fila-1,pos_col);

      else
         printf("Has arribat al final del tauler. Posicio final: %d, %d\n", pos_fila,pos_col);
      
      printf("Tornar a repetir el simulador? (S/N)");
      scanf("%c",&repetir);
      printf("\n\n");
   }while((repetir=='s')||(repetir=='S'));
}

Olvide decir k el programa tiene los mensajes en katalan..., en fin, solo dice en k posicion del tablero esta la ficha.
Thx!
Volver arriba
rir3760



Registrado: 01 Oct 2004
Mensajes: 3650
Ubicación: Mexico

MensajePublicado: 30/10/2007 4:30 pm
Título:

Algo que se ve muy mal en tu programa es definir constantes simbolicas mediante directivas define:
Código:
#define KEY_LEFT 75
#define KEY_RIGHT 77
#define KEY_ESC 27

Y no utilizarlas en el bloque switch:
Código:

case 27:
   stop = 1;
   break;
case 75:
   if (pos_col>0)

/* ... */


Un error importante en el programa es que no defines una accion si no se ha pulsado una tecla (en este caso _kbhit retornaria falso, esto es, el valor cero). Debido a esto cada vez que se ejecuta este bloque en tu programa:
Código:
do {
   printf("Posicio actual de la fitxa (fila-columna): %d, %d\n",pos_fila,pos_col);
   
   if (_kbhit()){
      tecla=_getch();
     
      switch (tecla){
      case 27:
         stop = 1;
         break;
      case 75:
         if (pos_col>0)
            pos_col--;
         break;   
      case 77:
         if (pos_col<max_colum-1)
            pos_col++;
         break;
      default:
         printf(" Tecla desconeguda...\n");
         break;
      }
     
      pos_fila++;
   }

}while (pos_fila<max_files && stop==0);

Si no se ha presionado una tecla el bucle se repite y es la causa de que se presente el "prompt" una y otra vez. Debes utilizar una sentencia if ... else donde verifiques el valor de retorno de _kbhit y si este es falso (no hay tecla presionada) se realize alguna accion, lo usual es que la pieza descienda.

Un saludo
_________________
The capacity to learn is a gift;
The ability to learn is a skill;
The willingness to learn is a choice.
--
Rebec of Ginaz
Volver arriba
mamntc02



Registrado: 30 Abr 2007
Mensajes: 238

MensajePublicado: 31/10/2007 5:47 am
Título:

Hola,

Hay otra cosilla q creo q hará q tu programa no funcione correctamente. Las teclas de dirección, al igual q las teclas de función, son teclas 'especiales'. Las teclas 'especiales' devuelen un 'código compuesto' q se debe recoger mediante dos llamadas a getch(). La primera sirve para saber si la tecla es especial o no (si es 0 ó 224), y la segunda no dice qué tecla especial és. Por ejemplo:
Código:
#include <stdio.h>
#include <conio.h>

int main(){

   printf("Presiona teclas para saber cuales son... ESC para salir \n\n");
   
   while(1){
      int valor = getch();
      
      if(valor == 0 ||valor == 224){ //Tecla extendida
         printf("Has presionado una tecla extendida %d con valor de extendida: %d\n", getch(), valor);
      }
      else{
         if(valor == 27){ // Tecla ESC
            printf("Has presionado ESC... Saliendo\n");
            break;
         }
         else
            printf("Has presionado la tecla %c con valor %d\n", valor, valor);
      }
   }      
}

Como puedes ver en el código puede q al hacer el primer getch() y decidir si la tecla es extendida, éstas pueden ser 224 ó 0. No recuerdo el pq de esta diferenciación, pero creo q las teclas de función, cambinaciones con ALT ó ALT GR, y alguna otra devuelven 0; y las teclas de dirección devuelven 224. Procura confirmarlo.

Como último, y se ha insistido mucho (yo entre ellos) q es mejor no usar conio, por no ser estandard, me iría a la API de Windows. Échale un vistazo a este artículo de introducción de creación de juegos a ver si te sirve, para el control del teclado.

Saludos.
Volver arriba
david_celta



Registrado: 02 Jun 2005
Mensajes: 45

MensajePublicado: 31/10/2007 9:52 pm
Título:

El problema(aparte de lo mencionado) puede ser que se usa un if(kbhit()) en vez de un while(kbhit())

con el while(kbhit()) podrias mantener la ficha cayendo mientras no se pulse ninguna tecla, una vez se pulse alguna alguna tecla saldrá del while y podras comprobar que tecla se pulsó

Código:


while(kbhit())
{
   //proceso para que la ficha caiga
}

//en esta linea ha salido del while porque se pulso una tecla
//capturamos la tecla que se ha pulsado

tecla=getch();

//aqui se deberia validar el codigo extendido haciendo otro getch o verificando si el primer getch devolvio 0
//...

if(tecla=flecha_izquierda)
{
   //procedimiento con la flecha izquierda
}
else if(tecla=flecha_derecha)
{
   //procedimiento con la flecha derecha
}
//...



Por supuesto que todo esto dentro de un while o do-while general que me parece ya definiste (el while que dice algo de posmax seria el while general)

Diferencias entre usar IF y usar WHILE
Logica de programacion
Prueba y Error
_________________
Este es un bloque de texto que se puede agregar a los mensajes que publique. Texto Compilado en C++. 0 errors y 1 un warning.
Volver arriba
      Índice del Foro elrincondelc.com -> Principiantes C/C++
Página 1 de 1Todas las horas están en GMT - 8 Horas

 
No puede crear mensajes
No puede responder temas
No puede editar sus mensajes
No puede borrar sus mensajes
No puede votar en encuestas

(c) ElRincondelC.com

Un proyecto de UrlanHeat.com