1. Antes de comenzar
En este codelab de Kotlin, crearás otro juego de dados, Lucky Dice Roll, con el que se intentará lanzar un número de la suerte. El programa establecerá un número de la suerte y lanzará el dado. Luego, comparará el resultado del lanzamiento con el número de la suerte y, finalmente, mostrará un mensaje adecuado. Para lograr esto, aprenderás a comparar valores y a tomar decisiones diferentes en tu programa de Kotlin.
A fin de que puedas concentrarte en los conceptos de programación sin tener que preocuparte por la interfaz de usuario de la app, usarás la herramienta de programación de Kotlin basada en el navegador e imprimirás los resultados en la consola.
Requisitos previos
- Conocimientos para abrir, editar y ejecutar código en https://developer.android.com/training/kotlinplayground
- Capacidad de crear y ejecutar un programa en Kotlin que use variables, funciones con argumentos y clases con métodos, y que imprima un resultado en la consola
Qué aprenderás
- Cómo usar las sentencias
if
yelse
- Cómo comparar valores mediante operadores como igual que (
==
), mayor que (>
) y menor que (<
) - Cómo usar las sentencias
when
a fin de elegir una opción según un valor determinado - Qué es el tipo de datos
Boolean
y cómo usar sus valorestrue
yfalse
para la toma de decisiones
Qué compilarás
- Compilarás un juego de dados llamado Lucky Dice Roll, basado en Kotlin, que te permitirá especificar un número de la suerte. El jugador ganará si lanza ese número de la suerte.
Requisitos
- Una computadora con conexión a Internet
2. La toma de decisiones dentro del código
El programa Lucky Dice Roll debe determinar si el usuario lanzó un número de la suerte y recibirá felicitaciones o, de no ser así, si verá un mensaje que lo invite a volver a intentarlo.
Como desarrollador de apps, tendrás que tomar decisiones acerca de cómo debe comportarse la app y crear diferentes resultados para los usuarios.
Si estás compilando una app de compra, puedes mostrar pantallas diferentes según las opciones de entrega que elija el usuario. En el caso de los juegos de preguntas y respuestas, debes mostrar pantallas diferentes en función de si la respuesta del jugador es correcta o no. Según la app, podría haber muchos resultados posibles, los que deberás tener en cuenta en tu código.
En tu programa Lucky Dice Roll, la app debería contemplar diferentes casos, como los siguientes:
- Si el resultado del lanzamiento es el número de la suerte, muestra un mensaje de felicitaciones.
- De lo contrario, si el resultado no es el número de la suerte, muestra un mensaje que invite a volver a intentarlo.
Para agregar esta lógica a tu código, usa palabras clave especiales de Kotlin, como if
, else
y when
.
Veamos algunos ejemplos.
Usa una sentencia if
a fin de establecer una condición que se cumplirá
- Revisa el código que aparece a continuación. ¿Puedes adivinar cuál será el resultado?
fun main() {
val num = 5
if (num > 4) {
println("The variable is greater than 4")
}
}
- Copia y pega el código en el editor de programa de Kotlin y ejecuta el programa para observar el resultado.
The variable is greater than 4
El proceso de toma de decisiones de este programa es el siguiente:
- Crea una variable
num
y establécela en5.
- Si es verdadero que
num
es mayor que 4, imprime"The variable is greater than 4"
. - En todas las demás situaciones, no hagas nada.
En el ejemplo anterior, num
se estableció en 5. La sentencia if
compara si la variable es mayor que 4. Como eso es verdadero, el sistema ejecutará las instrucciones indicadas en las llaves y, luego, imprimirá el mensaje.
Observa el formato general de la sentencia if
:
- Comienza con la palabra clave
if
. - Sigue con dos paréntesis
()
. Dentro de los paréntesis, coloca la condición. Esa condición indica todo lo que puede sertrue
ofalse
. Por ejemplo, si un número es mayor que otro. - A continuación, agrega dos llaves
{}
. Dentro de ellas, coloca el código que se ejecutará si la condición estrue
.
if (condition-is-true) { execute-this-code }
Usa una sentencia if
para configurar una condición que no se cumplirá
- Cambia el valor de
num
a 3, como se muestra a continuación. ¿Qué esperas que suceda si ejecutas este código?
fun main() {
val num = 3
if (num > 4) {
println("The variable is greater than 4")
}
}
- Copia y pega el código en el editor de programa de Kotlin y ejecuta el programa para observar el resultado vacío.
Si se establece num
en 3, no se imprimirá nada, ya que el valor de num
es menor que 4. Por lo tanto, la condición de que num
es mayor que 4 es false
, el código entre las llaves no se ejecutará y no se imprimirá nada.
Usa else
a fin de crear una alternativa para las condiciones que no se cumplen
En lugar de no hacer nada, puedes ofrecer a tus usuarios una alternativa cuando no se cumpla una condición. Como sucede con el lenguaje común, puedes hacer esto mediante una sentencia else
.
- Agrega una sentencia
else
para imprimir un mensaje cuandonum
no sea superior a 4, como se muestra a continuación. ¿Qué esperas que suceda si ejecutas este código?
fun main() {
val num = 3
if (num > 4) {
println("The variable is greater than 4")
} else {
println("The variable is less than 4")
}
}
- Copia y pega el código en el editor de programa de Kotlin y ejecuta el programa para observar el resultado.
The variable is less than 4
- Ten en cuenta que, cuando
num
tenga un valor de 3, el programa imprimirá el mensaje "The variable is less than 4
" asociado con la sentenciaelse
, ya quenum
no es mayor que 4. - Cambia
num
a 5 y vuelve a ejecutar el programa. Ahora es cierto quenum
es mayor que 4 y el programa imprimirá "The variable is greater than 4
". - Cambia
num
a 4 y ejecuta tu programa. Ahora 4 no es superior a 4, y el programa imprimirá "The variable is less than 4
".
Si bien "The variable is less than 4
" es el resultado correcto para las condiciones que estableciste en el código, ese enunciado impreso no es preciso, ya que 4 no es menor que 4. Lo que puedes hacer es agregar otra condición que compruebe la tercera posibilidad, es decir, si num
es exactamente 4 y que, luego, imprima un enunciado correcto cuando esa condición resulte verdadera.
Usa una combinación de else
y if
para agregar condiciones alternativas
Puedes tener más de una condición. En el caso de ejemplo, esta es la forma de contemplar todas las posibilidades de num
:
- Si
num
es mayor que 4, imprime"The variable is greater than 4"
. - Sino, si
num
es igual a 4, imprime"The variable is equal to 4"
. - Sino, imprimir
"The variable is less than 4"
.
A estos se los conoce como los casos diferentes de la sentencia if-else. Hay 3 casos detallados.
El código actualizado se verá de la siguiente manera:
fun main() {
val num = 4
if (num > 4) {
println("The variable is greater than 4")
} else if (num == 4) {
println("The variable is equal to 4")
} else {
println("The variable is less than 4")
}
}
Observa los cambios que se indican a continuación:
- El valor de
num
ahora se establece en 4 a fin de que puedas probar la condición nueva. - Entre las sentencias
if
yelse
originales ahora existe una nueva sentenciaelse if
para el caso cuandonum
sea exactamente 4.
- Copia y pega el código anterior en el editor de programa de Kotlin y ejecuta el programa para observar el resultado.
The variable is equal to 4
- Experimenta: cambia el valor de
num
y observa cómo esto afecta el resultado. Cambianum
a 2 y 6 de modo que puedas ver que cada una de las condiciones aparece comotrue
.
Flujo de control
A partir de las sentencias if-else anteriores, el código se ejecutará, o fluirá, según lo establecido por las condiciones. La manera de guiar la ejecución mediante estos condicionales se denomina el "flujo de control" del programa.
- Supongamos que el
num
del lanzamiento del dado es 3. El programa verificará la primera condición (num > 4). Esto es falso, por lo que el programa verificará la siguiente condición (num == 4), que también es falso. Luego, el programa ejecutará el código de la sentencia else, que es la opción final. - Si el resultado del lanzamiento es 6, la primera condición (num > 4) será verdadera. El programa imprimirá el mensaje "
The variable is greater than 4
". Dado que esta condición es verdadera, no necesita comprobar el resto y no continuará con la sentencia if-else. - Usa otra combinación de if y else a fin de agregar condiciones alternativas.
3. Crea el juego Lucky Dice Roll
En esta sección, por medio del contenido que aprendiste en la tarea anterior, actualizarás el programa Lucky Dice Roll para comprobar si lanzaste un número de la suerte predeterminado. Si lo consigues, ¡ganas!
Configura tu código de partida
Estás iniciando el programa Lucky Dice Roll con un código similar al de la solución del programa Dice Roller anterior en Kotlin. Puedes editar la función main()
de tu código anterior para que coincida, o bien copiar y pegar el código siguiente para comenzar.
fun main() {
val myFirstDice = Dice(6)
val rollResult = myFirstDice.roll()
println("Your ${myFirstDice.numSides} sided dice rolled ${rollResult}!")
}
class Dice (val numSides: Int) {
fun roll(): Int {
return (1..numSides).random()
}
}
Verifica si se lanzó el número de la suerte
Primero, establece el número de la suerte y, luego, compara el resultado del lanzamiento con ese número.
- En
main()
, borra la sentenciaprintln()
. - En
main()
, agrega unval
llamadoluckyNumber
y establécelo en 4. Tu código debería verse de la siguiente manera:
fun main() {
val myFirstDice = Dice(6)
val rollResult = myFirstDice.roll()
val luckyNumber = 4
}
- A continuación, agrega una sentencia
if
con una condición dentro de los paréntesis()
que verifique sirollResult
es igual (==
) aluckyNumber
. Deja espacio entre las llaves{}
de modo que puedas agregar más código.
fun main() {
val myFirstDice = Dice(6)
val rollResult = myFirstDice.roll()
val luckyNumber = 4
if (rollResult == luckyNumber) {
}
}
- Dentro de las llaves
{}
, agrega una sentenciaprintln
para imprimir"You win!"
fun main() {
val myFirstDice = Dice(6)
val rollResult = myFirstDice.roll()
val luckyNumber = 4
if (rollResult == luckyNumber) {
println("You win!")
}
}
- Ejecuta el programa. Quizás necesites ejecutarlo varias veces antes de tener suerte y ver el mensaje ganador en el resultado.
You win!
Muestra una respuesta cuando no se haya lanzado el número de la suerte
Si el programa no muestra ningún comentario al usuario cuando este no gana, es posible que el usuario se pregunte si el programa funciona. Te recomendamos que siempre proporciones una respuesta cuando el usuario realice alguna acción. En el programa Lucky Dice Roll, puedes indicarle que no ganó mediante una sentencia else
.
- Agrega una sentencia
else
para imprimir"You didn't win, try again!"
.
fun main() {
val myFirstDice = Dice(6)
val rollResult = myFirstDice.roll()
val luckyNumber = 4
if (rollResult == luckyNumber) {
println("You win!")
} else {
println("You didn't win, try again!")
}
}
- Ejecuta el programa. Independientemente del resultado, el usuario siempre verá una notificación.
En este punto, el usuario sabrá si ganó o no, pero no conocerá el motivo. Siempre brinda información a los usuarios de modo que comprendan el resultado de sus acciones. Imagina que tu programa es una aplicación de préstamos. "La solicitud no fue aprobada porque tu calificación del crédito es baja" resulta mucho más informativo que "Lo sentimos, no podemos ofrecerte ningún préstamo. Vuelve a intentarlo". En el caso de Lucky Dice Roll, puedes dar un mensaje informativo diferente tras cada lanzamiento si el usuario no gana. Para lograr esto, usa varias sentencias else if
.
- Agrega sentencias
else if
a fin de imprimir un mensaje diferente para cada lanzamiento. Si lo necesitas, consulta el formato que aprendiste en la tarea anterior.
fun main() {
val myFirstDice = Dice(6)
val rollResult = myFirstDice.roll()
val luckyNumber = 4
if (rollResult == luckyNumber) {
println("You win!")
} else if (rollResult == 1) {
println("So sorry! You rolled a 1. Try again!")
} else if (rollResult == 2) {
println("Sadly, you rolled a 2. Try again!")
} else if (rollResult == 3) {
println("Unfortunately, you rolled a 3. Try again!")
} else if (rollResult == 5) {
println("Don't cry! You rolled a 5. Try again!")
} else {
println("Apologies! You rolled a 6. Try again!")
}
}
Mediante el código anterior, el programa realiza las siguientes acciones:
- Verifica si el
rollResult
es elluckyNumber
. - Si el
rollResult
es elluckyNumber
, imprime el mensaje ganador. - De lo contrario, comprueba si
rollResult
es 1 y, de ser así, imprime un mensaje que invita al usuario a intentarlo de nuevo. - De no ser así, comprueba si
rollResult
es 2 y, en ese caso, imprime un mensaje diferente para que el usuario vuelva a intentarlo. - Si tampoco se cumple esa condición, sigue realizando la validación hasta llegar al número 5.
- Si el número lanzado no fue ninguno del 1 al 5, la única opción que queda es que sea el número 6, por lo que no es necesario que se realice otra prueba con
else if
. Puedes llegar a esa última posibilidad mediante la sentenciaelse
final.
Dado que tener varios casos else if
es algo muy frecuente, Kotlin tiene una manera más sencilla de escribirlos.
4. Usa una sentencia when
En programación, es muy común realizar pruebas de muchos resultados, o casos, diferentes. A veces, la lista de resultados posibles puede ser muy extensa. Por ejemplo, si lanzaras un dado de 12 caras, tendrías 11 sentencias else if
entre el éxito y la else
final. Para facilitar la escritura y lectura de este tipo de sentencias, lo cual ayuda a evitar errores, Kotlin ofrece una sentencia when
.
Cambiarás tu programa de modo que use una sentencia when
. Una sentencia when
comienza con la palabra clave when
, seguida de paréntesis ()
. Dentro de ellos, se indicará el valor que se va a probar. A continuación, se agregarán llaves {}
a fin de que el código se ejecute en virtud de diferentes condiciones.
- En tu programa, en
main()
, selecciona el código desde la primera sentenciaif
hasta la llave}
que cierra la última sentenciaelse
y bórralo.
fun main() {
val myFirstDice = Dice(6)
val rollResult = myFirstDice.roll()
val luckyNumber = 4
}
- En
main()
, debajo de la sentencialuckyNumber
, crea una sentenciawhen
. Dado que tuwhen
debe realizar las pruebas con base en el resultado del lanzamiento, colocarollResult
entre los paréntesis()
. Agrega llaves{}
con espacios adicionales, como se muestra a continuación.
fun main() {
val myFirstDice = Dice(6)
val rollResult = myFirstDice.roll()
val luckyNumber = 4
when (rollResult) {
}
}
Como antes, primero prueba si rollResult
coincide con el luckyNumber
.
- Dentro de las llaves
{}
de la sentenciawhen
, agrega una sentencia que comparerollResult
conluckyNumber
y, si son iguales, que imprima el mensaje ganador. La sentencia se ve de la siguiente manera:
luckyNumber -> println("You win!")
Esto significa lo siguiente:
- Primero, coloca el valor que estás comparando con
rollResult
. Es, decir,luckyNumber
. - A continuación, ingresa una flecha (
->
). - Luego, agrega la acción que deseas que se realice en caso de haber una coincidencia.
Lee esto como "Si rollResult
es luckyNumber
, imprime el mensaje "You win!"
".
Tu código main()
tendrá el siguiente aspecto:
fun main() {
val myFirstDice = Dice(6)
val rollResult = myFirstDice.roll()
val luckyNumber = 4
when (rollResult) {
luckyNumber -> println("You win!")
}
}
- Usa el mismo patrón a fin de agregar líneas y mensajes para los posibles lanzamientos del 1 al 6 (excepto el 4), como se muestra a continuación. La función
main()
terminada debería verse de la siguiente manera:
fun main() {
val myFirstDice = Dice(6)
val rollResult = myFirstDice.roll()
val luckyNumber = 4
when (rollResult) {
luckyNumber -> println("You won!")
1 -> println("So sorry! You rolled a 1. Try again!")
2 -> println("Sadly, you rolled a 2. Try again!")
3 -> println("Unfortunately, you rolled a 3. Try again!")
5 -> println("Don't cry! You rolled a 5. Try again!")
6 -> println("Apologies! You rolled a 6. Try again!")
}
}
- Ejecuta el programa. No hay diferencias en el resultado, pero tu código será mucho más compacto y fácil de leer.
¡Felicitaciones! Aprendiste dos formas de imprimir mensajes en función de una condición. Esta es una herramienta poderosa para escribir programas interesantes.
5. Código de solución
fun main() {
val myFirstDice = Dice(6)
val rollResult = myFirstDice.roll()
val luckyNumber = 4
when (rollResult) {
luckyNumber -> println("You won!")
1 -> println("So sorry! You rolled a 1. Try again!")
2 -> println("Sadly, you rolled a 2. Try again!")
3 -> println("Unfortunately, you rolled a 3. Try again!")
5 -> println("Don't cry! You rolled a 5. Try again!")
6 -> println("Apologies! You rolled a 6. Try again!")
}
}
class Dice(val numSides: Int) {
fun roll(): Int {
return (1..numSides).random()
}
}
6. Resumen
- Usa una sentencia
if
a fin de establecer una condición para ejecutar algunas instrucciones. Por ejemplo, si el usuario lanza el número de la suerte, imprime un mensaje ganador. - El tipo de datos
Boolean
tiene valorestrue
yfalse
, y se puede usar para tomar decisiones. - Compara valores mediante operadores tales como igual que (
==
), mayor que (>
) y menor que (<
). - Usa una cadena de sentencias
else if
a fin de establecer varias condiciones. Por ejemplo, imprime un mensaje diferente para cada lanzamiento posible. - Usa una sentencia
else
al final de una cadena de condiciones a fin de detectar casos que pueden no estar contemplados de forma explícita. Si contemplas los casos para un dado de 6 caras, una sentenciaelse
alcanzaría los números 7 y 8 lanzados con un dado de 8 caras. - Usa una sentencia
when
como una forma compacta de ejecutar código con base en la comparación de un valor.
Forma general de if-else:
if (condition-is-true) {
execute-this-code
} else if (condition-is-true) {
execute-this-code
} else {
execute-this-code
}
Sentencia when:
when (variable) {
matches-value -> execute-this-code
matches-value -> execute-this-code
...
}
7. Más información
8. Practica por tu cuenta
Haz lo siguiente:
- Cambia
myFirstDice
para que tenga 8 caras y ejecuta tu código. ¿Qué ocurre entonces?
Sugerencia: Cuando aumentas la cantidad de caras, la sentencia when
deja de contemplar todos los casos, por lo que no se imprimirá nada en los casos no contemplados.
- Corrige la sentencia
when
a fin de que tenga en cuenta las 8 caras. Puedes hacer esto si agregas los casos que correspondan a los números adicionales. Desafío: En lugar de agregar un caso nuevo para cada número, usa una sentenciaelse
a fin de abarcar todos los casos que no están contemplados de forma explícita.
Sugerencia: Puedes agregar más casos para contemplar más caras. Esa es una buena forma de hacerlo si deseas un mensaje diferente para cada número posible. También puedes usar una sentencia else
y, luego, imprimir el mismo mensaje para todas las caras mayores a las 6 contempladas en el código actual.
- Cambia
myFirstDice
para que tenga solo 4 caras. ¿Qué ocurre entonces?
Sugerencia: Cambiar la cantidad de caras de un dado por un número inferior al contemplado por la sentencia when
no tiene un efecto evidente, ya que todos los casos posibles seguirán estando contemplados.