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
ifyelse - Cómo comparar valores mediante operadores como igual que (
==), mayor que (>) y menor que (<) - Cómo usar las sentencias
whena fin de elegir una opción según un valor determinado - Qué es el tipo de datos
Booleany cómo usar sus valorestrueyfalsepara 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
numy establécela en5. - Si es verdadero que
numes 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 sertrueofalse. 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
numa 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
elsepara imprimir un mensaje cuandonumno 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
numtenga un valor de 3, el programa imprimirá el mensaje "The variable is less than 4" asociado con la sentenciaelse, ya quenumno es mayor que 4. - Cambia
numa 5 y vuelve a ejecutar el programa. Ahora es cierto quenumes mayor que 4 y el programa imprimirá "The variable is greater than 4". - Cambia
numa 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
numes mayor que 4, imprime"The variable is greater than 4". - Sino, si
numes 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
numahora se establece en 4 a fin de que puedas probar la condición nueva. - Entre las sentencias
ifyelseoriginales ahora existe una nueva sentenciaelse ifpara el caso cuandonumsea 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
numy observa cómo esto afecta el resultado. Cambianuma 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
numdel 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 unvalllamadoluckyNumbery 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
ifcon una condición dentro de los paréntesis()que verifique sirollResultes 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 sentenciaprintlnpara 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
elsepara 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 ifa 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
rollResultes elluckyNumber. - Si el
rollResultes elluckyNumber, imprime el mensaje ganador. - De lo contrario, comprueba si
rollResultes 1 y, de ser así, imprime un mensaje que invita al usuario a intentarlo de nuevo. - De no ser así, comprueba si
rollResultes 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 sentenciaelsefinal.
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 sentenciaifhasta la llave}que cierra la última sentenciaelsey 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 tuwhendebe realizar las pruebas con base en el resultado del lanzamiento, colocarollResultentre 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 comparerollResultconluckyNumbery, 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
ifa 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
Booleantiene valorestrueyfalse, 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 ifa fin de establecer varias condiciones. Por ejemplo, imprime un mensaje diferente para cada lanzamiento posible. - Usa una sentencia
elseal 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 sentenciaelsealcanzaría los números 7 y 8 lanzados con un dado de 8 caras. - Usa una sentencia
whencomo 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
myFirstDicepara 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
whena 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 sentenciaelsea 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
myFirstDicepara 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.