elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Estamos en la red social de Mastodon


  Mostrar Mensajes
Páginas: 1 ... 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 [18] 19 20 21 22 23 24 25 26
171  Programación / Programación C/C++ / Re: [SOLUCIONADO] Generar nombre aleatorio. en: 10 Marzo 2014, 01:11 am
Hola a todos. Creo que al programilla le falta la parte donde decide quién ganó (o quizá yo no la vi, sorry). Como un switch() anidado con las nueve posibilidades sería muy tedioso es más cómodo definir una matriz de 3x3, donde la opción 1 representa tijera, 2 la piedra, 3 el papel. En la posición (i,j) de la matriz se pone:
  • 1, si i le gana a j
  • -1, si i pierde ante j
  • 0, si son iguales y hay empate

Así por ejemplo, para el caso de la tijera, como empata consigo misma, pierde ante piedra y gana ante papel, la primera fila de la matriz debe ser {0, -1, 1}. El programa inspecciona el elemento de la matriz, y ahí sabe si usted ganó, perdió o empató.

En la primera parte del programa el usuario elige tijera, piedra o papel pulsando '1', '2' ó '3' (más cómodo que escribir el nombre completo), y este valor entero se deposita en la variable human_op. Luego, elige la máquina al azar usando rand() y srand(), y su valor se deposita en machine_op. Como ya se explicó, el valor de A[human_op - 1][machine_op - 1] dará la respuesta.

Al final, te pregunta si quieres jugar de nuevo y así sucesivamente. Confieso que yo mismo me puse a jugar contra la máquina y casi me envicio, jajaja  >:D.

Un detalle, la función clear_screen() está codificada para Windows y para Linux. En Windows debes dejar la línea system("cls") y comentariar  system("clear"), mientras en Linux se hace al revés. La versión que pongo aquí está para Windows:

Código
  1. #include <cstdlib>
  2. #include <iostream>
  3. #include <time.h>
  4.  
  5. void clear_screen( void );
  6.  
  7. using namespace std;
  8.  
  9. int main () {
  10.  
  11.    string human, machine;
  12.    int human_op = 0;        /* 1: tijera, 2: piedra, 3: papel */
  13.    int machine_op = 0;
  14.    char next;                /* next == 's' indica que se quiere seguir jugando */
  15.  
  16.    /* Declarar matriz de casos:
  17.      *
  18.      * 1: tijera, 2: piedra, 3: papel
  19.      *
  20.      * El elemento (i,j) vale:
  21.      *   1 si "i le gana a j"
  22.      *  -1 si "i pierde ante j"
  23.      *   0 si hay empate
  24.      */
  25.    int A[3][3] = {{0, -1, 1}, {1, 0, -1}, {-1, 1, 0}};
  26.  
  27.    /* inicializar semilla */
  28.    srand( time(NULL) );
  29.  
  30.    do {
  31.  
  32.        /* El humano elige */
  33.        do {
  34.            clear_screen( );        /* borrar pantalla */
  35.            cout << "Juego piedra, papel o tijera ..." << endl << endl
  36.                << "1: tijera" << endl
  37.                << "2: piedra" << endl
  38.                << "3: papel" << endl << endl
  39.                << "elige: ";
  40.            cin >> human_op;
  41.        } while ( human_op < 1 || human_op > 3 );
  42.        switch ( human_op ) {
  43.            case 1:
  44.                human = "tijera";
  45.                break;
  46.            case 2:
  47.                human = "piedra";
  48.                break;
  49.            case 3:
  50.                human = "papel";
  51.                break;
  52.        }
  53.  
  54.        /* La maquina elige */
  55.        machine_op = rand( ) % 3 + 1;
  56.        switch ( machine_op ) {
  57.            case 1:
  58.                machine = "tijera";
  59.                break;
  60.            case 2:
  61.                machine = "piedra";
  62.                break;
  63.            case 3:
  64.                machine = "papel";
  65.                break;
  66.        }
  67.  
  68.        /* Ahora se decide quien gana */
  69.        cout << endl << "Usted elige: " << human << endl
  70.            << "La maquina elige: " << machine << endl << endl
  71.            << "... ";
  72.        switch ( A[human_op - 1][machine_op - 1] ) {
  73.            case 1:
  74.                cout << "Usted gana !!!" << endl;
  75.                break;
  76.            case -1:
  77.                cout << "Ups, usted pierde" << endl;
  78.                break;
  79.            case 0:
  80.                cout << "Empate" << endl;
  81.                break;
  82.        }
  83.  
  84.        /* Seguir jugando ? */
  85.        cout << "Seguir jugando s/n? ";
  86.        cin >> next;
  87.    } while ( next == 's' );
  88. }
  89.  
  90. /* Borra la pantalla */
  91. void clear_screen( void ) {
  92.  
  93.    /* para Windows */
  94.    system( "cls" );
  95.    /* para Linux */
  96.    //system( "clear" );
  97. }
