FPY-1101 · Fundamentos de Programación

Tarea Programada:
Luces del Laboratorio

Lights-Out Puzzle · Python · Consola · Piso 3×3

E
A
E
A
E
A
E
A
E

Descripción del problema

El laboratorio de computación tiene un piso con 9 salas distribuidas en una cuadrícula 3×3. Cada sala tiene una luz que puede estar encendida (E) o apagada (A).

Al llegar al turno de noche, el guardia nota que varias luces quedaron encendidas al azar. Tu programa debe ayudarle a apagarlas todas, pero hay un problema: el panel de control invierte no solo la sala elegida, sino también todas sus salas adyacentes (arriba, abajo, izquierda, derecha).

⚠ El guardia no puede ver el estado del piso después de elegir una sala. Solo se le indica cuántas salas quedaron encendidas y cuántas apagadas.
🎯 El objetivo es llegar a cero salas encendidas, en la menor cantidad de intentos posible.

Ejemplo de jugada

E
A
E
E
E
A
A
E
A

sala elegida = 5

A
E
A
A
A
E
E
A
E

sala 5 + adyacentes (2,4,6,8) invertidas

Numeración del tablero

Distribución de salas

1
2
3
4
5
6
7
8
9

El jugador ingresa un número del 1 al 9

Adyacencias por sala

SalaAdyacentesPosición
12, 4Esquina superior izquierda
21, 3, 5Borde superior centro
32, 6Esquina superior derecha
41, 5, 7Borde izquierdo centro
52, 4, 6, 8Centro (mayor impacto)
63, 5, 9Borde derecho centro
74, 8Esquina inferior izquierda
87, 9, 5Borde inferior centro
96, 8Esquina inferior derecha

Niveles de dificultad

💡 Cada nivel construye sobre el anterior. Guarda una copia funcional antes de avanzar.
NIVEL 1 · BASE

Juego básico funcional

Implementa el juego completo en su forma esencial.

  • Asignar estado inicial aleatorio: E (encendida) o A (apagada) usando random.randint(0,1)
  • Mostrar solo la cantidad de salas encendidas y apagadas al inicio (no el estado del piso)
  • Pedir al jugador que ingrese un número de sala del 1 al 9 en cada turno
  • Validar que la entrada sea un dígito válido entre 1 y 9 usando .isdigit()
  • Al elegir una sala: invertir la sala elegida y todas sus adyacentes (arriba, abajo, izquierda, derecha)
  • Después de cada jugada mostrar cuántas salas quedan encendidas y cuántas apagadas
  • El estado del piso no se muestra en ningún momento durante el juego
  • Contar los intentos realizados
  • Terminar cuando todas las salas estén apagadas y mostrar el total de intentos
NIVEL 2 · INTERMEDIO

Historial de partidas

+1 décima prueba

Agrega estadísticas acumuladas entre partidas.

  • Todo lo del Nivel 1 funcionando correctamente
  • Al terminar cada partida, preguntar si el jugador desea jugar otra vez
  • Mantener durante toda la ejecución: total de partidas jugadas, partidas ganadas, mejor resultado (mínimo intentos) y total de intentos acumulados
  • Al salir mostrar un resumen con todas las estadísticas
  • Calcular y mostrar el promedio de intentos por partida ganada
NIVEL 3 · AVANZADO

Modos de juego y pistas

+0,8 décimas prueba

Agrega configuración antes de cada partida.

  • Todo lo del Nivel 2 funcionando correctamente
  • Menú antes de cada partida: [1] Modo normal (aleatorio) · [2] Modo difícil (todas encendidas) · [3] Modo personalizado (el jugador ingresa E o A por cada sala)
  • Sistema de pistas: si el jugador lleva más de 10 intentos, ofrecerle ver cuántas salas cambiarían al elegir una sala específica (sin revelar el estado del piso)
  • La pista es opcional y no tiene penalización
  • Distinguir en las estadísticas las partidas ganadas con y sin pistas
NIVEL 4 · EXPERTO

Modo demostración

+0,5 décimas prueba

El programa resuelve el puzzle automáticamente.

  • Todo lo del Nivel 3 funcionando correctamente
  • Opción [4] Ver demostración: el programa intenta salas en orden (1 a 9, repetidamente) hasta apagar todas las luces
  • Mostrar cada jugada automática: sala elegida y cuántas quedaron encendidas
  • Si supera 50 intentos sin resolver, detenerse e informarlo
  • El jugador puede comparar su resultado con el de la demostración

