DEV Community

Maximiliano Burgos
Maximiliano Burgos

Posted on

Curso Kotlin | #19. Pair

Bienvenido/a a otro capítulo del Curso de Kotlin! Podés consultar el curso completo desde este link que te dejo acá. Podés seguirme por LinkedIn o Twitter si querés estar al tanto de las próximas publicaciones.

A veces necesitamos relacionar dos valores y almacenarlos en una variable única, y para ello tenemos a Pair.

La estructura de Pair es muy sencilla. Imaginemos que necesitamos almacenar el nombre y apellido de una persona. Esto implica dos valores de tipo String. Por lo cual, lo podemos hacer de la siguiente manera:

val person = Pair<String, String>("Maxwell", "Tompson")
Enter fullscreen mode Exit fullscreen mode

En principio, Pair nos pide que especifiquemos los tipos de datos que se van a almacenar en la variable; algo similar a la vez que estudiamos arrays. Luego, por parametro inicializamos el mismo, pasándole nuestros dos elementos. Podemos quitar “” porque Kotlin, al leer los parámetros que introducimos, infiere el tipo necesario.

val person = Pair("Maxwell", "Tompson")
Enter fullscreen mode Exit fullscreen mode

Para accederlo, existen dos atributos llamados first y second:

println("Hola ${person.first} ${person.second}")
output: Hola Maxwell Tompson
Enter fullscreen mode Exit fullscreen mode

Como ven, la utilización de Pair es extremadamente sencilla, pero útil. Podemos utilizarla en el contexto de una lista de variables, por ejemplo:

val persons = arrayOf(
    Pair("Maxwell", "Tompson"),
    Pair("Tomas", "Voltor"),
)

println("Hola ${persons[0].first} ${persons[0].second}")
Enter fullscreen mode Exit fullscreen mode

¡Termina el corte publicitario!

Ahora que les he demostrado (y promocionado) el poder de Pair, volvamos a nuestro juego para darle la forma final a la funcionalidad del diálogo. En principio cambiaremos cada array de respuesta por un Pair, de la siguiente manera:

Pair(1, "1. Si, soy nuev@")
Enter fullscreen mode Exit fullscreen mode

Habrá que hacerlo con cada uno, pero les voy a dejar el trabajo final:

val conversation = arrayOf(
    arrayOf(
        "Bienvenido a Pueblo Ceniza! Eres nuev@ por aqui?",
        arrayOf(
            Pair(1, "1. Si, soy nuev@"),
            Pair(2, "2. No es mi primer visita!")
        )
    ),
    arrayOf(
        "Espero que puedas hacer nuevos amigos!",
        arrayOf(
            Pair(0, "0. Gracias!")
        )
    ),
    arrayOf(
        "Ya me parecía que tu nombre me resultara conocido!",
        arrayOf(
            Pair(0, "0. Gracias!")
        )
    ),
)
Enter fullscreen mode Exit fullscreen mode

Cada first de nuestros Pair va a llevar la referencia de la posición a la que saltará cuando se seleccione esa respuesta; y cada second contendrá el String de la respuesta en si misma. Esto es, en efecto, un Pair(). Una vez terminada de modificar nuestra variable de conversaciones, vamos al método letsTalk. Primero modificaremos la variable responses, porque ya no es un array de arrays:

val responses = conversation[line][1] as Array<Pair<Int, String>>
Enter fullscreen mode Exit fullscreen mode

Ahora es un arreglo de Pair, y esto nos resultará sencillo de tratar en nuestra iteración de respuestas:

for(res in responses) {
    println(res.second)
}
Enter fullscreen mode Exit fullscreen mode

El problema radica en que nosotros no tenemos una referencia a cada res.first para llevarnos la posición de la pregunta siguiente, pero esto lo solucionaremos pronto. En principio, dentro de nuestro try vamos a solicitar el input y convertirlo a un entero:

val input = readLine()?.toInt()
Enter fullscreen mode Exit fullscreen mode

Luego utilizaremos una lambda function para buscar si el número que utilizamos existe dentro de nuestro array de pares:

val isFound = responses.any { term -> term.first == input }
Enter fullscreen mode Exit fullscreen mode

Profundizaremos en el concepto de este tipo de funciones más adelante. Ahora tenemos una variable booleana isFound, la cual nos da la información de si se encontró o no la respuesta, y por ello vamos a armar su debido condicional:

if(isFound) {
    letsTalk(input!!)
} else {
    throw Exception()
}
Enter fullscreen mode Exit fullscreen mode

Si la encuentra, enviará la respuesta por parámetro de nuestra llamada recursiva. Necesitamos el bang bang operator porque readLine() devuelve un String Nullable, pero sabemos que no fallará porque se encontró el valor entero en la lista, gracias a la función any. En caso contrario, lanzamos una excepción para evitar código repetido (principio DRY), lo cual nos llevará al catch.

} catch (e: Exception) {
    println("No has respondido mi pregunta...")
    letsTalk(line)
}
Enter fullscreen mode Exit fullscreen mode

Aquí devolvemos un mensaje y llamamos recursivamente a nuestra función con el mismo parámetro para repetir la pregunta.

Conclusiones

¡Felicidades! Ahora tenemos un sistema de diálogos funcionando dinámicamente. Podés agregarle todas las preguntas y respuestas que quieras para ir navegando y testeando cada proceso de la misma. Lo siguiente será generar ciertos eventos entre los diálogos, como por ejemplo gastar dinero, puntos de vida, u otros atributos del heroe. ¡Se vienen tópicos muy interesantes!

Top comments (0)