172  Programación / Programación C/C++ / Re: Biblioteca de matriz de cadenas en: 9 Marzo 2014, 23:59 pm
Totalmente de acuerdo, y con respecto a " lagunas de memoria, accesos a memoria no reservada o desbordamientos de buffer", te cuento que sí que tuve muchos dolores de cabeza con eso, pues me ocurría en las primeras versiones del código.

La verdad, este fue un ejercicio más que todo para aprender, pues como dices en una aplicación real lo más lógico es usar STL pues se vuelve más fácil de comprender y mantener.

Hacía tiempo quise ponerme a "inventar", y emular clases con C pero me encontré algunos problemas. Por ejemplo, tengamos la clase circle (círculo) con sus miembros x, y, radious, cuyos significados son obvios. Ahora queremos definir el método setX para cambiar el valor del miembro x. Claro, no son clases verdaderas, sino la emulación de éstas en C.

En C++ las clases mantienen su espacio privado de nombres de métodos, por lo que debemos usar el operador :: para acceder a ellos. No sucede lo mismo en C, donde hay que usar funciones "sueltas". Una idea sería prefijar los nombres de los métodos con el nombre de la clase, algo como:

CIRCLE_setX( double new_x, circle * this)

aunque aún es un poco burdo. No se si es lo mejor que se puede hacer a costa de mantenerse puro dentro de C, o se puede mejorar un poquito.
¿Acaso podemos ser creativos e inventar algo con #define para volverlo más amigable?

A ver, ¿cómo hacían los programadores antiguos, cuando no había aparecido C++?
173  Programación / Programación C/C++ / Re: No funciona timer en Linux en: 9 Marzo 2014, 23:45 pm
Mmmm, entonces la implementación es diferente que en Windows. En Windows el tiempo sí transcurre a pesar de getchar(). Curioso (?!)

Probé este otro, que imprime "1 ... " y espera 3 segundos antes de imprimir "2". Éste sí funciona en Linux de la manera esperada:

Código
  1. #include <stdio.h>
  2. #include <time.h>
  3.  
  4. int main( ) {
  5.  
  6. clock_t t1, t2;
  7. int i, j, k;
  8.  
  9. t1 = clock();
  10. printf( "1 ... " );
  11.        fflush( stdout );
  12. do {
  13. t2 = clock();
  14. } while ( (double)(t2 - t1)/CLOCKS_PER_SEC < 3 );
  15. printf( "2" );
  16. }
174  Programación / Programación C/C++ / Re: encontrar el ultimo valor de la matriz recorrida en: 9 Marzo 2014, 23:30 pm
Igualmente un gran abrazo hermano, aprecio tu solidaridad !!!!!!!!!  ;D

Ah, el pastebin es porque como es un código largo, para no embasurar el foro, pero también se puede poner aquí ...

Mira, pero me pusiste la bandera "izquierdista", con 8 estrellas y el caballo andando a la izquierda, jaja. Tienes que poner ésta  :laugh:

