Batalla Pokémon con while en Swift

Resumen

¿Quieres practicar funciones, diccionarios y ciclos en Swift con un reto real? Vas a construir una batalla Pokémon paso a paso, usando while, if y unwrap de opcionales para decidir el ganador. Es el ejercicio ideal si ya dominas variables, condicionales y recorridos.

Qué reto resuelve la batalla Pokémon en Swift

La idea es escribir una función que reciba dos diccionarios, uno por cada Pokémon, con sus puntos de vida (PV) y puntos de ataque (PA). El primer Pokémon ataca, el segundo responde si sigue vivo, y la función retorna un string con el ganador cuando alguno se queda sin vida [2:10].

Este tipo de ejercicio refleja la lógica que usas a diario en una app real: recorrer listas, filtrar resultados o validar estados, como cuando Platzi muestra cursos o aplica búsquedas por categoría [0:20].

¿Qué hace un ataque en este reto? Resta los puntos de ataque del atacante a los puntos de vida del defensor. Si los PV quedan en cero o menos, ese Pokémon pierde.

Por qué los parámetros de una función en Swift son constantes

Al entrar al editor, lo primero que descubres es que los parámetros de una función en Swift llegan como constantes (let). Si intentas modificar pokemon1["PV"] = 0 dentro de la función, Xcode marca error [3:30].

La solución es simple: copia los parámetros a variables locales con var.

  • var p1 = pokemon1 para tener una copia mutable del primer Pokémon.
  • var p2 = pokemon2 para hacer lo mismo con el segundo.
  • A partir de ahí ya puedes restarles vida sin que el compilador se queje.

Y aquí viene el segundo obstáculo. Cuando obtienes un valor de un diccionario por su llave, Swift te lo devuelve como opcional, porque esa llave podría no existir [4:30]. Por eso, cada vez que leas p1["PV"] tienes que hacerle unwrap antes de compararlo con números.

¿Qué es un opcional en Swift? Es un valor que puede existir o ser nil. Como no sabes si la llave de un diccionario existe, Swift te obliga a desempaquetarlo antes de usarlo en operaciones.

Cómo estructurar el ciclo while para la batalla

La columna vertebral del ejercicio es un while que se ejecuta mientras ambos Pokémon estén vivos.

Cómo controlar el turno con una variable

Declara una variable turno que arranca en 1, indicando que el Pokémon 1 ataca primero [5:40]. Dentro del while, validas con un if si turno == 1 o si le toca al Pokémon 2.

La condición del ciclo es directa: mientras los PV de p1 sean mayores a cero y los PV de p2 también, la batalla continúa. Cuando uno cae, el ciclo se rompe y la función retorna al ganador.

Cómo aplicar el ataque y validar la vida restante

Dentro del turno del Pokémon 1, la línea clave es restar al defensor:

  • p2["PV"] = p2["PV"]! - p1["PA"]! reduce la vida del rival.
  • Luego, un if verifica si p2["PV"]! > 0; si es así, cambia turno = 2.
  • En el else, ejecuta return "Ganó Pokémon 1" para terminar la función al instante.

El turno del Pokémon 2 es espejo del primero: cambias las variables para que ahora p1 sea quien recibe el daño, y validas si todavía puede contraatacar.

¿Qué pasa cuando usas return dentro de un while? La función termina inmediatamente. Swift no sigue evaluando el ciclo ni el resto del código.

Cómo imprimir el resultado y probar la función

La función ya retorna el ganador, pero si solo la llamas sin guardar el valor, no verás nada en consola. Asigna la salida a una variable y luego imprímela.

  • let resultado = simularBatallaPokemon(p1, p2) guarda el ganador.
  • print(resultado) lo muestra en la consola de Xcode.
  • Cambia los PV de Pikachu a 500 y verás que ahora gana el Pokémon 1, demostrando que la lógica responde al cambio de datos [10:30].

Un detalle de estilo importante: dentro de los strings puedes usar tildes, eñes o signos especiales sin problema, porque son cadenas de caracteres. Pero evita esos caracteres al nombrar variables o funciones, porque Swift te lanzará un error de compilación [8:30].

Habilidades y conceptos clave del ejercicio

Este reto consolida varias habilidades fundamentales de Swift que vas a reutilizar siempre:

  • Funciones con parámetros tipo diccionario: aprendes a recibir estructuras de datos completas y trabajarlas internamente.
  • Mutabilidad con var: descubres por qué necesitas copiar parámetros para modificarlos.
  • Desempaquetado de opcionales (unwrap): lo aplicas cada vez que lees una llave de diccionario.
  • Ciclos while con condición compuesta: dos validaciones unidas con && para mantener viva la batalla.
  • Control de flujo con if/else y return temprano: terminas la función en el momento exacto en que se define el ganador.

Con esto cierras el módulo de Fundamentos de programación con Swift, ya manejando variables, condicionales, arreglos, conjuntos y diccionarios. ¿Tu solución fue distinta a la planteada aquí? Cuéntame en los comentarios qué cambiarías y qué dificultades te encontraste.