Mapa de conceptos requeridos

▸ Nivel 1

ConceptoUso
random.randintEstado inicial aleatorio
.isdigit()Validar número de sala
whileBucle principal del juego
if / elif / elseCondicionales de adyacencia e inversión
ContadoresIntentos y conteo de salas
Operadores lógicosVerificar condición de victoria

▸ Niveles 2–4

ConceptoUso
AcumuladoresPartidas, intentos totales
int / floatConversión y promedios
Menú con whileSelección de modo
Validación de rangoOpciones de menú
Condicionales anidadosLógica de pistas y modos
Operaciones aritméticasPromedios, porcentajes
Solo puedes usar: input, int, float, str, isdigit(), if, else, elif, while, for, random.randint, operadores aritméticos y lógicos. Representa el estado con 9 variables separadas (s1…s9), no con listas.

Ejemplo de ejecución (Nivel 1)

===================================
  LUCES DEL LABORATORIO · Nivel 1  
===================================
  E = encendida   |   A = apagada  
===================================

Estado inicial:
  Salas encendidas (E): 5
  Salas apagadas  (A): 4

Recuerda: no puedes ver el piso.

Ingresa el número de sala (1-9): 5

Jugada 1 — elegiste sala 5
  Salas encendidas (E): 3
  Salas apagadas  (A): 6

Ingresa el número de sala (1-9): hola
  ⚠ Entrada inválida. Ingresa un número entre 1 y 9.

Ingresa el número de sala (1-9): 2

Jugada 2 — elegiste sala 2
  Salas encendidas (E): 1
  Salas apagadas  (A): 8

Ingresa el número de sala (1-9): 1

Jugada 3 — elegiste sala 1
  Salas encendidas (E): 0
  Salas apagadas  (A): 9

===================================
  ¡LABORATORIO EN SILENCIO!        
===================================
  Intentos realizados: 3
===================================
ℹ El ejemplo muestra una partida ideal. Tu programa debe funcionar con cualquier estado inicial aleatorio, incluyendo el caso en que todas las salas ya estén apagadas desde el inicio.

Restricciones técnicas

✗ No está permitido

  • Listas, tuplas, diccionarios o cualquier colección
  • Funciones definidas por el usuario (def)
  • Manejo de excepciones (try / except)
  • Módulos externos (solo random está permitido)
  • Clases u orientación a objetos

✓ Sí está permitido

  • input(), int(), float(), str()
  • .isdigit() para validación
  • if, elif, else, while, for
  • Operadores aritméticos y lógicos
  • random.randint(0, 1)
  • 9 variables simples: s1, s2, …, s9
  • print() con formato

⚡ Sugerencia de estructura

Usa 9 variables s1…s9 con valor "E" (encendida) o "A" (apagada). La inversión y el conteo se hacen con condicionales:

# Invertir sala: E → A o A → E
if s1 == "E":
    s1 = "A"
else:
    s1 = "E"

# Contar salas encendidas (E)
encendidas = 0
if s1 == "E": encendidas = encendidas + 1
if s2 == "E": encendidas = encendidas + 1
# ... (repetir para s3 a s9)

Rúbrica y entrega

CriterioPuntaje
Estado inicial aleatorio correcto (E/A)10 pts
Inversión correcta de sala + adyacentes25 pts
Validación de entrada (rango + tipo)15 pts
Conteo y mensaje de encendidas/apagadas10 pts
Condición de victoria y mensaje final15 pts
Conteo de intentos10 pts
Código ordenado con comentarios15 pts
Total Nivel 1 100 pts

📋 Checklist antes de entregar

  • El programa ejecuta sin errores con Python 3
  • El estado inicial usa E (encendida) y A (apagada)
  • Elegir sala 5 invierte salas 5, 2, 4, 6 y 8
  • Elegir sala 1 invierte salas 1, 2 y 4 únicamente
  • Entradas inválidas muestran error y vuelven a pedir
  • El juego termina correctamente con 0 encendidas
  • El archivo se llama luces_laboratorio.py
  • El código tiene comentarios en las partes clave
⚠ Entregar código con def, listas o librerías no autorizadas descuenta 20 puntos por cada uso.