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

 

 


Tema destacado: Usando Git para manipular el directorio de trabajo, el índice y commits (segunda parte)


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Duda con juego que genera numeros aleatorios
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Duda con juego que genera numeros aleatorios  (Leído 4,962 veces)
Caster


Desconectado Desconectado

Mensajes: 786


Ver Perfil WWW
Duda con juego que genera numeros aleatorios
« en: 30 Septiembre 2012, 11:36 am »

En el libro que estoy leyendo sobre C, venia un ejemplo de un programa de como utilizar funciones, aqui el programa:

la funcion main:

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <ctype.h>
  4.  
  5. #define SEMILLA 12345
  6.  
  7. void juego(void);
  8. int tirada(void);
  9.  
  10. int main() {
  11.  
  12. char respuesta = 'S';
  13.  
  14. printf("Bienvenido al juego CRAPS\n\n");
  15. printf("Para lanzar los dados, pulsa Intro\n\n");
  16.  
  17. srand(SEMILLA);
  18.  
  19. while (toupper(respuesta) != 'N') {
  20. juego();
  21. printf("\nDeseas jugar de nuevo? (S/N) ");
  22. scanf(" %c", &respuesta);
  23. printf("\n");
  24.  
  25. }
  26. printf("Adios, que lo pases bien");
  27. }

la funcion juego:

Código
  1. void juego(void) {
  2.  
  3. int puntos1;
  4. int puntos2;
  5. char nada;
  6.  
  7. printf("\nPor favor lanza los dados...");
  8. scanf("%c", &nada);
  9. printf("\n");
  10. puntos1 = tirada();
  11. printf("\n%2d", puntos1);
  12.  
  13. switch(puntos1) {
  14.  
  15. case 7:
  16. case 11:
  17.  
  18. printf(" - Felicidades! Ganaste a la primera tirada\n");
  19. break;
  20.  
  21. case 2:
  22. case 3:
  23. case 12:
  24.  
  25. printf(" - Lo siento! Perdiste en la primera tirada\n");
  26. break;
  27.  
  28. case 4:
  29. case 5:
  30. case 6:
  31. case 8:
  32. case 9:
  33. case 10:
  34.  
  35. do {
  36.  
  37. printf(" - Lanza los dados de nuevo...");
  38. scanf("%c", &nada);
  39. puntos2 = tirada();
  40. printf("\n%2d", puntos2);
  41. } while (puntos2 != puntos1 && puntos2 != 7);
  42.  
  43. if (puntos2 == puntos1)
  44. printf(" - Ganas por igualar tu primera tirada\n");
  45. else
  46. printf(" - Pierdes por no igualar tu primera tirada");
  47. break;
  48. }
  49. return;
  50. }

la funcion tirada:

Código
  1. int tirada(void)  {
  2.  
  3. float x1;
  4. float x2;
  5. int n1;
  6. int n2;
  7.  
  8. x1 = rand() / 32768.0;
  9. x2 = rand() / 32768.0;
  10.  
  11. n1 = 1 + (int) (6 * x1);
  12. n2 = 1 + (int) (6 * x2);
  13.  
  14. return(n1 + n2);
  15. }

Entiendo todo perfectamente, pero donde me pierdo es en las funciones rand() y srand(), en la funcion tirada entiendo todas las operaciones que se hacen en ella para obtener los numeros, lo que no entiendo es para que se utiliza la funcion srand() y la constante SEMILLA, en el libro viene explicado pero no logro entenderlo, si alguien me lo puede explicar de alguna forma mas facil, gracias,


Saludos


En línea

do-while


Desconectado Desconectado

Mensajes: 1.276


¿Habra que sacarla de paseo?


Ver Perfil
Re: Duda con juego que genera numeros aleatorios
« Respuesta #1 en: 30 Septiembre 2012, 11:47 am »

¡Buenas!

rand() te genera una sucesion de numeros pseudoaleatorios. Es decir, si la llamas sin haber llamado a srand() siempre te generara la misma secuencia de numeros.

srand() hace que esa secuencia empiece por otro numero de la sucesion. Por lo tanto, si a srand le pasas una constante, la secuencia de numeros que genera rand() sera distina (en principio) de la que genera sin haber llamado a srand, pero al haber inicializado srand la secuencia que generara rand a un valor constante (fijo), seguiran repitiendose los mismos valores en las mismas posiciones.

