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.
Continúa en nuestra aplicación.
Podrás escuchar el audiolibro con la pantalla apagada, recibir un certificado gratuito para este curso y además tener acceso a otros 5.000 cursos online gratuitos.
O continúa leyendo más abajo...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).