domingo, 14 de agosto de 2016

Capítulo 62. Números aleatorios en C


Diario de un programador.- Dia 159


Es el turno de C. En esta oportunidad, vamos a estudiar, cómo generar un número aleatorio y con esos conocimientos, crear un sencillo juego en modo texto, conocido como Craps. 

Números aleatorios.

En esta ocasión se va a intentar construir un programa que produzca números aleatorios o al azar. Para ello se utilizará la función rand(). Esta función genera un número entre 0 y RAND_MAX (Una constante definida en el archivo cabecera stdlib.h) El estándar ANSI, indica que el valor de RAND_MAX, para un entero de 16 bit (2 bytes) debe ser de por lo menos 32767.
Para ver cómo funciona esto, se mostrará un ejemplo:

#include<stdio.h>
#include<stdlib.h>

int main(void){

 int azar = rand();
 printf("El numero escogido al azar es %d\n", azar);

return 0;



Para hacer que el rango de números sea menor, por ejemplo si se desea buscar un número al azar para simular un dado, se utiliza el signo % seguido del número que representa el rango en el cual se debe realizar la búsqueda. Por ejemplo, si quisiera que el rango estuviese entre 1 y 6, entonces, la variable azar del programa anterior debe quedar así:

int azar = 1 + rand() % 6;

Debido a que la función rand() empieza a realizar la búsqueda desde el número cero, se  antepuso el número 1 a la función rand, para que la búsqueda empiece desde 1 y no cero, como es que viene por defecto. El programa se verá así:

#include<stdio.h>
#include<stdlib.h>

int main(void){

 int azar = 1 + rand() % 6;
 printf("El numero escogido al azar es %d\n", azar);

return 0;
}


Seguramente más de alguno se habrá dado cuenta que al ejecutar el programa varias veces, la función rand() escoge el mismo número al azar. Esto es así debido a que se facilita la depuración (corrección) del programa cuando existen elementos que se generan al azar. Una vez que el programa fue corregido, se puede emplear otra función que permita a rand() escoger un número al azar diferente. Esta función es srand(). La función srand() solicita un argumento unsigned (entero sin signo, o sea entero positivo) y ese número es tomado como base o semilla para generar un número aleatorio. Ejemplo.

#include<stdio.h>
#include<stdlib.h>

int main(void){

 unsigned semilla = 5;
 srand(semilla);

 int azar = 1 + rand() % 6;
 printf("El numero escogido al azar es %d\n", azar);

return 0;
}



Cambiando el número de la semilla, se puede generar un nuevo número al azar. Voy a probar un nuevo programa, pero esta vez haré que me pida un valor, el cual será utilizado como la semilla.

#include<stdio.h>
#include<stdlib.h>

int main(void){
  unsigned semilla;
  int i;
  int azar;

  printf("Ingresa un numero base o semilla: ");
  scanf("%u", &semilla);
  printf("\n** Numeros Generados **\n");

  for(i = 0; i < 10; i++){
    semilla++;
    srand(semilla);
    azar  = 1 + rand() % 10;
    printf("%d\n", azar);
  }
return 0;
}


Cada vez que se ejecuta el programa, entregará una lista diferente de números aleatorios, siempre y cuando se entregue una semilla diferente.
Otra forma de hacer aleatorio este programa sin necesidad de introducir una semilla cada vez que se ejecute, es utilizar la función srand(time(NULL)). La función time, devuelve la hora en segundos, el cual es convertido en entero unsigned. Time es capaz de proporcionar una cadena representando la hora del día. El argumento NULL desactiva esa capacidad entregando solamente un número. Para utilizar time, se debe agregar la cabecera time.h
Ejemplo:

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

int main(void){

  int i;
  int azar;
  srand(time(NULL));
  printf("\n** Numeros Generados **\n");

  for(i = 0; i <= 10; i++){
    azar  = 1 + rand() % 10;
    printf("%d\n", azar);
  }
return 0;
}

De esta manera, cada vez que se ejecute el programa, saldrá una secuencia diferente de dígitos.

CRAPS

A continuación, voy a crear una especie de juego "Craps", el cual consiste en lanzar 2 dados, sumando el número obtenido por ambos dados. Si el número obtenido es un 7 o un 11, entonces se gana la partida, pero si se obtiene un 2, un 3 o un 12, se pierde inmediatamente. Si sale un número diferente a los mencionados anteriormente, (4, 5, 6, 8, 9, 10) entonces se vuelven a lanzar los dados, tratando de conseguir nuevamente el mismo número obtenido. Por ejemplo, si se consigue un 9 en el primer lanzamiento, entonces el jugador debe volver a lanzar los dados para tratar de obtener nuevamente un 9. Se deben lanzar dados consecutivamente hasta obtener un 9, pero en caso de salir un 7, se pierde la partida.
A continuación, se muestra la solución que yo conseguí hacer.

//JUEGO CRAPS MARZO 2016. GUSTAVO J. CERDA NILO
#include<stdio.h>
#include<stdlib.h>
#include<time.h>

int main(void){
  int azar, i, tirada[2], punto, repetir, ptoRepetir, intentos = 1;

  printf("TIRAR DADOS. 1ER INTENTO\n\n");
  printf("############################################\n");
  printf("# NROS. GANADORES  EN 1ER INTENTO 7, 11    #\n");
  printf("# NROS. PERDEDORES EN 1ER INTENTO 2, 3, 12 #\n");
  printf("############################################\n\n");
  system("pause");

  srand(time(NULL));
  for (i = 0; i < 2; i++){
    azar = 1 + rand() % 6;
    tirada[i] = azar;
  }
  punto = tirada[0] + tirada[1];

   printf("\nLanzando el primer dado... %d\n", tirada[0]);
   printf("Lanzando el segundo dado...  %d\n", tirada[1]);
   printf("Nro. obtenido: %d (%d + %d)\n\n", punto, tirada[0], tirada[1]);
   system("pause");

  if(punto == 7 || punto == 11){
    printf("\nHAS GANADO!!!\n");
  }
  if(punto == 2 || punto == 3 || punto == 12){
    printf("\nHAS PERDIDO!\n");
  }
  if(punto == 4 || punto == 5 || punto == 6 || punto == 8 || punto == 9 || punto == 10){
    ptoRepetir = punto;

    do{
      intentos++;
      system("cls");
      printf("##############################################\n");
      printf("# NUEVO INTENTO. Esta vez para repetir el %d  #\n", ptoRepetir);
      printf("#          SI SALE UN 7 PIERDES !!!          #\n");
      printf("##############################################\n\n");

      for (i = 0; i < 2; i++){
        azar = 1 + rand() % 6;
        tirada[i] = azar;
      }//fin for
      punto = tirada[0] + tirada[1];

      printf("numero buscado: %d\n",ptoRepetir);
      printf("dado1 = %d\n", tirada[0]);
      printf("dado2 = %d\n", tirada[1]);
      printf("Nro. obtenido: %d (%d + %d)\n", punto, tirada[0], tirada[1]);

      if (punto == 7){
        printf("\nHAS PERDIDO!\n");
        printf("Nro de intentos: %d\n", intentos);
        break;
      }
      system("pause");
    }while (punto != ptoRepetir);
  }//fin if

  if (punto == ptoRepetir){
        printf("\nHAS GANADO!!!\n");
        printf("Nro de intentos: %d\n", intentos);
  }

  return 0;
}//fin main







Espero se haya entendido. Saludos


Gustavo J. Cerda Nilo
Febrero 2016, Agosto 2016




No hay comentarios:

Publicar un comentario

C++ El apuntador This

El apuntador This En C++, cada objeto tiene acceso a su propia dirección a través de un puntero o apuntador denominado This. Lo...