Hace años publiqué una explicación sobre condiciones en C. En aquel tiempo lo hice todo en audio porque tenía un alumno con debilidad visual (casi ciego). Pero el servidor donde subí el audio cerró sin decir agua va y el artículo no sirve de mucho: puedes ver parte de la explicación y el código, pero se pierde mucho. Asi que, como sigo hablando de C con mis alumnos (y seguiré haciéndolo), es hora de volver a explicarlo.
Uno de los pilares de la programación es hacer que el programa tome decisiones. En otro ámbito, eso es lo que los papás esperamos de nuestros hijos: de que algún día puedan tomar las decisiones correctas. Pero al tratar con la computadora es más fácil: nunca va a renegar ni a ignorar lo que le diga (como lo suelen hacer mis hijas) porque siempre va a hacer lo que le indique y siempre lo hará igual. Claro que mis niñas pueden hacer millones de cosas que mi computadora no, y las amo millones de veces más que mi compu, pero esa es harina de otro costal.
Volviendo al mundo de la programación, casi todos los lenguajes tienen la instrucción IF que nos permite definir las instrucciones que se van a ejecutar en caso que se cumpla alguna condición. C no es la excepción y en el siguiente video te voy a explicar un programa que usa condiciones IF en C (o C++ que para este caso, da lo mismo).
En el video explico un programa ya hecho, un ejemplo que usa IFs. Si no tienes idea de qué es el IF, te sugiero revisar esta página de Nacho Cabanes que lo explica. Luego regresas a este video.
/* *** * gato.c - programa que juega al gato. Ejemplo del uso de if * ***/#include<stdio.h>intmain(){// Declaro variableschara1,a2,a3,b1,b2,b3,c1,c2,c3;// Estos son los "huecos" donde se puede jugarcharjugador;// Éste es la letra del jugador (X o O)intfila,col;// La fila y columna donde desea jugarintgana,jugadas;// Indica si ganó (1 si sí, 0 si no) y cuantas jugadas se han hecho// Inicializo el gatoa1=a2=a3=b1=b2=b3=c1=c2=c3='#';// Las posiciones pueden tener # (aún no se ocupa), X u Ogana=jugadas=0;// Todavía no ganan (en 0) y no se han hecho jugadasjugador='X';// El primer jugador es el X// Ciclo que se repite mientras no ganawhile(gana==0){// Imprimo el gatoprintf("%c | %c | %c\n",a1,b1,c1);printf("--+---+--\n");printf("%c | %c | %c\n",a2,b2,c2);printf("--+---+--\n");printf("%c | %c | %c\n",a3,b3,c3);// Pido coordenadasprintf("\n\nJugador %c\nFila (1, 2 o 3): ",jugador);scanf("%d",&fila);fflush(stdin);// Elimina las teclas que no leyó el scanf anterior (el ENTER)printf("Columna (A, B o C): ");scanf("%c",&col);// Guardo la "tirada"if(fila==1){if(col=='A'){a1=jugador;}elseif(col=='B'){b1=jugador;}elseif(col=='C'){c1=jugador;}else{printf("\nError de columna\n");}}elseif(fila==2){if(col=='A'){a2=jugador;}elseif(col=='B'){b2=jugador;}elseif(col=='C'){c2=jugador;}else{printf("\nError de columna\n");}}elseif(fila==3){if(col=='A'){a3=jugador;}elseif(col=='B'){b3=jugador;}elseif(col=='C'){c3=jugador;}else{printf("\nError de columna\n");}}else{printf("\nError de fila\n");}// Veo si ya ganaronif((a1==jugador&&b1==jugador&&c1==jugador)||(a2==jugador&&b2==jugador&&c2==jugador)||(a3==jugador&&b3==jugador&&c3==jugador)||(a1==jugador&&a2==jugador&&a3==jugador)||(b1==jugador&&b2==jugador&&b3==jugador)||(c1==jugador&&c2==jugador&&c3==jugador)||(a1==jugador&&b2==jugador&&c3==jugador)||(a3==jugador&&b2==jugador&&c1==jugador)){gana=1;printf("Gana el jugador %c\n",jugador);}else{// Aumento el número de jugadasjugadas++;// Reviso empate (si llegan a 9 jugadas y nadie ha ganado, es empate)if(jugadas==9){printf("Hubo empate\n");gana=1;// No ganó, pero quiero que se salga del ciclo}else{// Si no ganó ni empató, cambio de jugadorif(jugador=='X'){jugador='O';}else{jugador='X';}}}}}
Hace tiempo escribí como se pueden generar números aleatorios en C++ (que igual aplica para C). Es sencillo y funcional. Sin embargo, en C# tenemos algo que todavía nos simplifica más la vida: la clase Random. Antes de continuar, te recomiendo leer el artículo anterior y cuando hable de código, regresen aquí.
En el otro post se usa el srand((unsigned)time(0)) para incializar el generador de números pseudoaleatorios con el valor del reloj del sistema. Al usar la clase Random, el constructor hace lo mismo. Asi que cuando iniciemos nuestro programa, se crea el objeto de la siguiente manera:
Random x = new Random();
Con eso se crea un objeto (e inicializa el generador de números usando el valor del reloj del sistema).
Tal ve te preguntes, ¿por qué se tiene que inicializar el generador de números aleatorios y porque es conveninte hacerlo con el reloj del sistema? Si no te lo preguntas y aceptas lo que te dicen sin cuestionar, sáltate los siguientes párrafos hasta que veas código.
Básicamente es porque no existe una manera de generar números al azar porque los cerebros humanos lo pueden hacer, pero no existe un procedimiento, un proceso para hacerlo. Por ejemplo piensa ahorita en un número al azar entre 1 y 10. ¿Por qué elegiste ese número? ¿Que proceso seguiste para determinar ese número? Simplemente se te ocurrió. Pero la computadora necesita que se le diga exactamente cómo hacer algo.
Asi que podemos agradecer a alguna deidad de las matemáticas* que se le ocurrió una ecuación que genera secuencias de números que parecen aleatorios (por eso los llamamos pseudoaleatorios). Pero el problema es que cada vez que lo usas, genera la misma serie. Pero a este señor se le ocurrió ponerle a esta ecuación un valor inicial y la secuencia depende de ese número. Por ejemplo, si lo inicializamos con 5, nos dará una secuencia de números. Si lo inicializamos con 6 nos da otra, etc. Por eso, si lo inicializamos con el reloj del sistema, cada vez que lo usemos nos dará una secuencia diferente.
Pero regresando a lo que estábamos hablando sobre el código, después de crear un objeto Random, generamos números enteros usando el método Next. Me voy a concentrar en números enteros, pero también puedes usar NextDouble para generar números aleatorios de tipo float/double que van entre 0 y 0.99999999, NextBytes para llenar un arreglos con bytes aleatorios, etc.
Asi que, siguiente con el objeto x que hice antes en el ejemplo de crear un objeto de tipo Random, tenemos estas variantes del Next:
x.Next() - devuelve un número entero aleatorio positivo.
x.Next(10) - devuelve un número entero aleatorio entre 0 y 9.
x.Next(1,10) - devuelve un número entero aleatorio entre 1 y 9.
Si quieres saber todo sobre el Random, lee este artículo de Microsoft.
Para ejemplificar el uso, hice esta sencilla app que prueba los tres tipos de Next. Tiene un Label donde muestra el número aleatorio, en un Groupbox hay 3 RadioButtons para seleccionar los tres tipos de Next y Textboxes para poner los números límites, si se seleccionan esas opciones. La app se ve como lo que puesta esta imagen y creo que de ver la interfaz, te puedes dar cuenta de cómo funciona:
El código del Form1.cs (que hace todo) lo tienes aquí a continuación. Lo "especial" sucede en estas líneas:
18 - Declaro el objeto Random (se llama azar)
31 al 71 - El método btnGeneraAzar_Click que se ejecuta cuando presionan el botón y usa los 3 tipos de Next para generar números al azar. Como dice allí, recuerda que int.Parse sirve para convertir un String (lo que está en una caja de texto en mi caso) a int (valor que necesita el Next).
usingSystem;usingSystem.Collections.Generic;usingSystem.ComponentModel;usingSystem.Data;usingSystem.Drawing;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;usingSystem.Windows.Forms;namespaceAleatorio{publicpartialclassForm1:Form{// Declaro mi objeto Random que se va a encargar de generar números al azar.// Es útil ponerlo como variable de clase porque no quieres crear y destruir objetos// a cada rato.Randomazar=newRandom();publicForm1(){InitializeComponent();}/// <summary>/// Llena el label (lblNum) con el número entero al azar que se generó./// Usa los radiobuttons para saber qué versión de Next usar./// </summary>/// <param name="sender"></param>/// <param name="e"></param>privatevoidbtnGeneraAzar_Click(objectsender,EventArgse){intnumAzar=0;// Variable donde voy a guardar el número generado// Genero número aleatorioif(rdoEntero.Checked){// Si solo es un entero aleatorio positivonumAzar=azar.Next();}elseif(rdoEnteroLimite.Checked){// Si es un entero con límite, debo verificar que escribieron el límiteif(txtLimite.Text.Length>0){// Nota: int.Parse() convierte un String a un int.numAzar=azar.Next(int.Parse(txtLimite.Text));}else{MessageBox.Show("Hay que escribir un número máximo para esta opción","C# Azar",MessageBoxButtons.OK,MessageBoxIcon.Error);}}else{// Si no fue ninguno de los anteriores, quiere número al azar en un rangoif(txtDesde.Text.Length>0&&txtHasta.Text.Length>0){numAzar=azar.Next(int.Parse(txtDesde.Text),int.Parse(txtHasta.Text));}else{MessageBox.Show("Hay que escribir un número mínimo y máximo para esta opción","C# Azar",MessageBoxButtons.OK,MessageBoxIcon.Error);}}// Muestro númerolblNum.Text=numAzar.ToString();}/// <summary>/// Si este control recibe el Focus, hago que rdoEnteroLimite esté checked/// </summary>/// <param name="sender"></param>/// <param name="e"></param>privatevoidtxtLimite_Enter(objectsender,EventArgse){rdoEnteroLimite.Checked=true;}/// <summary>/// Si este control recibe el Focus, hago que rdoEnteroRango esté checked/// </summary>/// <param name="sender"></param>/// <param name="e"></param>privatevoidtxtDesde_Enter(objectsender,EventArgse){rdoEnteroRango.Checked=true;}/// <summary>/// Si este control recibe el Focus, hago que rdoEnteroRango esté checked/// </summary>/// <param name="sender"></param>/// <param name="e"></param>privatevoidtxtHasta_Enter(objectsender,EventArgse){rdoEnteroRango.Checked=true;}/// <summary>/// Si seleccionó esta opción, muevo el cursor a txtLimite/// </summary>/// <param name="sender"></param>/// <param name="e"></param>privatevoidrdoEnteroLimite_Enter(objectsender,EventArgse){txtLimite.Focus();}/// <summary>/// Si seleccionó esta opción, muevo el cursor a txtDesde/// </summary>/// <param name="sender"></param>/// <param name="e"></param>privatevoidrdoEnteroRango_Enter(objectsender,EventArgse){txtDesde.Focus();}}}
Si desea descargar el proyecto comprimido en formato 7Zip, haz click aquí.