Hemos visto la sentencia FOR, la cual sirve para repetir bloques de código un número específico de veces. Resultará muy útil para ciertas tareas, sin embargo, sabemos que no siempre servirá. En la lección anterior les di el ejemplo del PIN de un celular.
Como ejemplo más sencillo podríamos imaginar un programa que nos haga adivinar un número en diez intentos. Nosotros ingresamos un número y el programa nos dice si acertamos o no. En caso de acertar ganamos el juego y el programa termina, sino acertamos seguimos intentando hasta gastar nuestros diez intentos, en cuyo caso perdemos.
Un programa como este puede finalizar por dos condiciones:
**Acertamos el número.
**Gastamos el número de intentos sin lograr acertar.
Claramente un FOR no serviría para algo como esto porque iteraría 10 veces, acertemos o no. Entonces ¿cómo hacemos para decirle al programa que repita algo mientras se den ciertas condiciones y que se detenga si estas no se dan?
Aquí entra la sentencia WHILE de la que hablaremos en esta lección. Sin embargo, antes de abordar ese tema veremos como obtener números aleatorios en Pascal ya que eso resultará útil para muchas cosas.
-------------------------------------------------------------------------------------
Generar números aleatorios:
Para obtener un número al azar se utiliza la función random. Su sintaxis es la siguiente:
Random(x)
donde X es un entero (integer) que marca el número máximo que se puede generar. Random(x) devolverá un número aleatorio entre 0 y X-1. Por ejemplo, si escribimos random(50) obtendremos un número al azar entre 0 y 49 inclusive.
Si nosotros queremos obtener un número entre 1 y X, entonces tenemos que ser sutiles:
Código:
nos mostrará en pantalla un número entre 0 y 9.WriteLn(Random(10));
Código:
nos mostrará en pantalla un número entre 1 y 10.WriteLn(Random(10) + 1);
Explicaré esto a continuación.
Veamos un ejemplo sencillo en el que el usuario ingresa cuál es el tope y el programa le devolverá un número aleatorio entre 1 y el número ingresado. Asumimos que el usuario ingresará un entero mayor que 1:
Código Pascal:
Ver original
PROGRAM funcion_random; Var x, valor_aleatorio: integer; BEGIN randomize; write('Ingrese un valor: '); readln(x); valor_aleatorio:= random(x) + 1; writeln('El número obtenido entre 1 y ',x,' es: ',valor_aleatorio); END.
Bien, este programa es bien sencillo de entender. Tenemos dos variables, x y valor_aleatorio. La primera será leída desde la entrada estándar y guardará el valor ingresado por el usuario. La segunda guardará el número al azar obtenido por la función random.
Lo primero a notar es que en la línea 7 hacemos una llamada al procedimiento randomize. Este no lleva parámetro alguno, simplemente indica que luego en algún momento del programa será utilizada la función random.
Si no hacen esto no podrán usar esta función y tendrán un error en tiempo de compilación.
En la línea 10 obtenemos el valor de X. En la línea 12 asignamos a valor_aleatorio el valor obtenido por random(x) más 1. ¿Por qué más 1? Si random(x) genera un número aleatorio entre 0 y X-1 pero nosotros queremos uno entre 1 y X solo basta sumar 1 al resultado. Por ejemplo, si hiciéramos random(10) podríamos obtener los números 0, 1, 2, 3, 4, 5, 6, 7, 8 o 9. Si quisiéramos un número entre 1 y 10 basta sumar 1 al valor sorteado. Si sale el 0, al sumar 1 obtenemos el 1. Si sale 9, al sumar 1 obtenemos el 10, o sea, corremos todo el intervalo un lugar a la derecha.
-------------------------------------------------------------------------------------
Secuencia de repetición WHILE…DO:
Comencemos entonces con WHILE. Esta instrucción nos permitirá definir las condiciones que harán que un bloque de código se repita. Por lo tanto estas repeticiones serán distintas en cada ejecución del programa, no como sucede con FOR.
WHILE...DO significa MIENTRAS…HAS.
Veamos antes que nada su sintaxis general:
Código:
Esto significa, mientras se cumpla la condición ejecuta tu instrucción. Una vez hecha la instrucción, WHILE regresará a su encabezado y volverá a verificar la condición. Si esta sigue siendo verdadera volverá a ejecutarse. En caso contrario salteará la instrucción y el programa continuará su curso. No está de más decir que la condición puede ser compuesta y que la instrucción puede ser un bloque de instrucciones delimitado por BEGIN y END. De este modo la forma más genérica de WHILE sería asíWhile condicion do Instrucción;
Código Pascal:
Ver original
WHILE condicion DO BEGIN Intruccion1; Instruccion2; . . . InstruccionN; END;
Veremos primero el ejemplo del que hablé hace poco, un programa que nos hará adivinar un número. Generaremos un número al azar entre 1 y 30 y tendremos 10 intentos para adivinarlo. Aquí usaremos RANDOM.
Código Pascal:
Ver original
PROGRAM AdivinadorSimple; CONST MAX_INTENTOS= 10; //El número máximo de intentos. TOPE= 30; //El número más alto que se puede generar. VAR numero_a_adivinar, numero_leido: INTEGER; adivinado: BOOLEAN; (*La variable adivinado será TRUE cuando el usuario acierte, y FALSE mientras esto no suceda.*) intento_actual: INTEGER; //Un contador que nos dirá en qué intento vamos. BEGIN randomize; //Decimos al programa que utilizaremos random en algún lado. numero_a_adivinar:= Random(TOPE) + 1; adivinado:= FALSE; //La inicializamos en FALSE porque aún no adivinamos nada. intento_actual:= 0; //Aún no hemos intentado adivinar nada. WriteLn('Ingrese números para intentar adivinar:'); WriteLn; WHILE (NOT adivinado) AND (intento_actual< MAX_INTENTOS) DO (*Vean este encabezado. El WHILE se repetirá mientras la variable adivinado sea FALSE porque tiene el operador NOT, y mientras a su vez el número de intentos sea menor que el máximo de intentos posibles. Si estas condiciones no se cumplen ambas a la vez, la condición AND vale FALSE y el WHILE termina.*) BEGIN intento_actual:= intento_actual + 1; //Sumamos 1 al número de intentos. Write(intento_actual,' --> '); //Mostramos el intento actual. ReadLn(numero_leido); //Leemos el número que el usuario ingresa. (*Si el número es correcto, la variable adivinado se vuelve TRUE, en caso contrario seguirá valiendo FALSE tal como al inicio.*) IF numero_leido= numero_a_adivinar THEN adivinado:= TRUE; END; (*El WHILE puede haber terminado por dos cosas, o adivinamos o perdimos. Si adivinamos entonces la variable adivinado será TRUE, en caso contrario será FALSE. Usamos eso para distinguir qué mensajes mostrar al usuario.*) IF adivinado THEN WriteLn('Felicitaciones ¡¡¡GANASTE!!!') ELSE WriteLn('Lamentablemente has perdido.'); ReadLn; //Simplemente para visualizar lo que el programa nos muestra. END.
Continuamos en la parte b.