================
== Pythonisas ==
================
Brujas del teclado. Alquimistas de los bits.

Práctica 1.4 — Academia Pythonisa IV: Reino de Dragones

prácticas

Misión: Las dos cuevas

Contexto mágico: La Academia organiza su primera expedición al Reino de Dragones. Allí, cada dragón vive en su cueva junto a su tesoro. Algunos son amistosos y lo comparten; otros están hambrientos y se comen a quien entre. Delante de ti hay dos cuevas… y no sabes qué dragón vive en cada una.

Hasta ahora tus programas eran una lista de órdenes de arriba abajo. Este juego es el primero que organizarás en funciones: pequeños hechizos con nombre que puedes invocar cuando los necesites. Y antes de escribir una sola línea, lo diseñarás con un diagrama de flujo.

Basado en el Capítulo 5 de Inventa tus propios juegos de computadora con Python – Al Sweigart (Cap. 5: Reino de dragones)

Así se ve una partida:

Estás en una tierra llena de dragones. Frente a ti
hay dos cuevas. En una de ellas, el dragón es generoso y amigable
y compartirá su tesoro contigo. El otro dragón es codicioso
y está hambriento, y te devorará inmediatamente.

¿A qué cueva quieres entrar? (1 o 2)
1
Te aproximas a la cueva...
Es oscura y espeluznante...
¡Un gran dragón aparece súbitamente frente a ti! Abre sus fauces y...

¡Te engulle de un bocado!
¿Quieres jugar de nuevo? (sí o no)
no

Los problemas a resolver

  1. Diseñar antes de programar — ¿Qué pasos tiene el juego? ¿Dónde hay que decidir? ¿Dónde se vuelve atrás? Un diagrama de flujo te responde antes de escribir código

  2. Organizar en funciones — Mostrar la introducción, elegir cueva, explorarla… Cada tarea es una función con def. El programa principal solo las invoca

  3. Pasar información — explorar_cueva() necesita saber qué cueva has elegido. Se lo das como argumento, y ella lo recibe como parámetro

  4. Devolver resultados — elegir_cueva() tiene que devolver la cueva elegida al programa principal. Para eso está return

  5. Validar la entrada — Si escriben 3 o patata, hay que volver a preguntar. Hace falta un while con una condición doble: and

  6. ¿Dónde vive cada variable? — Una variable creada dentro de una función no existe fuera. Es el entorno local frente al global

  7. El suspense — Un time.sleep(2) entre frase y frase convierte un programa en una historia


Herramientas a tu disposición

HerramientaPara qué sirve
def nombre(parametro):Define una función (un hechizo con nombre)
return valorLa función devuelve un valor a quien la llamó
nombre(argumento)Llama (invoca) a la función
and, or, notCombinan condiciones
'''...'''Cadena de varias líneas
import timeMódulo del tiempo
time.sleep(segundos)Pausa el programa

Tablas de verdad (pruébalas en la Shell):

ABA and BA or Bnot A
TrueTrueTrueTrueFalse
TrueFalseFalseTrueFalse
FalseTrueFalseTrueTrue
FalseFalseFalseFalseTrue

Desafío 1: Diseña el juego (diagrama de flujo)

Antes de programar, dibuja el diagrama de flujo del juego. Cada caja es una acción; cada flecha, el camino a la siguiente. Donde el camino se divide, hay una decisión.

Requisitos:

  • Cajas de Inicio y Fin
  • Todas las acciones: mostrar introducción, elegir cueva, comprobar dragón, ganar/perder, jugar de nuevo
  • La flecha que vuelve atrás si la jugadora quiere jugar otra vez
  • La flecha que vuelve atrás si escribe una cueva que no existe (¡esta no está en el libro!)

Hazlo en papel (y fotografíalo) o en draw.io (y expórtalo a PNG). Cuando lo tengas, compáralo con el del libro:

Figure 1: Diagrama de flujo de Reino de Dragones (Al Sweigart, CC BY-NC-SA)

Figure 1: Diagrama de flujo de Reino de Dragones (Al Sweigart, CC BY-NC-SA)

Diagnóstico: pon el dedo en Inicio y sigue las flechas: tu dedo es la ejecución del programa. ¿Puedes llegar a Fin por todos los caminos? ¿Hay algún camino sin salida?


Desafío 2: Completa el código

Renómbralo a dragones.py. Completa los huecos ___ y ...:

# dragones.py — Práctica 1.4: Reino de Dragones
# Completa los huecos marcados con ___ y ...
import random
import ___


def mostrar_introduccion():
    print('''Estás en una tierra llena de dragones. Frente a ti
hay dos cuevas. En una de ellas, el dragón es generoso y amigable
y compartirá su tesoro contigo. El otro dragón es codicioso
y está hambriento, y te devorará inmediatamente.''')
    print()


def elegir_cueva():
    cueva = ''
    while cueva != '1' ___ cueva != '2':
        print('¿A qué cueva quieres entrar? (1 o 2)')
        cueva = input()

    ___ cueva


def explorar_cueva(cueva_elegida):
    print('Te aproximas a la cueva...')
    time.sleep(2)
    print('Es oscura y espeluznante...')
    time.___(2)
    print('¡Un gran dragón aparece súbitamente frente a ti! Abre sus fauces y...')
    print()
    time.sleep(2)

    cueva_amigable = random.randint(1, 2)

    if cueva_elegida == ___(cueva_amigable):
        print('¡Te regala su tesoro!')
    else:
        ...