175  Programación / Programación C/C++ / Re: Matriz Dinamica en c++. Como rellenarla en coordenadas especificas? en: 9 Marzo 2014, 21:27 pm
Hola María. Compatriota!!!, entiendo tu situación pues también soy de Vzla y es triste la situación que vivimos. Los poderosos explotando a los débiles  >:(, no importa el lado político en que se midan.

Ok, vamos por partes. Una primera recomendación sería declarar las variables contador i, j al principio del main(), y no dentro de cada ciclo. Así:

int i, j;

y de este modo ya puedes escribir

for (i = 0; i < dim; i++)

sin tener que poner "int" dentro del for. Me tomé el atrevimiento de cambiar el nombre "matriz" por "dim" porque me pareció más acorde con el significado o intención de esa variable, que es representar la dimensión de la matriz.

En esta primera parte del programa pides al usuario el tamaño o dimensión del tablero, y luego creas la matriz dinámicamente. Al principio la matriz se rellena toda con ceros, luego el programa te va pidiendo que le indiques dónde van las minas. Le indicas un '1' para decir que hay una mina en la posición indicada, o un '0' para decir que no hay mina.

Ahora creo que señalaste el problema de que es muy fastidioso preguntar por todas las casilla si sólo van 2 ó 3 bombas. Primero recuerda que el programa te tiene que pedir todas las coordenadas, ya que las minas podrían en cualquier parte. Sin embargo, si terminaste de declarar las minas antes de recorrer toda la matriz, introduce un 'x' ó un 'q' para terminar el ciclo. Eso se hace con la parte:

else if ( c == 'q' || c == 'Q' || c == 'x' || c == 'Q' )
   listo = 1;

La otra forma de trabajar sería que el programa no te pregunte por todas y cada de una de las casillas sino que te pida coordenada i, coordenada j, y valor. Ahora, yo creo que esta segunda opción sería incluso más fastidiosa (!?).

Otra manera más sería que el programa rellenara las minas aleatoriamente, también podemos hacerlo así, depende de los requerimientos de diseño, de cómo lo quieres hacer y si profesor ha puesto alguna clase de límites o condiciones.

La siguiente parte del código es donde se imprime la matriz, indicando con '*' donde hay bomba, y '0' donde no hay.

Ahora, por otra parte el programa de leosansan está muy completo, aunque no se si lo has leído, si quieres basarte en él, o si lo pudiste entender.

Unas preguntas o comentarios:
  • ¿Trabajas en Windows o Linux?
  • ¿Te permiten usar getch()?
  • Si es en Windows, ¿te permiten usar la biblioteca conio?
  • ¿Se puede usar simplemente C en lugar de C++? Me parece que la complejidad del programa no exige C++ (no lleva clases)
  • Finalmente quiero comentar que para mí la matriz puede ser de char, o de int, indistintamente. Al fin y al cabo almacena números (ceros o unos).

Aquí el código de la primera parte, que es simplemente la correción de unos pequeños detalles del que hiciste:
Código
  1. #include <iostream>
  2. #include <string>
  3.  
  4. using namespace std;
  5.  
  6. int main()
  7. {
  8.   int dim, bomba='*', valor;
  9.   int i, j;      /* <-- declara aqui, no dentro del ciclo */
  10.   char c;
  11.   char listo;
  12.  
  13.   cout << time(NULL);
  14.   return 0;
  15.  
  16.   cout << "Tamano de la matriz: ";
  17.   cin >> dim;
  18.   cout << endl;
  19.  
  20.   /* creamos la matriz, y rellenamos con ceros */
  21.   char **M = new char *[dim];
  22.   for (i = 0; i != dim; i++)
  23.      M[i] = new char [dim];
  24.  
  25.   for (i = 0; i < dim; i++)
  26.      for (j = 0; j < dim; j++)
  27.         M[i][j] = '0';
  28.  
  29.   /* poniendo posiciones de las minas */
  30.   listo = 0;
  31.   for (i = 0; i < dim && listo == 0; i++) {
  32.      for (j = 0; j < dim && listo == 0; j++) {
  33.         cout << endl << "Posicion [ " << i << " ] [ " << j << " ]: ";
  34.         cin >> c;
  35.         if ( c == '1' )
  36.            M[i][j] = '1';
  37.         else if ( c == 'q' || c == 'Q' || c == 'x' || c == 'Q' )
  38.            listo = 1;
  39.      }
  40.   }
  41.  
  42.   // mostrar matriz
  43.   cout << endl << "La matriz es:" << endl;
  44.   for (i = 0; i != dim; i++) {
  45.      for (j = 0; j != dim; j++)
  46.         if ( M[i][j] == '1')
  47.            cout << "*\t";
  48.         else
  49.            cout << "0\t";
  50.      cout << endl;
  51.   }
  52.  
  53.   // destruye la matriz
  54.   for (i = 0; i != dim; i++)
  55.     delete[] M[i];
  56.   delete[] M;
  57.  
  58.   return 0;
  59. }
176  Programación / Programación C/C++ / Re: Recibir int seguro en: 9 Marzo 2014, 17:48 pm
Una recomendación a ivance96. Para que el código sea más portable, recordemos que los tipos enteros no tienen una longitud rígidamente definida, por ejemplo en algunas máquinas (antiguas) los enteros son de 16bits, y en otras de 32bits. Si mal no recuerdo, la norma indica que la longitud de int debe estar entre la longitud de short y la de long, pero la elección entre ambos depende de la implementación. Debiendo ser la longitud de short de al menos 16 bits, y la de long de al menos 32 bits. Así que por ejemplo una implementación en particular (quizá en el futuro, para una máquina potente) pudiera tener short de 32 bits, int de 64 bits y long de 64 bits.

La biblioteca <limits.h> define los máximos posibles para los distintos tipos aritméticos según la puesta en práctica. Por ejemplo, CHAR_MAX, SHRT_MAX, UINT_MAX define los máximos de char, short int y unsigned int respectivamente, y son valores que dependen de la implementación de C en tu máquina particular. Así que el programa podría quedar algo así como:
Código
  1. /** INT && UINT **/
  2. if(s[0]=='-')
  3. sign=true;
  4. if ( allNumeric(s.substr(sign, s.size()))) {
  5. if(sign) {
  6.   if ( atoi(s.substr(1, s.size())) <= INT_MAX  )
  7. type+=type_int;
  8. }else{
  9. if ( atoi(s.substr(0, s.size())) <= INT_MAX )
  10. type+=type_int;
  11. if ( atoi(s.substr(0, s.size())) <= UINT_MAX)
  12. type+=type_uint;
  13. }
  14. }

el cual es transportable sin problemas de una máquina a otra.
177  Programación / Programación C/C++ / No funciona timer en Linux en: 9 Marzo 2014, 17:34 pm
Hola, preciso ayuda de los Linuxeros. Este sencillo código (que mide el tiempo transcurrido entre el inicio del programa y la pulsación de ENTER) no funciona como debe en Linux. En Windows lo probé y está Ok.

El problema es que clock() devuelve siempre cero (0), tanto para t1 como para t2, y por eso no mide el tiempo. ¿Qué es lo que le falta "ajustar" para que funcione en plataformas Linux y/ similares?

Código
  1. #include <stdio.h>
  2. #include <time.h>
  3.  
  4. int main( ) {
  5.  
  6. clock_t t1, t2;
  7.  
  8. t1 = clock();
  9. getchar();
  10. t2 = clock();
  11. printf("Han transcurrido %.2lf s\n", (double)(t2 - t1)/CLOCKS_PER_SEC );
  12.  
  13. }
178  Programación / Programación C/C++ / Re: [C] Rombo con asteriscos en: 9 Marzo 2014, 17:28 pm
Ok, el triángulo de Pascal, pero exactamente qué se te ocurre hacer?? Acepto el reto, jeje (claro, en un nuevo post) ...
179  Programación / Programación C/C++ / Re: Recibir int seguro en: 9 Marzo 2014, 17:26 pm
Ah, leosansan pero es mi intención fue precisamente recibir una cadena de 3 o menos dígitos. O sea, si aceptamos en forma estricta la longitud y el número fuera 12 tendrías que escribir 012, que es un fastidio, puff

Una solución sería definir un búfer más grande (por ello la constante N), digamos de 10 o 20 caracteres, así el usuario dispone de todos esos espacios para escribir su número (grande o pequeño). Ahora si él se equivoca tecleado el número, es culpa de él, jajajajajajaja

La otra opción de que sea una cantidad fija de dígitos, ni más ni menos, también puede ser deseable. Eso depende de cómo el diseñador quiera presentar la interfaz de su programa, y de la aplicación que involucre. Si por ejemplo vas a meter un cifra cuya cantidad de dígitos se conoce con exactitud (cédula de identidad, código de un producto en un almacén, o el carnet de un trabajador) vale el segundo enfoque. Pero si la longitud es variable y desconocida vale el primer enfoque con un búfer tan grande como la máxima longitud admisible.

Ya eso depende del caso que se quiera trabajar ..... Y saludos como siempre  :D
180  Programación / Programación C/C++ / Re: encontrar el ultimo valor de la matriz recorrida en: 9 Marzo 2014, 16:55 pm
Jajaja, ¿MS-DOS?. De buena intención te digo que deberías aventurarte a conocer el Linux, cuando lo domines no querrás dejarlo. Te voy a poner un ejemplo, quieres inspeccionar en el directorio actual todos los ficheros cuyo nombre empieza con "abc" y hayan sido modificados hace menos de 10m. Con una simple orden bash (la consola de Linux):

find . -name "abc*" -mmin -10

¿y cómo lo harías así de rápido en Win?

Bueno pero volviendo al tema, al final quedé un poco frustrado porque no logré el comportamiento deseado. Me hubiera gustado que la bola siguiera un movimiento continuo en una dirección dada y al pulsar una tecla de flecha cambiara la dirección. Pero esto tiene un inconveniente, y es que la pulsación de dichas flechas sería asíncrona, es decir, no sabes cuándo va a suceder. Si haces algo como:

Sleep(500);
c = getch();

sería un error porque se quedaría "colgado" tras cada movimiento pidiendo tecla.

Lo ideal aquí sería un "servicio" o "demonio", es decir un programa que corre paralelo al principal, en segundo  plano, y su labor sería inspeccionar si hay caracteres no leídos en el búfer de teclado. En ese caso, los extrae e interpreta: si es un carácter de flecha, cambia la dirección de la bola. Si no hay caracteres disponibles no hacer nada.

Hasta lo que tengo entendido la función getch() no funciona de este modo porque es "bloqueante", es decir bloquea el programa llamador hasta que se reciba un carácter. En los sistemas conformes a POSIX este comportamiento se puede modificar para que espere un tiempo dado y de no recibir carácter en ese lapso, devuelva al programa principal. En Windows realmente no se cómo se pude imitar este comportamiento (aunque de seguro se puede), imagino que un manera sería crear un "servicio" que inspeccione continuamente el teclado y deposite los caracteres en un búfer virtual. De esta manera al no recibir tecla se bloquearía el programa servicio y no el programa principal.

Finalmente, y para curar en salud, elegí quitar la pausa y pedir tecla siempre  :rolleyes:
O sea, la pelotita se mueve sólo un paso a la vez. Tienes que teclear y teclear para moverla por todo el tablero. Por otro lado, y como no recuerdo la codificación de la teclas de flecha en Windows, decidí hacerlo con las teclas del teclado numérico:

8:  arriba
2:  abajo
4:  izq
6:  der

Si sabes los códigos de las teclas de flecha en Win, modifica el programa en la parte de getch(). En Linux (como es conforme al estándar ECMA) estas teclas se codifican de manera diferente, como "secuencias de escape". De hecho, es bueno saber que supuestamente el único sistema que no acepta secuencias de escape es Windows (?!), o sea, Win es la excepción y no la regla (aunque esa "excepción" copa el 90% del mercado!)

Volviendo al tema, el juego termina cuando hayas alcanzado la fila inferior del tablero, o te hayas excedido del máximo posible de movimientos (le puse un límite de 100, jeje). Sería bueno modificar el tablero para hacer una especie de laberinto ...

El código es multiplataforma, se puede compilar en Linux y en Windows. Para el primer caso debes definir la macro _LINUX, y para el segundo define _WIN. Lo más cómodo es por supuesto en la orden de compilación:

Windows: gcc -o tablero tablero.c -D_WIN
Linux:   gcc -o tablero tablero.c -D_LINUX


Pruébalo y me comentas si le añadimos o quitamos algo (sólo modifiqué la opción 2 del programa, no toqué ni la 3 ni la 4).

NOTA. El parámetro blocked parece redundante (no hace nada) pero está porque en un principio quería hacer que al quedarse bloqueado pidiera tecla para cambiar la dirección, pero como comenté anteriormente no pude al menos en este primer intento.

Aquí el código fuente (pastebin): http://pastebin.com/fDweNAsf
Páginas: 1 ... 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 [18] 19 20 21 22 23 24 25 26
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines