1. Biblioteca procedimental

En su repositorio personal de control de versiones, cree una biblioteca que resuelva el problema siguiente con los requerimientos planteados por su docente.

Se necesita una biblioteca en C capaz de crear laberintos de dimensiones arbitrarias. Los laberintos generados deben poderse resolver, es decir, que exista un camino desde la entrada a la salida. Su biblioteca también debe ser capaz de resolver laberintos. Es decir, dado un laberinto marcar en él el camino solución. Su biblioteca debe ser capaz de leer y escribir laberintos en archivos de texto y archivos binarios. Ante cualquier error, la biblioteca debe reportarlos a quien la use, en lugar de caerse. Tampoco debe generar accesos inválidos o mal uso de la memoria.

Se necesita un programa de pruebas usando una biblioteca de pruebas unitarias como Google Test. Para cada subrutina pública de la biblioteca, debe haber al menos un caso de prueba que la invoque con entradas correctas, y al menos un caso de prueba que la invoque con entradas mal intencionadas. El programa de pruebas unitarias debe compilarse a un ejecutable. Al ejecutarlo, probará todas las subrutinas públicas de la biblioteca. Si alguna de las pruebas falla, debe reportarlo en el error estándar. En caso de no producir salida, se interpretará como que la biblioteca pasó todas las pruebas unitarias definidas.

Se necesita un comando que permita a sus usuarios crear laberintos, o resolver laberintos existentes. El comando debe leer laberintos de la entrada estándar, de archivos de texto, o de archivos binarios para resolverlos. El comando debe ser capaz de imprimir en la salida estándar, en archivos de texto, o archivos binarios, los laberintos que genera o que resuelve. Proponga a su cliente (su docente), la interfaz de línea de comandos que tendrá su solución.

En mutuo acuerdo con el resto de estudiantes del grupo, decida el formato de los archivos de texto (fáciles de comprender y editar por humanos) y binarios (eficientes para el procesamiento de la máquina) que representarán los laberintos. Cada estudiante debe crear casos de prueba en un repositorio común provisto por su docente, de tal forma, que todos los casos de prueba del grupo pueden ser reutilizados para probar su comando.

2. Programación genérica y polimórfica

Resuelva el problema siguiente con los requerimientos planteados por su docente utilizando los paradigmas de programación genérica (plantillas en C++) y programación orientada a objetos (herencia y polimorfismo).

Se necesita un traductor universal de documentos estructurados, usando una representación intermedia polimórfica, y programación genérica (plantillas) para representar las notaciones de entrada y salida (.txt, .md, .adoc, .xml, .html, .tex, .rtf, .odt, .pdf).

El proyecto se realizará en dos fases. En la primera fase, el equipo (en parejas), elaborará una prueba de concepto. Consiste en diseñar una solución completa al problema planteado usando UML y algoritmos. Implementar parcialmente las clases principales para demostrar la viabilidad de la solución propuesta mediante una prueba de concepto. No se necesita una implementación completa del sistema, sino una demostración parcial de que su solución resuelve el problema con un subconjunto de un par de notaciones.

En la segunda fase se simulará un proceso de desarrollo industrial. Es decir, producir una solución completa al problema planteado, tal como se haría en una empresa de desarrollo de software. Docentes tomarán el rol de usuarios. Asistentes del curso tomarán el rol de líderes técnicos. Estudiantes en parejas, tomarán el rol de desarrolladores.

Al iniciar la segunda etapa, se hará una discusión grupal para definir el diseño final de la solución. Todas las parejas de estudiantes discutirán juntas el diseño final de la solución, aprovechando la experiencia construida en la fase 1. Una vez definido el diseño final, se crearán issues en el repositorio de control de versiones del sistema completo. Los issues se repartirán entre las parejas de estudiantes. Por cada issue, la pareja creará una rama en el sistema de control de versiones. Una vez implementada una solución al issue, la pareja emitirá una solicitud de unirlo a la rama principal (merge request). La persona asistente se encargará de hacer la unión o solicitar correcciones. Se dará crédito a la pareja de desarrollo por cada issue que logre completar y sea unido a la rama principal.

Al final habrá una demostración del producto a las personas clientes (docentes), por parte de todo el equipo de desarrollo (el grupo completo de estudiantes).

2.1. Evaluación

3. Programación multi-paradigma

Para el tercer proyecto se simulará una situación realista muy común. Usted y su colega de desarrollo se integran a un proyecto de software ya iniciado, con un código fuente existente (llamado código heredado). Mediante videos u otros materiales usted recibirá una inducción al código heredado. Se les contrata para mejorar el código existente aplicando mejores paradigmas de programación e incrementar su funcionalidad para satisfacer nuevos requerimientos. El problema se resume a continuación, pero deberán averiguar los nuevos requerimientos con su docente, y proponer mejoras creativas en acuerdo con su cliente (docente).

Una compañía de videojuegos quiere extender un videjuego existente para sacar al mercado una segunda edición de la saga. Se determinó que la primera edición del videojuego no es eficiente, es difícil de mantener, y su código difícilmente pueda cumplir con los requerimientos para la nueva edición. Se encontró que la primera edición del videjuego se creó con programación orientada a objetos. Se les contrata para dos objetivos principales a desarrollar en dos fases:

  1. En la primera fase se les pide hacer una reingeniería (refactoring) del código existente, para aplicar el patrón de diseño entidad-componente-sistema (ECS) y así mejorar la eficiencia del código. Este patrón requiere la aplicación de los paradigmas de programación genérico, basado en arreglos, dirigido por eventos, y deseablemente programación funcional de orden superior. Antes de implementar la nueva arquitectura, se les pide diseñarla usando UML, máquinas de estados finitos, algoritmos, y funciones matemáticas. Luego discutir su diseño con su docente hasta obtener la aprobación, y finalmente implementar la nueva arquitectura. El videojuego debería funcionar exactamente igual con una mejora en el rendimiento.

  2. En la segunda fase se les pide proponer e implementar nuevas funcionalidades al videojuego para lanzar la segunda edición de la saga. Implementar estas nuevas funcionalidades serán más fáciles aprovechando la nueva arquitectura basada en el patrón ECS. Se les pide proponer nuevas funcionalidades creativas y discutirlas con su docente antes de implementarlas.