Mini-reto: juego de adivinanza con intentos y pistas

Capítulo 10

Tiempo estimado de lectura: 6 minutos

+ Ejercicio

Objetivo del mini-reto

Vas a construir un juego de adivinanza por consola: el programa elige un número secreto y la persona intenta adivinarlo con un número limitado de intentos. En cada intento, el juego da una pista (“más alto” o “más bajo”) y, opcionalmente, pistas extra según qué tan cerca esté el intento.

Qué vas a practicar aquí (sin repetir teoría)

  • Diseñar reglas del juego (intentos, rango, pistas) y convertirlas en pasos concretos.
  • Combinar entrada/salida por consola con validación práctica.
  • Controlar el estado de la partida: intentos restantes, mejor aproximación, fin por acierto o por agotamiento.
  • Usar aleatoriedad con random para generar el número secreto.

Reglas del juego (especificación mínima)

Define estas reglas antes de programar (puedes cambiarlas luego):

  • Rango del número secreto: por ejemplo, de 1 a 100.
  • Intentos máximos: por ejemplo, 7.
  • Pista básica: si el intento es menor que el secreto, decir “más alto”; si es mayor, “más bajo”.
  • Fin de partida: si acierta, gana; si se acaban los intentos, pierde y se revela el número.

Pistas extra (opcional, pero recomendado)

Además de “más alto/más bajo”, añade una pista de cercanía calculando la distancia absoluta entre el intento y el secreto.

  • Si la distancia es 0: acertó.
  • Si la distancia es <= 3: “¡Muy caliente!”
  • Si la distancia es <= 10: “Caliente”
  • Si la distancia es <= 20: “Tibio”
  • Si la distancia es mayor: “Frío”

Estos umbrales son configurables. Lo importante es que la pista dependa de un cálculo sencillo y consistente.

Paso a paso: versión base (más alto / más bajo)

1) Genera el número secreto

Usa el módulo estándar random para elegir un entero dentro del rango.

Continúa en nuestra aplicación.
  • Escuche el audio con la pantalla apagada.
  • Obtenga un certificado al finalizar.
  • ¡Más de 5000 cursos para que explores!
O continúa leyendo más abajo...
Download App

Descargar la aplicación

import random

min_n = 1
max_n = 100
secret = random.randint(min_n, max_n)

2) Define intentos y controla el bucle de juego

Necesitas un contador de intentos restantes y un bucle que se repita mientras queden intentos y no se haya acertado.

max_tries = 7
tries_left = max_tries
won = False

3) Pide un número y valida que esté en rango

La entrada debe convertirse a entero y además debe estar dentro del rango. Si no lo está, no debería consumir un intento (decisión típica en juegos). Aquí se muestra una forma práctica: repetir la petición hasta obtener un entero válido en rango.

def ask_int_in_range(prompt, min_n, max_n):
    while True:
        raw = input(prompt)
        try:
            n = int(raw)
        except ValueError:
            print("Entrada inválida: escribe un número entero.")
            continue

        if n < min_n or n > max_n:
            print(f"Fuera de rango: debe estar entre {min_n} y {max_n}.")
            continue

        return n

4) Compara y muestra la pista

En cada intento: pedir número, comparar con el secreto, dar pista y actualizar intentos restantes.

import random

def ask_int_in_range(prompt, min_n, max_n):
    while True:
        raw = input(prompt)
        try:
            n = int(raw)
        except ValueError:
            print("Entrada inválida: escribe un número entero.")
            continue
        if n < min_n or n > max_n:
            print(f"Fuera de rango: debe estar entre {min_n} y {max_n}.")
            continue
        return n

min_n = 1
max_n = 100
secret = random.randint(min_n, max_n)

max_tries = 7
tries_left = max_tries
won = False

print(f"Adivina el número entre {min_n} y {max_n}. Tienes {max_tries} intentos.")

while tries_left > 0 and not won:
    guess = ask_int_in_range(f"Intento ({tries_left} restantes): ", min_n, max_n)

    if guess == secret:
        won = True
        print("¡Correcto!")
    else:
        tries_left -= 1
        if guess < secret:
            print("Pista: más alto.")
        else:
            print("Pista: más bajo.")