Para evitar que la sucesion de numeros aleatorios sea siempre la misma, puedes utilizar como semilla un valor mas o menos aleatorio, como por ejemplo el valor devuelto pot la funcion time (que se encuentra en time.h o ctime), con parametro NULL, que devuelve el numero de segundos que han pasado desde 1900 (o algun otro año, no lo se) hasta el momento en el que se ejecuta el programa. Asi, cada vez que ejecutes el programa este valor sera diferente, y por lo tanto la sucesion que generara rand() tambien sera distinta.

¡Saludos!


« Última modificación: 30 Septiembre 2012, 11:50 am por do-while » En línea

- Doctor, confundo los números y los colores.
- Vaya marrón.
- ¿Marrón? ¡Por el culo te la hinco!
leosansan


Desconectado Desconectado

Mensajes: 1.314


Ver Perfil
Re: Duda con juego que genera numeros aleatorios
« Respuesta #2 en: 30 Septiembre 2012, 12:11 pm »

Para que "veas" lo que dice do-while corre el siguiente código varias veces. Observa que la primera lista es siempre la misma -fíjate en srand en el código- mientras que las otras dos varían -fijate otra vez en el segundo srand- .
:
Código
  1. /*Numero aleatorios entre 0 y 50:
  2. num=rand()%51;
  3.  
  4. Numero aleatorios entre 11 y 100:
  5. num=11+rand()%(101);
  6.  
  7. Numero aleatorios entre 250 y 420:
  8. num=250+rand()%(421-250);
  9.  
  10. De forma general es:
  11. variable = limite_inferior + rand() % (limite_superior +1 - limite_inferior) ;*/
  12.  
  13. #include <stdio.h>
  14. #include <time.h>
  15. main()
  16. {
  17.    int i,x,n;
  18.    srand();
  19.    printf("15  numeros entre 1 y 10: \n\n");
  20.    for (i = 0; i < 15; i++)
  21.        {
  22.            n = rand() % 10 ;
  23.            printf("%d, ", n);
  24.  
  25.        } printf("\b\b \n\n");
  26.    srand(time(0));
  27.    printf("15  numeros entre 1 y 10: \n\n");
  28.    for (i = 0; i < 15; i++)
  29.        {
  30.            n = rand() % 10 ;
  31.            printf("%d, ", n);
  32.  
  33.        } printf("\b\b \n\n");
  34.    printf("15  numeros entre 25 y 100: \n\n");
  35.    for (i = 0; i < 15; i++)
  36.        {
  37.            n = 25+rand() % (101-25) ;
  38.            printf("%d, ", n);
  39.  
  40.        } printf("\b\b \n");
  41. }
Espero que te sea útil.
Saludos!.
« Última modificación: 30 Septiembre 2012, 12:12 pm por leosansan » En línea

Caster


Desconectado Desconectado

Mensajes: 786


Ver Perfil WWW
Re: Duda con juego que genera numeros aleatorios
« Respuesta #3 en: 30 Septiembre 2012, 14:28 pm »

A ver, rand() genera una lista de numeros aleatorios, pero siempre son los mismos, hasta ahi creo que es asi, y entonces se llama a srand() para que empiece por otro numero y cambie la secuencia, pero si esto se repite volveriamos al problema del principio, a generar siempre la misma sucesion aun utilizando srand(), entonces para que esto no pase se le pasa una semilla que cambie cada cierto tiempo.

¿Lo he entendido bien?

Si estoy en lo cierto entonces, en mi programa como la semilla siempre es la misma, al final tambien terminarian repitiendose las suceciones, ¿es cierto?

Gracias por el codigo leosansan, me ha ayudado bastante

Saludos y muchas gracias.

EDITO: A la pregunta que hago sobre mi programa, estoy en lo cierto, en cada ejecucion se repiten las misma sucesiones. Creo que ya lo entiendo todo perfectamente.

EDITO 2: Me surge otra pregunta, utilizar srand() sin semilla y srand() pero con una semilla que no cambie, es realmente lo mismo no?

Muchas gracais
« Última modificación: 30 Septiembre 2012, 14:38 pm por Caster » En línea

leosansan


Desconectado Desconectado

Mensajes: 1.314


Ver Perfil
Re: Duda con juego que genera numeros aleatorios
« Respuesta #4 en: 30 Septiembre 2012, 15:39 pm »

SI
En línea

rir3760


Desconectado Desconectado

Mensajes: 1.639


Ver Perfil
Re: Duda con juego que genera numeros aleatorios
« Respuesta #5 en: 30 Septiembre 2012, 16:07 pm »

Me surge otra pregunta, utilizar srand() sin semilla y srand() pero con una semilla que no cambie, es realmente lo mismo no?
No.

La función "srand" requiere de un argumento, llamarla como indica leosansan (sin argumento) es un error.

