Introducción a la programación con
CodeCombat (Python)
CodeCombat
Para dominar la programación no basta con comprender los conceptos fundamentales, sino que
debemos practicar una y otra vez hasta dominarlos por completo, algo que suele resultar bastante
aburrido en las clases de programación convencionales.
[Link] facilita dicha práctica, proporcionándonos multitud de ejemplos en los que,
con pequeñas variaciones, se nos introduce de forma gradual y entretenida en las herramientas básicas
(y no tan básicas) del mundo de la programación.
Aunque el juego es muy accesible, es fácil que nos atasquemos en algunas ocasiones, aunque basta
con pulsar el objetivo no resaltado para continuar la partida.
Selección de mundo y personaje
Según entramos a nuestra nueva partida, veremos como aparece un mapa con varios mundos. Por
ahora sólo podremos entrar al primero, la Mazmorra de Kithgar, en la que practicaremos la sintaxis
más básica de la programación; una vez terminada la mazmorra podremos acceder al segundo mundo
(condicionales), después al tercero (control de bucles) y así hasta el cuarto (bucles condicionales,
funciones, etc.), donde ya podremos decir que hemos visto los fundamentos de la programación y
acumulado docenas de horas de práctica.
Al pulsar el botón Jugar entramos en la mazmorra, donde una gran flecha amarilla nos deja claro dónde
tenemos que hacer clic para empezar. Esta flecha nos acompañará a lo largo de todo el juego, aunque
como veremos a veces estorba más que ayuda, ya que podemos pasar por alto cosas interesantes o
incluso puede dirigirnos a la opción equivocada.
En éste caso haremos caso de lo que nos dice, y sobre la marcha aparece la pantalla de selección de
héroe. Aunque hay ciertas diferencias a la hora de jugar, no afectan demasiado a la programación, así
que en este caso optaremos por la primera opción, una guerrera con un alto nivel de vida y ataque.
Mucho más importante que elegir nuestra heroína es la selección del lenguaje de
programación en el desplegable que hay bajo ella, que en nuestro caso será Python
(valor por defecto), pero que también puede ser JavaScript, CoffeScript o Lua.
Por último, tendremos que pulsar el botón Siguiente héroe para empezar a jugar.
A continuación, entraremos en la pantalla de selección de equipo; de nuevo aparece la flecha amarilla,
indicándonos que las botas son imprescindibles (sin ellas no podremos dar órdenes de movimiento).
En teoría es posible desbloquear equipo extra, como la armadura (vida) y la espada (ataque), pero para
ello necesitaremos ir recogiendo gemas a lo largo de los distintos niveles del juego. Una vez equipadas
las botas se activará el botón jugar y podremos entrar al dungeon.
Según empecemos a jugar Anya se dirigirá a la derecha, ya que el programa incluye la línea de código
[Link](), pero a continuación se quedará inmóvil.
Para continuar tendremos que completar el programa, añadiendo los movimientos
necesarios para cruzar el camino sin chocar con los pinchos (primero abajo, y luego de
nuevo a la derecha); el código para los movimientos aparece en amarillo junto a las
botas (columna Methods), y también se nos sugerirá en pantalla al tratarse de un nivel
inicial.
A medida que escribimos el código veremos que los nuevos movimientos se señalizan en la pantalla de
la izquierda; lo único molesto es que el juego tiende a probar todo lo que escribimos sobre la marcha,
siendo conveniente pausar la reproducción para que no nos estorbe. También es posible gestionar la
reproducción mediante la barra de control (color amarillo), pasar a pantalla completa, controlar el
audio, etc.
Una vez terminado pulsamos el botón Hecho, se nos entregará nuestra recompensa (experiencia y
gemas) y volveremos de nuevo al mapa de la mazmorra, donde se nos señalará nuestro próximo
objetivo.
Comentario sobre programación estructurada
Acabamos de completar nuestro primer programa y, aunque todavía no hemos empezado
a utilizar la sintaxis básica, este primer ejercicio nos ayuda a entender la naturaleza lineal de la
programación, en la que una línea se ejecuta después de otra, siendo imprescindible adaptar nuestra
forma de pensar a dicho comportamiento secuencial.
El programador experimentado habrá notado algo más: el héroe es en realidad un objeto (hero) que
dispone de una serie de métodos (moveRight(), moveLeft(), etc.) que hemos ido invocando a medida
que los necesitábamos. Resulta gracioso que, una vez completado el aprendizaje básico de la
programación, nuestro objetivo será justamente crear clases que definirán nuestros propios objetos y
métodos… así que en cierta forma estamos viendo el resultado final de nuestros esfuerzos.
Progresión inicial en el juego
El nivel 2 (Gemas en las profundidades) nos proporciona un cinturón que no aporta nada nuevo, sólo
una pizca de vida extra, y un nuevo recorrido en el que ésta vez conseguiremos algunas gemas extra.
Si nos fijamos un poco veremos que la propia pantalla de presentación nos indica la ruta a seguir, así
que este nivel no debería causarnos ninguna dificultad. Además, justo encima del código de nuestro
programa podemos pulsar el botón azul Hints (pistas), que nos ayudará en caso de quedar bloqueados.
El nivel 3 es similar (hay que dar un rodeo para evitar al ogro), pero el nivel 4 nos da una espada, con
lo que ya podremos atacar. Como la espada no es muy buena y no hace demasiado daño, tendremos
que atacar dos veces a cada enemigo, que se identificará por su nombre escrito entre comillas. Además,
habrá que avanzar hacia la derecha después de matar al primer ogro, no sólo para
coger la gema, sino porque no es posible atacar a un enemigo si no está en nuestra
línea de visión.
Recuerde que, si liamos mucho el código, siempre podemos usar el botón Hints o Pistas para solicitar
pistas, o pulsar Reiniciar para volver a dejarlo como estaba al principio.
Ahora la cosa se complica un poco: las estrellas amarillas marcan los niveles que ya hemos resuelto, y
la banderola roja marca el siguiente a resolver, pero aparecen también cuatro banderolas azules; se
trata de niveles de pago, únicamente disponibles para aquellos jugadores que dispongan de una
suscripción, así que si no tenemos una seguiremos con el camino normal y empezaremos el nivel 5
(banderola roja, a la derecha en la imagen).
La solución del nivel 5 parece bastante sencilla, en teoría es suficiente con atacar dos veces a cada uno
de los tres ogros ("Rig", "Gurt" y "Ack") para terminarlo, pero nuestra heroína no tiene suficiente vida
para sobrevivir al combate; necesita que le compremos una armadura con las gemas que hemos ido
adquiriendo a lo largo del juego.
Este es uno de los grandes atascos del juego, ya que si el aviso azul se cierra mucha
gente no sabe cómo comprar la armadura que necesitan; hay que pulsar el botón
Jugar, que nos llevará a la pantalla principal, y hacer clic en el icono del cofre (Objetos),
donde podremos desbloquear la armadura para a continuación pulsar en el aspa roja,
volver al juego, volver al juego, entrar de nuevo en el nivel 5 y equiparla cuando aparece el menú de
inventario, con lo que ya podremos completar el nivel.
A partir de este momento podemos comprar equipo con cierta libertad, ya que su uso no es crítico
para el progreso del juego, aunque siempre viene bien ir adquiriendo armaduras más fuertes (tener
más vida nos permite ser menos eficientes en el código durante los combates) o espadas capaces de
matar a los enemigos de un solo golpe.
Bucles
La programación se apoya en tres conceptos fundamentales: las órdenes matemáticas, las
condicionales (que actúan de forma distinta según la respuesta sea sí o no), y por último los bucles,
que permiten repetir fragmentos de código.
Normalmente el bucle se programa para dar un número limitado de vueltas, dependiendo de que se
cumpla una condición (bucle while) o se alcance un número especificado de antemano (bucle for); un
bucle sin fin o infinito es aquél que nunca para de dar vueltas y suele deberse a un error, atascando el
programa en la misma ubicación, aunque a veces se utilizan de forma intencionada, por ejemplo, en la
programación orientada a eventos, típica en los microcontroladores.
Muchos programas de CodeCombat recurren al bucle infinito "while True:" (la condición siempre es
veraz), ya que lo único que desea es repetir de forma continua un patrón. Tenemos nuestro primer
ejemplo en el nivel 6, Bailando del fuego, en el que una vez equipado el libro de bucles debemos
esquivar unas bolas de fuego moviéndonos continuamente de izquierda a derecha y de derecha a
izquierda.
Es fundamental observar que las líneas de movimiento tienen una sangría de 4
espacios (basta con presionar una vez el tabulador para obtener esa sangría) respecto
al comando while, lo que en Python significa que son parte del bucle, es decir, son los
elementos que se repetirán indefinidamente. Si añadimos el comando [Link]() sin sangrarlo
correctamente el bucle lo ignorará, repitiendo infinitamente [Link]().
El nivel 7 (Segundo laberinto de Kith) complica un poco más las cosas, ya que necesitaríamos 12
movimientos para atravesarlo, pero sólo se nos permiten 12 líneas de código.
Si nos fijamos en la pantalla de presentación, resulta bastante evidente que basta con repetir una
secuencia de cuatro movimientos (derecha, arriba, derecha, abajo) para atravesar el laberinto, así que
será suficiente con cinco líneas de código (una del bucle y cuatro de movimientos). Aprender a dividir
procesos en secuencias es uno de los pilares de la programación, ya que nos permite automatizarlas
mediante bucles.
Variables
Estamos en el nivel 8, Enemigo conocido, y vamos a entrar en contacto con otro
elemento fundamental de la programación: las variables.
En algunos lenguajes su definición puede ser bastante compleja, pero en Python las
variables vienen a ser lo mismo que las incógnitas en las fórmulas y ecuaciones matemáticas:
elementos que contienen un valor determinado. Eso sí, hay que tener en cuenta dos reglas al trabajar
con ecuaciones y variables:
• En programación lo único que puede haber a la izquierda del signo igual (=) es una variable, y
lo único que hace es asignar el valor de su derecha a la variable de la izquierda (más tarde veremos
que para comprobar si dos elementos distintos son iguales se utiliza un doble signo ==).
• El valor a la derecha debe estar definido; da igual que contenga constantes, fórmulas o
variables, pero se producirá un error si intentamos "leer" una variable a la que no se le ha asignado
previamente un valor.
Por ejemplo, matemáticamente X=X+1 no tiene sentido, sin embargo, en programación significa
"incrementa el valor de la variable en 1", ya que primero se calcula el lado derecho, sumando 1 al valor
de X (pero sin modificarla), y acto seguido se asigna el valor calculado a la izquierda, actualizando X.
Por supuesto, para que esto funcione X necesita tener algún tipo de valor antes de realizar la suma
(inicialización). Este tipo de cálculo suele utilizarse como contador en los bucles, ya que cada vez que
el bucle pasa por esa línea suma 1, pero X debe definirse fuera del bucle.
Las normas asociadas a las variables pueden resultar un poco confusas, pero irán quedando más claras
con la práctica. Por ejemplo, en el nivel 8 se definen tres variables cuyo contenido son los nombres de
los ogros a los que hay que atacar.
Los tres programas de las imágenes anteriores realizan la misma función, atacando dos veces a "Kratt",
"Gert" y "Ursa". En el primero escribimos sus nombres directamente en la función de ataque, en el
segundo los cargamos en las variables enemy1, enemy2 y enemy3, para luego leer su valor dentro de
las funciones de ataque, y en el tercero nos limitamos a ir actualizando el contenido de la variable
enemy para cambiar a quién vamos atacando.
Ojo, no debemos cometer el error de poner el nombre de las variables entre comillas:
[Link]("enemy1") no ataca a Kratt sino a un ogro llamado enemy1, que lógicamente no existe.
Un último detalle, podemos ver que el código del tercer programa se repite varias
veces; está pidiendo a gritos un bucle, siempre y cuando fuese posible cambiar el
contenido de la variable enemy en cada vuelta… y justo eso es lo que van a hacer las gafas
que equiparemos en el nivel 9.
Generalización
En teoría, para resolver el nivel 9 basta con obtener los nombres de los enemigos mediante el nuevo
"poder" otorgado por las gafas, [Link](), asignándolos a las variables enemy1,
enemy2 y enemy3. Sin embargo, ya hemos visto que también podemos usar la misma variable tres
veces, actualizando su valor, y en este caso podemos ver que el código es idéntico las tres veces (hemos
usado el truco de nombrar a la variable enemigo en español para ayudar a distinguirla de los comandos
del sistema).
Como el código se repite es posible utilizar un bucle; de esta forma no sólo ahorramos líneas de código
y hacemos que sea más fácil leerlo, sino que podemos enfrentarnos a un número infinito de enemigos
con sólo cuatro líneas de programa (tres si hemos comprado una buena espada).
En resumen, hemos generalizado la solución de un problema específico (matar tres ogros) para un
número infinito de ogros, haciendo que el programa sea mucho más útil. Además, el nivel 10 (Un caos
de Munchkins) nos pide que hagamos exactamente eso, así que el mismo código se aplica a ambos
niveles.
Niveles finales
El nivel 11 no aporta nada nuevo, limitándose a aplicar lo aprendido hasta el momento para que
busquemos una secuencia de movimientos que incluye detección y ataque a enemigos, todo ello en
un bucle de menos de 10 líneas.
En cambio, el nivel 12 aporta un elemento completamente nuevo, un martillo que
reemplaza a nuestra espada, quitándonos la capacidad de ataque, pero
permitiéndonos construir barreras o trampas explosivas, pero que reemplaza nuestra
espada. Es decir, que a partir de ahora tendremos que estar un poco atentos para elegir qué queremos
equipar, aunque el inicio del nivel suele dejárnoslo bastante claro, restringiendo los elementos que no
podemos usar.
Para el nivel 12 equiparemos el martillo, ya que debemos construir una barrera en los puntos indicados.
Podemos ver sus coordenadas dejando reposar el ratón sobre ellos, así que el programa final será muy
sencillo de implementar; simplemente copiaremos el comando de construcción ajustando las
coordenadas correctas, y nos moveremos hacia la derecha hasta salir por la puerta.
Segundo mundo
Al terminar la Mazmorra de Kithgar se desbloquean tres nuevos mundos; los dos pequeños son
prácticas para el desarrollo de juegos y páginas web, y sólo están disponibles para usuarios de pago. El
otro es el segundo mundo de CodeCombat, llamado Bosque de Backwoods, donde aprenderemos el
uso de las condicionales.
De buenas a primeras topamos con un problema; la flecha amarilla indica una banderola azul,
correspondiente a una suscripción premium, pero si nos fijamos un poco veremos una banderola roja
a su derecha, que es donde debemos pulsar.
El primer dungeon es extremadamente sencillo, limitándonos a construir dos vallas para bloquear el
acceso de los enemigos, tal y como hicimos al final del primer mundo.
El segundo nos obliga a cambiar las botas clásicas por otras que se mueven a coordenadas específicas.
De nuevo es bastante fácil, ya que a estas alturas deberíamos estar acostumbrados a utilizar
coordenadas. La idea es ir recogiendo las gemas para, al final, poner una barrera e irnos sin que nos
ataque el ogro gigante.
El problema es que hay cuatro gemas que no podemos recoger, ya que el gigante está delante.
Podemos dejar el programa, pero da rabia dejar esas gemas abandonadas… ¿a menos que haya una
solución?
Como sólo hay un enemigo podemos construir una trampa de fuego (fire-trap) en lugar de la barrera,
dirigiéndonos después a [37,13]; mientras que recogemos esa gema el gigante choca con la trampa y
muere, dejando el paso libre para las últimas gemas.
Este sería el código del caso anterior:
Condicionales
Por fin, el último y probablemente más importante de los bloques fundamentales de la programación,
la capacidad de tomar decisiones mediante sentencias condicionales. El tercer dungeon (Woodlan
Cubbies) nos devuelve la espada y nos ofrece un libro ampliado, que agrega las sentencias if-then-else
a la capacidad para generar bucles (si andamos jugando con el inventario hay que tener cuidado de no
volver a equipar por error el libro antiguo, o nos será imposible resolver los próximos niveles).
Antes de ponernos a resolver el nivel vamos a estudiar un poco el funcionamiento de las condicionales.
Empiezan con una sentencia if (si ocurre esto, entonces…) y a continuación viene una condición; si
dicha condición es cierta se ejecutan las líneas asignadas a la condicional mediante sangrado, y si no
se saltan.
Las condiciones más habituales son booleanas, es decir, arrojan un resultado si/no, y
suelen comparar igualdad (==), desigualdad (!=), mayor (>), menor (<), mayor o igual
(>=) y menor o igual (<=), aunque en algunos casos se utilizan otras operaciones lógicas.
Por ejemplo, consideremos un programa que divide X entre Y; en teoría es inofensivo, pero en la
práctica existe el riesgo de provocar una división por cero si Y es nulo, así que vamos a utilizar una
condicional para evitar que ocurra:
X=5
Y=2
if Y!=0:
print X/Y
Si dejamos el programa como está se realizará la división (el comando print lo mostraría en pantalla),
pero si cambiamos Y para que valga cero se saltará esa línea. El problema es que, al no hacer nada, no
queda claro lo que ha ocurrido, así que lo mejor sería mostrar un mensaje de error en el caso Y=0:
X=5
Y=0
if Y!=0:
print X/Y
if Y==0:
print "Error: división por cero"
Por último, es posible evitar la segunda condicional mediante el uso de la sentencia else (y si nó), que
se ejecuta en el caso de que el if que le precede no se cumple; es decir, if (condición) se realiza[ líneas
sangradas], y si nó se realizan [otras líneas sangradas].
X=5
Y=0
if Y!=0:
print X/Y
else:
print "Error: división por cero"
Volviendo al dungeon número 3, tenemos que ir a distintas ubicaciones en las que puede haber o no
ogros (se generan al azar en cada ejecución); el problema es que si no hay ogro enemy queda sin
definir, y por tanto se producirá un error de programa si intentamos atacar un ogro inexistente.
Afortunadamente podemos utilizar la condicional if de forma directa, comprobando si enemy está
definida (verdadero) o no (falso):
¡Cuidado con el 4º dungeon! Al principio se nos ofrecen como elementos equipables el libro antiguo
(sin condicionales) y los zapatos (movimiento sin coordenadas); si lo hacemos perderemos las
capacidades que necesitamos para completar el dungeon, al menos hasta que volvamos a equipar los
elementos correspondientes. Si no cometemos errores con el equipamiento la solución es sencilla, sólo
necesitamos un bucle con ataque condicional:
Es importante apreciar la doble sangría en el comando de ataque, ya que pertenece a la condicional,
que a su vez está contenida dentro de un bucle.
En el 5º dungeon (Hombro con hombro) elegiremos entre dos opciones, atacar un enemigo si está
cerca o volver a la posición original si no hay nadie a tiro; dicho de otra forma: si enemigo a tiro ataco,
si nó vuelvo.
Llegamos al sexto dungeon, Woodland Cleaver, y conseguimos una nueva habilidad de
ataque, que literalmente se traduce como partir, aunque también podríamos llamarlo
hachazo. El cleave es un ataque giratorio que mata a todos los enemigos alrededor del
personaje, pero tiene un problema: tiene un tiempo de carga determinado, y si
intentamos activarlo antes se descarga, perdiendo el ataque.
Cleave es un nuevo ejemplo del valor de las condicionales: si está listo lo uso, si no lo está ataco
normalmente (en este dungeon los enemigos están a la vista, así que necesitaremos comprobar que
existen antes de atacar):
Un último tropiezo
Llegados a este punto, una gran flecha señala una banderola doble, pero en realidad deberíamos
continuar con la roja, Backwoods Standoff.
La banderola doble es un punto de combate online, en el que los jugadores comparan sus habilidades,
y si hacemos clic sobre ella nos hace volver una y otra vez, aunque ganemos; en estos casos la única
solución que he encontrado es salir del juego, volver a entrar y hacer clic en la banderola correcta
(conviene ganar al menos una vez, ya que hace que desaparezca la flecha).
Este suele ser el último punto de bloqueo debido a la interfaz del juego; a partir de aquí los jugadores
suelen arreglarse bastante bien, excepto en los casos que se atascan debido a complejidades del
programa.
Por ejemplo, en el séptimo dungeon se nos ofrecen tres elementos a equipar, pero sólo se pone la
mejora de escudo ya que los otros dos son el libro antiguo y los zapatos. Por lo demás el código es
idéntico al anterior, activando cleave cuando es necesario, pero es fácil que el héroe
muera en este nivel por tener poca vida; en este caso los jugadores ya saben lo
bastante como para acceder al cofre y mejorar su equipo.
A partir de aquí las cosas se complican cada vez más: nuevos equipos, nuevos métodos de
programación, y por supuesto programas cada vez más complejos. Pero habiendo llegado hasta aquí
el auto-aprendizaje resulta mucho más fácil, y rara vez se quedará uno bloqueado; debemos recordar
que el botón PISTAS puede darnos pistas útiles y que, en el peor de los casos, siempre nos quedará
buscar el título del dungeon en Google, donde fácilmente podremos encontrar ejemplos del código
correcto.