2.2 Funciones para azar

Una de las posibilidades más interesantes de la programación es permitir la generación de resultados al azar.
Esta posibilidad tiene múltiples aplicaciones, desde la programación de juegos que tengan algún componente aleatorio, hasta el desarrollo de algoritmos de seguridad, para encriptación de claves.

Para ello, en C++ se utiliza la función rand, cuyo prototipo es:

      int rand()

Esta función no recibe ningún parámetro, y devuelve un valor entero. Dicho valor entero estára entre 0 y el máximo valor posible de un entero. Este valor máximo es como mínimo 32767; pudiendo ser hasta 2147483647.

Veamos un ejemplo de su uso:

 #include <iostream>
using namespace std;
void main()
{
    int i,n;
    for (i=1;i<=10;i++)
    {
        n = rand();
        cout << n <<endl;
    }
    cin>>n;
}

Este programa genera y muestra 10 números al azar, por ejemplo:






Como vemos, los números generados están en el rango 0-32767. Si queremos llevar este número a otro rango de valores, debemos realizar ciertas operaciones. Para convertir el número al rango 1-6 se debe modificar la línea correspondiente por:

    n = rand()%6+1;

Así la operación %6 divide el número generado por 6 y toma el resto de dicha división, lo que da un número entre 0 y 5. Sólo falta sumar 1 y se obtienen números en el rango 1-6.

El siguiente programa simula los números de una ruleta hasta que sale el cero:

#include <iostream>
using namespace std;

void main()
{
    int n;
    long i;
    n=1;
    do
    {
        n = rand()%37;
        cout << n << "   ";
        for (i=0; i<100000000; i++);
    }
    while (n!=0);
    cin>>n;
  }


 Como ya se habrán dado cuenta a esta altura, el programa devuelve siempre la misma serie de números aleatorios cada vez que se ejecuta. Esto puede ser útil si se quiere reproducir una serie varias veces para ver cómo responde un programa, pero no sirve de mucho si estamos simulando un juego de azar, ya que en ese caso sólo sería necesario memorizar la serie para ganar siempre.
Para evitar esto, debemos ver cómo se generan los números en la función rand. La computadora no puede generar números realmente aleatorios, lo que hace para causar la apariencia de azar es tomar un número inicial o semilla de la serie y le aplica una serie de operaciones matemáticas lo suficientemente complejas como para que no sean deducibles a partir del resultado. El valor así obtenido es el que devuelve la función rand y se convierte en la semilla para el nuevo valor. Así, la próxima vez que llamemos a la función, tomará este valor como semilla, le aplicará los cálculos y nos dará como resultado el tercer valor de la serie. Los valores así obtenidos no son realmente aleatorios, sino pseudoaleatorios.


Para evitar esto, utilizamos la función srand:

     void srand(int);
 
Esta función recibe como parámetro un valor entero que será la nueva semilla de la serie.
Ahora bien, podemos cambiar la semilla de la serie, pero ¿cómo hacemos que sea un valor aleatorio? No podemos pedir al usuario que ingrese su valor: No tardará en descubrir que siempre que ingresa el mismo número, obtiene la misma serie. Dicho valor deber obtenerse de la computadora. Para ello podemos utilizar la función time, incluida en el archivo <ctime>. Esta función devuelve un valor entero, y cuando se la invoca con el parámetro NULL, devuelve un valor que representa la cantidad de segundos transcurridos desde el tiempo "cero" del sistema (generalmente, el 01/01/1970). Ahora sí, tenemos un valor realmente aleatorio para comenzar nuestra serie, sólo agregando un par de líneas al programa:

 #include <iostream>
using namespace std;
 #include <ctime>

void main()
{
    int n;
    long i;
    srand(time(NULL));
    n=1;
    do
    {
        n = rand()%37;
        cout << n << "   ";
        for (i=0; i<100000000; i++);
    }
    while (n!=0);
    cin>>n;
  }


  

No hay comentarios:

Publicar un comentario