Un saludo
En línea

C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language
leosansan


Desconectado Desconectado

Mensajes: 1.314


Ver Perfil
Re: Duda con juego que genera numeros aleatorios
« Respuesta #6 en: 30 Septiembre 2012, 16:32 pm »

La función "srand" requiere de un argumento, llamarla como indica leosansan (sin argumento) es un error.
¿¿¿....???      cPor qué no pruebas a correr el código que expuse?.¿No será que "quieres decir otra cosa?, porque decir que no "funciona" cuando sí funciona es erróneo. Otra cosa es que quieras decir que no sirve para generar números aleatorios diferentes cada vez que le llames. Pero te recuerdo que la duda era otra, ésta en concreto:
Respuesta a:
Citar
EDITO 2: Me surge otra pregunta, utilizar srand() sin semilla y srand() pero con una semilla que no cambie, es realmente lo mismo no?

SI, puedes ponerla sin semilla así "srand()" o con semilla, así  "srand(15)" y en ambos casos se genera el mismo juego de números aleatorios.
Un saludo
En línea

rir3760


Desconectado Desconectado

Mensajes: 1.639


Ver Perfil
Re: Duda con juego que genera numeros aleatorios
« Respuesta #7 en: 30 Septiembre 2012, 18:42 pm »

cPor qué no pruebas a correr el código que expuse?.
Porque eso es lo peor que se puede hacer en este escenario. C no es un lenguaje con "rueditas" y debido a sus reglas "tasajear" código para en base al resultado sacar conclusiones no es una buena idea. Lo explico mas adelante.


¿No será que "quieres decir otra cosa?
No, estas leyendo de mas en mis mensajes.


porque decir que no "funciona" cuando sí funciona es erróneo.
Cuando se trata del lenguaje C y sus estándares hay que ser muy cuidadoso con el lenguaje (con el otro, me refiero al español).

Yo no dije que en tu caso el programa no funcione correctamente, eso lo podemos dar por un hecho. Yo indique que es un error. Voy a explicar con mas detalle.


El estándar de C define el lenguaje y el comportamiento que tendrán los programas desarrollados con el pero, si se viola una de sus reglas, se genera "comportamiento no definido". Si revisamos uno de los últimos borradores (N1124) del estándar C99 tenemos:
Citar
6.5.2.2  Function calls

[...]

2 If the expression that denotes the called function has a type that includes a prototype, the number of arguments shall agree with the number of parameters.

[...]

6  If the expression that denotes the called function has a type that does not include a prototype, the integer promotions are performed on each argument, and arguments that have type float are promoted to double. These are called the default argument promotions. If the number of arguments does not equal the number of parameters, the behavior is undefined.
En base a esa parte podemos concluir que, si se llama a la función "srand" sin argumentos cuando su prototipo (cortesía de <stdlib.h>) indica que se debe pasar uno, se genera comportamiento no definido.

¿Porque es un error? Porque, como su nombre sugiere, una vez se genere el comportamiento no definido (en nuestro caso con la llamada a "srand") ya no hay garantías sobre el comportamiento del programa.

Cualquier cosa puede pasar, por ejemplo el programa:
* Funciona correctamente.
* Genera resultados inesperados.
* Simplemente revienta.
* etc.

Y ese es el problema: el compilador se "lava las manos" y lo que sea que resulte del programa es responsabilidad de programador (por violar las reglas del lenguaje).


Otro ejemplo, por desgracia común, es el uso de "fflush(stdin)". El estándar define el comportamiento de la función pero solo para streams de salida. Si se trata de un stream de entrada (como es el caso de "stdin") y como el estándar no define el comportamiento en ese caso se genera ...


Pero te recuerdo que la duda era otra, ésta en concreto:
Respuesta a:
Citar
EDITO 2: Me surge otra pregunta, utilizar srand() sin semilla y srand() pero con una semilla que no cambie, es realmente lo mismo no?
SI, puedes ponerla sin semilla así "srand()" o con semilla, así  "srand(15)" y en ambos casos se genera el mismo juego de números aleatorios.
Espero ahora se entienda mejor: utilizar "srand()" es un error ya que no se puede garantizar el comportamiento del programa a partir de ese punto.

Un saludo
En línea

C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language
Caster


Desconectado Desconectado

Mensajes: 786


Ver Perfil WWW
Re: Duda con juego que genera numeros aleatorios
« Respuesta #8 en: 30 Septiembre 2012, 20:14 pm »

Ya esta, ya me quedo claro como se usa correctamente, muchas gracias a todos por responder. Haya paz.

Saludos.
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines