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
randompara 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.
- Escuche el audio con la pantalla apagada.
- Obtenga un certificado al finalizar.
- ¡Más de 5000 cursos para que explores!
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).