Hasta ahora vimos los principales conceptos de PSeInt por separado: condicionales, ciclos, vectores, matrices, búsquedas, ordenamiento, funciones y subprocesos. En este proyecto final vamos a combinar gran parte de todo eso en un programa completo y bastante más cercano a un sistema real.
La idea es construir un sistema de reservas de cine que permita visualizar una sala, reservar y cancelar asientos, consultar estadísticas de ocupación y calcular la recaudación. El programa estará dividido en subprocesos para mantener cada responsabilidad separada y reducir la complejidad del algoritmo principal.
¿Qué vamos a practicar?
- Matrices para representar los asientos de la sala.
- Condicionales para validar reservas y cancelaciones.
- Ciclos para recorrer filas y columnas.
- Funciones y subprocesos para dividir el programa.
- Acumuladores y contadores para obtener estadísticas.
- Menús interactivos.
- Validaciones para evitar operaciones incorrectas.
Como en los demás ejemplos del sitio, vamos a trabajar con posiciones que comienzan en 1.
Cómo representaremos la sala
Usaremos una matriz de 5 filas por 6 columnas. El valor 0 indicará que un asiento está libre y el valor 1 que está reservado.
Dimension sala[5,6]
Visualmente queremos mostrar algo parecido a esto:
========================================
CLUB PROGRAMADOR CINE
========================================
Película: Interestelar
Función: 21:30
1 2 3 4 5 6
Fila 1 L L X L L L
Fila 2 X X L L L X
Fila 3 L L L X L L
Fila 4 L X L L L L
Fila 5 L L L L L L
L = Libre
X = Reservado
Funciones principales del sistema
- Inicializar la sala.
- Mostrar los asientos.
- Reservar un asiento.
- Cancelar una reserva.
- Contar asientos ocupados.
- Calcular porcentaje de ocupación.
- Calcular recaudación.
- Detectar la fila con más reservas.
- Mostrar estadísticas.
- Salir del sistema.
Código completo
SubProceso InicializarSala(sala, filas, columnas) Definir f, c Como Entero Para f <- 1 Hasta filas Hacer Para c <- 1 Hasta columnas Hacer sala[f,c] <- 0 FinPara FinPara FinSubProceso SubProceso MostrarSala(sala, filas, columnas) Definir f, c Como Entero Escribir "" Escribir " 1 2 3 4 5 6" Para f <- 1 Hasta filas Hacer Escribir Sin Saltar "Fila ", f, " " Para c <- 1 Hasta columnas Hacer Si sala[f,c] = 0 Entonces Escribir Sin Saltar " L " Sino Escribir Sin Saltar " X " FinSi FinPara Escribir "" FinPara Escribir "" Escribir "L = Libre" Escribir "X = Reservado" FinSubProceso SubProceso ReservarAsiento(sala, filas, columnas) Definir fila, columna Como Entero Escribir "Ingrese fila:" Leer fila Escribir "Ingrese columna:" Leer columna Si fila >= 1 Y fila <= filas Y columna >= 1 Y columna <= columnas Entonces Si sala[fila,columna] = 0 Entonces sala[fila,columna] <- 1 Escribir "Reserva realizada correctamente." Sino Escribir "Ese asiento ya se encuentra reservado." FinSi Sino Escribir "Fila o columna fuera de rango." FinSi FinSubProceso SubProceso CancelarReserva(sala, filas, columnas) Definir fila, columna Como Entero Escribir "Ingrese fila:" Leer fila Escribir "Ingrese columna:" Leer columna Si fila >= 1 Y fila <= filas Y columna >= 1 Y columna <= columnas Entonces Si sala[fila,columna] = 1 Entonces sala[fila,columna] <- 0 Escribir "Reserva cancelada correctamente." Sino Escribir "Ese asiento ya se encuentra libre." FinSi Sino Escribir "Fila o columna fuera de rango." FinSi FinSubProceso SubProceso cantidad <- ContarReservados(sala, filas, columnas) Definir f, c Como Entero cantidad <- 0 Para f <- 1 Hasta filas Hacer Para c <- 1 Hasta columnas Hacer Si sala[f,c] = 1 Entonces cantidad <- cantidad + 1 FinSi FinPara FinPara FinSubProceso SubProceso filaMayor <- FilaMasOcupada(sala, filas, columnas) Definir f, c, cantidadFila, maximo Como Entero maximo <- -1 filaMayor <- 1 Para f <- 1 Hasta filas Hacer cantidadFila <- 0 Para c <- 1 Hasta columnas Hacer Si sala[f,c] = 1 Entonces cantidadFila <- cantidadFila + 1 FinSi FinPara Si cantidadFila > maximo Entonces maximo <- cantidadFila filaMayor <- f FinSi FinPara FinSubProceso SubProceso MostrarEstadisticas(sala, filas, columnas, precioEntrada) Definir reservados, totalAsientos, filaMayor Como Entero Definir porcentaje, recaudacion Como Real reservados <- ContarReservados(sala, filas, columnas) totalAsientos <- filas * columnas porcentaje <- reservados * 100 / totalAsientos recaudacion <- reservados * precioEntrada filaMayor <- FilaMasOcupada(sala, filas, columnas) Escribir "" Escribir "========== ESTADISTICAS ==========" Escribir "Asientos reservados: ", reservados Escribir "Asientos libres: ", totalAsientos - reservados Escribir "Ocupacion: ", porcentaje, "%" Escribir "Recaudacion: $", recaudacion Escribir "Fila con mayor ocupacion: ", filaMayor Escribir "==================================" FinSubProceso Algoritmo SistemaReservasCine Definir sala, opcion Como Entero Definir filas, columnas Como Entero Definir precioEntrada Como Real Dimension sala[5,6] filas <- 5 columnas <- 6 precioEntrada <- 5000 InicializarSala(sala, filas, columnas) Repetir Escribir "" Escribir "========================================" Escribir " CLUB PROGRAMADOR CINE" Escribir "========================================" Escribir "Pelicula: Interestelar" Escribir "Funcion: 21:30" Escribir "" Escribir "1. Ver sala" Escribir "2. Reservar asiento" Escribir "3. Cancelar reserva" Escribir "4. Ver estadisticas" Escribir "5. Salir" Escribir "" Escribir "Seleccione una opcion:" Leer opcion Segun opcion Hacer 1: MostrarSala(sala, filas, columnas) 2: MostrarSala(sala, filas, columnas) ReservarAsiento(sala, filas, columnas) 3: MostrarSala(sala, filas, columnas) CancelarReserva(sala, filas, columnas) 4: MostrarEstadisticas(sala, filas, columnas, precioEntrada) 5: Escribir "Gracias por utilizar Club Programador Cine." De Otro Modo: Escribir "Opcion invalida." FinSegun Hasta Que opcion = 5 FinAlgoritmo
1. Inicialización de la sala
Al comenzar el programa necesitamos asegurarnos de que todos los asientos estén libres. Para eso recorremos toda la matriz y colocamos 0 en cada posición.
Para f <- 1 Hasta filas Hacer Para c <- 1 Hasta columnas Hacer sala[f,c] <- 0 FinPara FinPara
Separar esta tarea en InicializarSala evita que el algoritmo principal tenga que conocer cómo se prepara internamente la matriz.
2. Mostrar la sala
El procedimiento MostrarSala recorre la matriz y transforma los valores internos en una representación más amigable:
0→ asiento libre: L1→ asiento reservado: X
Así conseguimos una interfaz sencilla sin cambiar la forma en la que almacenamos los datos.
3. Reservar un asiento
Antes de modificar la matriz hacemos dos validaciones:
- que la fila y columna estén dentro del rango válido;
- que el asiento se encuentre libre.
Si sala[fila,columna] = 0 Entonces sala[fila,columna] <- 1 Escribir "Reserva realizada correctamente." Sino Escribir "Ese asiento ya se encuentra reservado." FinSi
Esto impide que una misma butaca se reserve dos veces.
4. Cancelar una reserva
La cancelación realiza el proceso inverso. Si el asiento está reservado, vuelve a asignarse el valor 0.
Si sala[fila,columna] = 1 Entonces sala[fila,columna] <- 0 Escribir "Reserva cancelada correctamente." Sino Escribir "Ese asiento ya se encuentra libre." FinSi
5. Contar asientos ocupados
La función ContarReservados recorre toda la sala y cuenta cuántos valores son iguales a 1.
Si sala[f,c] = 1 Entonces cantidad <- cantidad + 1 FinSi
Este único resultado luego nos permite calcular otros datos sin repetir el recorrido.
6. Porcentaje de ocupación
Conociendo la cantidad de reservas y el total de asientos:
porcentaje <- reservados * 100 / totalAsientos
En una sala de 30 lugares, si hay 15 reservas, la ocupación será del 50%.
7. Recaudación
En este ejemplo usamos un precio fijo de entrada:
precioEntrada <- 5000
La recaudación se obtiene multiplicando la cantidad de reservas por el precio:
recaudacion <- reservados * precioEntrada
Podés cambiar ese valor para probar distintos escenarios.
8. Fila con mayor ocupación
Para encontrar la fila con más reservas contamos los asientos ocupados de cada fila y conservamos el mayor valor encontrado.
Este patrón aparece constantemente en programación: recorrer un conjunto, calcular un valor parcial y comparar contra un máximo anterior.
9. Un algoritmo principal mucho más simple
Una de las partes más importantes del proyecto es observar cómo queda el algoritmo principal. En vez de contener cientos de instrucciones mezcladas, se limita a coordinar operaciones:
MostrarSala(sala, filas, columnas) ReservarAsiento(sala, filas, columnas) CancelarReserva(sala, filas, columnas) MostrarEstadisticas(sala, filas, columnas, precioEntrada)
Esta es justamente la utilidad de separar complejidades: cada subproceso resuelve una parte concreta y el programa principal se ocupa del flujo general.
Ideas para ampliar el proyecto
Si querés convertir este ejercicio en un desafío todavía mayor, podés agregar:
- varias películas;
- varios horarios por película;
- diferentes precios según el tipo de entrada;
- nombres de clientes;
- número de reserva;
- asientos VIP;
- descuentos para estudiantes;
- una matriz diferente para cada función;
- recaudación por película;
- ranking de funciones con mayor ocupación;
- impresión de un comprobante al finalizar la reserva.
Qué conceptos reúne este proyecto
Este sistema combina prácticamente todo el recorrido de PSeInt que desarrollamos en Club Programador:
- variables y operadores;
- condicionales;
- ciclos;
- matrices;
- contadores y acumuladores;
- búsqueda de máximos;
- funciones y subprocesos;
- validaciones;
- menús interactivos;
- modularización.
Seguí practicando PSeInt
Si todavía querés practicar algún tema antes de encarar este proyecto completo, podés recorrer nuestro hub de PSeInt, donde reunimos los ejercicios y guías del sitio en un orden recomendado.
También podés repasar los ejercicios con vectores, los ejercicios con matrices y nuestra guía de funciones y subprocesos.
¿Te sirvió este proyecto? ☕
Si este contenido te ayudó a estudiar, practicar o preparar un trabajo, podés apoyar a Club Programador. Tu aporte ayuda a mantener el sitio online y a seguir publicando ejercicios y proyectos gratuitos.
🇦🇷 Apoyar desde Argentina
☕ Invitame un café con Mercado Pago