Por lo menos en la programación, dejamos algunas cosas al azar. Es muy importante generar números al azar para diferentes tipos de aplicaciones, desde juegos, simulaciones y análisis de datos hasta ciberseguridad y mil aplicaciones más.
Para facilitarnos la vida, Python tiene un módulo, llamado random, que nos ayuda a generarlos. En este post te voy a mostrar cómo usarlo.
Antes de empezar...
Antes de poder empezar a generar números aleatorios, debes importar el módulo random. Puedes hacerlo con una simple declaración import al principio de tu programa:
import random
Con esto tu programa ya tiene acceso a varias funciones y clases para generar datos aleatorios, algunos de los cuales vamos a hablar más adelante.
Generando números enteros aleatorios
El módulo random proporciona la función randint(a, b) para generar un número entero aleatorio entre a y b, incluyendo ambos valores. Así es cómo puedes utilizarlo:
En este ejemplo, random.randint(1, 10) genera un número entero aleatorio entre 1 y 10, y el resultado se almacena en la variable entero_aleatorio. Puedes ajustar el rango para adaptarlo a tus necesidades específicas.
Generando números con decimales
No es tan común, pero a veces necesitas generar números que tengan decimales de forma aleatoria. Para esto puedes utilizar la función random.uniform(a, b). Genera un número de punto flotante aleatorio entre a y b. Aquí tienes un ejemplo:
# Genero números al azar# Este import me deja usar el objeto randomimportrandomprint('10 números al azar entre 5 y 30...')i=0whilei<10:# random.randint de devuelve un número al azar entre...# ...los números que le diga, en este caso, entre 5 y 30.print(random.randint(5,30))i=i+1input('Fin del programa, presione ENTER para salir');
random tiene muchas otras funciones en los que no me voy a meter pero que estos son los principales o más usuales. Espero que les haya sido de utilidad. ¡Hasta la próxima!
El otro día estaba tratando de hacer un programa que te permite jugar 21 (Blackjack), aunque no fuera de forma "completa", más bien como un ejercicio del uso de vectores, clases y objetos en C++.
Uno de los problemas era revolver una baraja. Como ya he hablado de cómo generar números aleatorios en C++, pensé una forma de generar números al azar e irlos cambiando con los que están, pero supuse que debía haber una mejor manera, algo más sencillo. Y sabía que en Java había forma de trabajar con ArrayLists, así que me puse a buscar cómo se puede hacer en C++. Y sí, hay una función que me puede "mezclar" al azar (o pseudoazar, como hemos dicho cuando hablé de números aleatorios), e incluso escribí brevemente sobre cómo usarlo, pero aquí te explico cómo usarlo con un ejemplo más completo.
El método en cuestión es el random_shuffle y para poderlo usar, tienes que incluir la librería <algorithm>. Y necesita el uso de números aleatorios (si no sabes cómo funcionan, lee primero este post de mi blog), así que incluimos la librería <cstdlib> para usar el srand y el rand, y la librería <ctime> para obtener la hora del sistema para inicializar el generador de números pseudoaleatorios. Así que la pura parte de la declaración, quedaría así:
Después de esto, en el main() antes en hacer cualquier otra cosa, inicializo el generador de números aleatorios con el reloj del sistema, como se ve aquí:
Esto va al principio del main(): srand(time(NULL)); baraja.Barajear();En la clase Baraja viene estos métodos:// Genera números aleatorios (para uso con random_shuffle)int myrandom (int i) { return rand()%i;}// Barajear: barajea toda la barajavoid Baraja::Barajear() { random_shuffle(cartas.begin(),cartas.end(),myrandom);}
Aquí viene una parte que va en el main() y también estoy mostrando el método de la clase Baraja (al rato pongo todo el código) que barajea (revuelve) los elementos del vector. También agrego una función, llamado myrandom, que no pertenece a ninguna clase, que genera los números aleatorios para ser usados en el método random_shuffle.
Aquí pongo el código completo. El archivo tiene una clase Carta que guarda el palo (corazones, trébol, etc.), el valor o rango (As, 2, 3, etc) y si está visible o no. Tiene un constructor que recibe dos cadenas (palo y rango) y métodos para voltear una carta, devolver los datos de una carta, saber si está visible o no y para devolver el valor (rango).
Luego tiene una clase Baraja que tiene un vector de objetos Carta, un constructor que inicializa el vector con todas las cartas de una baraja inglesa (para eso hay un par de arreglos para ayudar a inicializar) y métodos que te devuelve una carta (y lo quita del vector), para barajear la carta (lo que mostré en el código anterior), para imprimir todas las cartas en la baraja, y una que nos indica si la baraja está vacía o no.
También hay una clase Jugador que tiene las manos de cada jugador: guarda un vector de tipo Carta y una cadena con el nombre del jugador. No tiene constructor y tiene métodos para Agregar una carta al vector del jugador, devolver el número de cartas que tiene, mostrar sus cartas, asignar un nombre al jugador y para mostrar el nombre del jugador.
El main() declara una Baraja y un vector de Jugador, inicializa la baraja (con un código que mostré con anterioridad), pide número de jugadores, pide las cartas para cada jugador, revisa si alguien ganó justo después de repartir las cartas (poco probable, pero hay que revisar) e inicia un ciclo donde muestra cartas del jugador y le pregunta si desea otra carta, revisa si perdió o si ganó. Si nadie ha ganado, al final determina el ganador (el que más cera esté de sumar 21).
Con esa explicación, ahora sí les dejo el código completo del programa, esperando que les sea de utilidad. ¡Saludos!
/* **** * Juego de 21 * ****/#include<iostream> // cout, cin#include<vector> // vector#include<string> // uso strings#include<algorithm> // random_shuffle#include<ctime> // Para usar time() - inicializar números aleatorios#include<cstdlib> // srand, randusingnamespacestd;/* *** * CLASE Carta * *** */classCarta{// Campos privadosstringpalo,rango;boolvisible;// Constructorpublic:Carta(string,string);// MétodosvoidVoltear(){visible=!visible;}stringImprimir();boolVisible(){returnvisible;}stringRango(){returnrango;}};// ConstructorCarta::Carta(stringpalo,stringrango){this->palo=palo;this->rango=rango;visible=false;}// ImprimirstringCarta::Imprimir(){stringx;x.append(rango).append(" de ").append(palo);returnx;}/* *** * CLASE Baraja * ***/classBaraja{// Camposprivate:vector<Carta>cartas;// Constructorpublic:Baraja();// MétodosCartaTomaCarta();voidBarajear();voidImprimir();//void Partir(int);boolVacia(){returncartas.empty();}};// Declaro arreglos útiles para inicializarstringrangos[]={"As","2","3","4","5","6","7","8","9","10","Joto","Reina","Rey"};stringpalos[]={"Corazones","Diamantes","Treboles","Picas"};// Constructor: llena la baraja con 52 cartasBaraja::Baraja(){inti,j;for(i=0;i<4;i++){for(j=0;j<13;j++){Cartatemp(palos[i],rangos[j]);cartas.push_back(temp);}}}// Imprimir: Imprime todas las cartas de la barajavoidBaraja::Imprimir(){inti;for(i=0;i<cartas.size();i++){cout<<cartas[i].Imprimir()<<endl;}}// Genera números aleatorios (para uso con random_shuffle)intmyrandom(inti){returnrand()%i;}// Barajear: barajea toda la barajavoidBaraja::Barajear(){random_shuffle(cartas.begin(),cartas.end(),myrandom);}// TomaCarta: Devuelve la última carta de la barajaCartaBaraja::TomaCarta(){Cartax=cartas[cartas.size()-1];// x = la última cartacartas.pop_back();// Elimino la última carta de la barajareturnx;// Devuelvo x}/* *** * CLASE: Jugador * ***/classJugador{// Camposprivate:vector<Carta>cartas;stringnombre;// Métodospublic:voidAgregarCarta(Carta);// Devuelve el número de cartas que tengo en las manosintNumCartas(){returncartas.size();}intSumaCartas();stringMuestraCartas();voidAsignaNombre(stringnombre){this->nombre=nombre;}stringMuestraNombre(){returnnombre;}};// Agrega una carta a las que tengo en mis manosvoidJugador::AgregarCarta(Cartac){cartas.push_back(c);}// Devuelve la suma de las cartasintJugador::SumaCartas(){inti,suma=0,temp;stringr;for(i=0;i<cartas.size();i++){r=cartas[i].Rango();if(r.compare("As")==0){suma+=11;}elseif(r.compare("Joto")==0||r.compare("Reina")==0||r.compare("Rey")==0){suma+=10;}else{temp=stoi(r);// Obtiene el entero que hay en la cadena del rangosuma+=temp;}}// Si me pasé de 21, veo si hubo As. Si hay, le resto 10if(suma>21){for(i=0;i<cartas.size();i++){if(cartas[i].Rango().compare("As")==0){suma-=10;}}}returnsuma;}// Devuelve una cadena con las cartas del jugadorstringJugador::MuestraCartas(){stringtemp;inti;for(i=0;i<cartas.size();i++){temp.append(cartas[i].Imprimir()).append("\n");}returntemp;}intmain(){// Declaro variables y objetosBarajabaraja;inti,j,noJugadores=0;vector<Jugador>jugadores;stringsiono;// Preparo la barajasrand(time(NULL));baraja.Barajear();// Preguntar número de jugadoreswhile(noJugadores<2||noJugadores>4){cout<<"Numero de jugadores: ";cin>>noJugadores;}getline(cin,siono);// Pedir cartasJugadorx;for(i=0;i<noJugadores;i++){// Creo un vector de jugadores del tamaño adecuadocout<<"Nombre: ";getline(cin,siono);x.AsignaNombre(siono);jugadores.push_back(x);}for(i=0;i<2;i++){// Se reparten 2 cartas a cada jugadorfor(j=0;j<noJugadores;j++){// Se reparten a todos los jugadoresjugadores[j].AgregarCarta(baraja.TomaCarta());}}// Si alguien tiene 21 (ya ganó desde el inicio)for(i=0;i<noJugadores;i++){if(jugadores[i].SumaCartas()==21){cout<<"¡Ganó el jugador "<<jugadores[i].MuestraNombre()<<"! Sus cartas fueron:\n"<<jugadores[i].MuestraCartas();return1;}}// Ciclo de pedir cartasfor(i=0;i<noJugadores;i++){do{// Muestro las cartas del jugador y le pregunto si quiere otracout<<jugadores[i].MuestraNombre()<<", tus cartas son:\n";cout<<jugadores[i].MuestraCartas()<<endl;cout<<"Jugador "<<jugadores[i].MuestraNombre()<<", ¿Otra carta (S/N)? ";getline(cin,siono);if(siono[0]=='S'||siono[0]=='s'){jugadores[i].AgregarCarta(baraja.TomaCarta());// Si perdió, elimino al jugador y decremento noJugadoresif(jugadores[i].SumaCartas()>21){cout<<"Jugador "<<jugadores[i].MuestraNombre()<<" perdió. Sus cartas suman "<<jugadores[i].SumaCartas()<<"\nY sus cartas son\n"<<jugadores[i].MuestraCartas()<<endl;jugadores.erase(jugadores.begin()+i);noJugadores--;}elseif(jugadores[i].NumCartas()==5){// Si llega a tener 5 cartas y no se pasa, ganacout<<jugadores[i].MuestraNombre()<<", ¡ganaste! Tienes 5 cartas y no te pasaste de 21. "<<"Tus cartas fueron:\n"<<jugadores[i].MuestraCartas()<<endl;return1;}elseif(jugadores[i].SumaCartas()==21){// Si sus cartas suman 21, ganacout<<jugadores[i].MuestraNombre()<<", ¡ganaste! Tus cartas suman 21. "<<"Tus cartas fueron:\n"<<jugadores[i].MuestraCartas()<<endl;return1;}}}while(siono[0]!='N'&&siono[0]!='n');}// Ver quien ganó (de los que quedan)j=0;// En j guardo el índice de quien ganóif(!jugadores.empty()){for(i=1;i<noJugadores;i++){if(jugadores[i].SumaCartas()>jugadores[j].SumaCartas()){j=i;}}cout<<"El ganador es "<<jugadores[j].MuestraNombre()<<" y sus cartas fueron:\n"<<jugadores[j].MuestraCartas()<<endl;}else{cout<<"Todos perdieron\n";}}