if not won:
    print(f"Se acabaron los intentos. El número era {secret}.")

Mejora 1: pistas de cercanía (frío/tibio/caliente)

Agrega una función que traduzca la distancia a una etiqueta. Esto hace el juego más “jugable” sin complicarlo.

def heat_hint(distance):
    if distance == 0:
        return "¡Exacto!"
    if distance <= 3:
        return "¡Muy caliente!"
    if distance <= 10:
        return "Caliente"
    if distance <= 20:
        return "Tibio"
    return "Frío"

Luego, dentro del bucle, calcula la distancia y muestra la pista adicional cuando no acierta:

distance = abs(guess - secret)
print(f"Cercanía: {heat_hint(distance)}")

Mejora 2: no repetir intentos y dar pista “repetido”

Evita que la persona desperdicie intentos repitiendo el mismo número. Guarda los intentos usados en una colección (por ejemplo, un set) y, si se repite, avisa y no descuentes intento.

used = set()

# dentro del bucle, después de leer guess:
if guess in used:
    print("Ya probaste ese número. Elige otro.")
    continue
used.add(guess)

Mejora 3: modo difícil (rango dinámico)

Una pista potente es ir “cerrando” el rango posible según las respuestas. Si el intento fue menor que el secreto, el mínimo posible sube; si fue mayor, el máximo baja. Así el juego se siente más inteligente.

current_min = min_n
current_max = max_n

# dentro del bucle, cuando no acierta:
if guess < secret:
    current_min = max(current_min, guess + 1)
    print(f"Pista: más alto. Nuevo rango: {current_min}-{current_max}")
else:
    current_max = min(current_max, guess - 1)
    print(f"Pista: más bajo. Nuevo rango: {current_min}-{current_max}")

Si aplicas rango dinámico, también conviene validar la entrada contra current_min y current_max en lugar del rango original.

Checklist de pruebas rápidas (para que no se rompa)

  • Entrada no numérica: el juego debe pedir de nuevo sin gastar intento.
  • Número fuera de rango: debe pedir de nuevo sin gastar intento.
  • Acierto en el primer intento: debe terminar inmediatamente.
  • Agotar intentos: debe revelar el secreto.
  • Si activas “no repetir”: repetir un número no debe gastar intento.
  • Si activas rango dinámico: el rango mostrado debe encogerse correctamente y la validación debe respetarlo.

Mini-retos extra (elige 1)

  • Marcador por puntos: empieza con 100 puntos y resta según la distancia en cada fallo (por ejemplo, restar abs(guess-secret) con un mínimo de 1).
  • Dos modos: “Fácil” (más alto/más bajo) y “Difícil” (rango dinámico + pistas de cercanía).
  • Semilla reproducible: permite pasar una semilla (seed) opcional para depurar partidas (si el usuario escribe vacío, usar aleatorio).
  • Récord personal: guarda el menor número de intentos usados en la sesión (solo mientras el programa está abierto).

Ahora responde el ejercicio sobre el contenido:

En un juego de adivinanza con validación de entrada y rango, ¿qué comportamiento es el más adecuado cuando la persona ingresa un valor no numérico o fuera del rango permitido?

¡Tienes razón! Felicitaciones, ahora pasa a la página siguiente.

¡Tú error! Inténtalo de nuevo.

La validación debe evitar penalizar errores de formato o valores fuera del rango: se repite la solicitud hasta obtener un entero en rango, manteniendo intactos los intentos para que el juego sea justo y consistente.

Siguiente capítulo

Lectura y escritura de archivos para persistencia de datos

Arrow Right Icon
Portada de libro electrónico gratuitaPython desde cero con mini-retos: aprende programando (sin teoría eterna)
83%

Python desde cero con mini-retos: aprende programando (sin teoría eterna)

Nuevo curso

12 páginas

Descarga la aplicación para obtener una certificación gratuita y escuchar cursos en segundo plano, incluso con la pantalla apagada.