jugar_de_nuevo = 'sí'
while jugar_de_nuevo == 'sí' ___ jugar_de_nuevo == 's':
    mostrar_introduccion()
    numero_de_cueva = ___()
    explorar_cueva(___)

    print('¿Quieres jugar de nuevo? (sí o no)')
    jugar_de_nuevo = input()

Pistas:

  • En elegir_cueva() el bucle debe repetirse mientras la cueva no sea 1 y no sea 2
  • ¿Por qué comparamos con str(cueva_amigable) y no con cueva_amigable a secas? (Recuerda la P1.2: ¿qué tipo devuelve input()?)
  • El while final debe seguir si responden sí o s

Diagnóstico: escribe 3, hola y una cadena vacía cuando te pregunte la cueva. El juego tiene que volver a preguntar las tres veces. Si acepta el 3, revisa el and.


Desafío 3: El experimento de los entornos

Añade temporalmente al final del programa (fuera de cualquier función):

print(cueva_amigable)

Ejecuta. ¿Qué error sale? ¿Por qué, si la variable existe dentro de explorar_cueva()?

Ahora prueba lo contrario: dentro de explorar_cueva() añade print(jugar_de_nuevo). ¿Funciona? ¿Por qué?

Diagnóstico: abre Ver → Variables mientras juegas. Verás que las variables de una función aparecen… y desaparecen cuando la función termina.

Borra estas pruebas antes de entregar y explica lo que has descubierto en explicacion.md.


Desafío 4: Tu propio reino

Ahora que funciona, hazlo tuyo. Elige al menos una ampliación y añádela también a tu diagrama de flujo:

  • Una tercera cueva (¿con un dragón dormido?)
  • Un segundo encuentro si sobrevives (un puente, un acertijo…)
  • Una función mostrar_tesoro(monedas) que reciba un parámetro y muestre el tesoro ganado
  • Otra historia completamente distinta con la misma estructura: dos puertas, dos pociones, dos portales…

Entrega

PRACTICA1.4/
+-- dragones.py            <-- el juego completo y ampliado
+-- diagrama_flujo.png     <-- foto o exportación de draw.io (con tu ampliación)
+-- explicacion.md         <-- tus respuestas a "Explica tu código"

Súbela al servidor SFTP del aula (put -r PRACTICA1.4).

Requisitos funcionales:

  • El juego se organiza en funciones con def
  • elegir_cueva() valida la entrada y devuelve la cueva con return
  • explorar_cueva() recibe la cueva como parámetro
  • Se puede volver a jugar respondiendo sí o s
  • Hay pausas con time.sleep()
  • El diagrama de flujo refleja tu versión del juego, incluida la ampliación

Explica tu código

  1. ¿Qué diferencia hay entre parámetro y argumento? Señala uno de cada en tu código
  2. ¿Qué pasaría si quitas el return cueva de elegir_cueva()? Pruébalo
  3. ¿Qué descubriste en el Desafío 3 sobre dónde “viven” las variables?

Rúbrica por competencias

CriterioHechicería (9-10)Aprendizaje (6-8)Iniciación (0-5)Peso
Diagrama de flujoCompleto, con bucles de repetición y validación, y la ampliaciónCorrecto pero sin validación o sin ampliaciónIncompleto o sin diagrama20%
Funciones (def, return, parámetros)Funciones claras, return y parámetros bien usadosFunciona pero alguna función no devuelve o no recibeTodo el código fuera de funciones30%
Bucles y operadores booleanosValidación con and, repetición con or, sin fallosUna de las dos condiciones fallaAcepta entradas no válidas15%
Entornos global y localExplica con precisión el experimento del Desafío 3Lo prueba pero la explicación es vagaNo lo realiza10%
Suspense y creatividadsleep() bien dosificado, ampliación originalAmpliación mínimaSin ampliación15%
Explica tu códigoRespuestas claras, con pruebas propiasCorrectas pero sin probarSin explicacion.md10%

Bonus (hasta +2)

BonusDescripciónPuntos
Arte ASCII del dragónEl dragón aparece dibujado (usa r'''...''')+0.5
MarcadorCuenta partidas ganadas y perdidas, y lo muestra al terminar (con f-strings)+0.5
Dragones con carácterCada cueva puede tener un dragón distinto, elegido al azar entre varios+1.0

Conceptos clave

ConceptoDónde lo ves
Diagrama de flujoEl mapa del juego antes de programarlo
Sentencia defdef elegir_cueva(): crea una función
Llamada a funciónelegir_cueva() la ejecuta
Parámetro / argumentodef explorar_cueva(cueva_elegida) / explorar_cueva(numero_de_cueva)
returnreturn cueva devuelve el valor al programa principal
Operadores booleanoscueva != '1' and cueva != '2'
Entorno localcueva_amigable solo existe dentro de explorar_cueva()
Entorno globaljugar_de_nuevo existe en todo el programa
Cadena multilíneaLa introducción entre '''...'''
time.sleep()Pausas para crear suspense

“Una función es un hechizo con nombre: lo escribes una vez y lo invocas mil.”