Pr´
actica 1
Evacuaci´
on del planeta helado Hoth (parte 1)
Esta pr´actica consiste en la realizaci´on de un programa que permita gestionar la evacuaci´on en naves de carga de las bases rebeldes del planeta helado Hoth, ante el inminente ataque del Imperio.
1.
Normas generales
1.1.
Entrega
1. El ´ultimo d´ıa para entregar esta pr´actica es el viernes 16 de marzo, hasta las 23:59. No se admitir´an entregas fuera de plazo.
2. La pr´actica debe tener s´olo un fichero llamado “evacuationOfHoth.cc”.
1.2.
Detecci´
on de plagios/copias
En el Grado en Ingenier´ıa Inform´atica, la Programaci´on es una materia fun-damental, que se aprende programando y haciendo las pr´acticas de las diferentes asignaturas (y otros programas, por supuesto). Si alguien pretende aprobar las asignaturas de programaci´on sin programar (copiando), obviamente tendr´a se-rios problemas para aprobar y para seguir otras asignaturas, y cuando intente trabajar. Concretamente, en Programaci´on 2 es muy dif´ıcil que alguien que no ha hecho las pr´acticas supere el examen de teor´ıa, por lo que copiar una pr´actica es una de las peores decisiones que se puede tomar.
La pr´actica debe ser un trabajo original de la persona que la entrega; en caso de detectarse indicios de copia de una o m´as pr´acticas se tomar´an las medidas disciplinarias correspondientes, informando a la direcci´on de la EPS por si hubiera lugar a otras medidas disciplinarias adicionales.
1.3.
Otras normas
1. La pr´actica se debe entregar exclusivamente a trav´es del servidor de pr´ acti-cas del departamento de Lenguajes y Sistemas Inform´aticos, al que se pue-de accepue-der pue-despue-de la p´agina principal del departamento (www.dlsi.ua.es, “Entrega de pr´acticas”) o directamente en la url https://pracdlsi. dlsi.ua.es.
No se admitir´an entregas por otros medios (correo electr´onico, UA-Cloud, etc.).
El usuario y contrase˜na para entregar pr´acticas es el mismo que se utiliza en el UACloud.
La pr´actica se puede entregar varias veces, pero s´olo se corregir´a la ´
2. El programa debe poder ser compilado sin errores con el compilador de C++ existente en la distribuci´on de Linux de los laboratorios de pr´acticas; si la pr´actica no se puede compilar su calificaci´on ser´a 0. Se recomienda compilar y probar la pr´actica con el autocorrector inmediatamente antes de entregarla.
3. La correcci´on de la pr´actica se har´a de forma autom´atica, por lo que es imprescindible respetar estrictamente los textos y los formatos de salida que se indican en este enunciado.
4. Al principio de todos los ficheros fuente entregados se debe incluir un comentario con el nombre y el NIF (o equivalente) de la persona que entrega la pr´actica, como en el siguiente ejemplo:
// NIF 12345678X GARCIA GARCIA, JUAN MANUEL
5. El c´alculo de la nota de la pr´actica y su influencia en la nota final de la asignatura se detallan en las transparencias de la presentaci´on de la asignatura.
2.
Funcionamiento de la pr´
actica
2.1.
Introducci´
on
La Alianza Rebelde ha concentrado sus tropas en una base secreta en el planeta helado Hoth. El Imperio ha lanzado millones de sondas por todo el espacio para localizar la base rebelde, y una de ellas cae en Hoth. Aunque Luke Skywalker y Han Solo consiguen destruir la sonda imperial, los t´ecnicos de la Alianza Rebelde han averiguado que la sonda consigui´o alertar al Imperio antes de ser destru´ıda, por lo que los inform´aticos de la Alianza deben dise˜nar un programa que permita evacuar en el m´ınimo tiempo posible la base principal y las dem´as bases que hay en el planeta.1
Esta pr´actica debe pedir los datos de las naves y de las bases rebeldes, y permitir establecer un plan de evacuaci´on en el que cada base ser´a asignada a una nave seg´un el algoritmo que se describe m´as adelante.
2.2.
Men´
u
Inicialmente, la pr´actica mostrar´a el siguiente men´u al usuario:
---========== Evacuation ==========---1- List info 2- Add/modify base 3- Add ship 4- Delete base 5- Delete ship 6- Evacuation plan q- Quit
Y pedir´a al usuario que elija una opci´on con el mensaje:
Option:
1Para m´as informaci´on se recomienda el visionado de la pel´ıcula “El imperio contraataca”, varias veces si es necesario.
Si la opci´on elegida no es ninguna de las que aparecen en el men´u (p.ej. un “7”, una “a” o un “;”), se emitir´a el errorERR_UNKNOWN_OPTION, llamando a la funci´onerrorcon ese par´ametro.2
Cuando el usuario del programa elige una opci´on correcta, se debe ejecutar el c´odigo asociado a esa opci´on, y luego se volver´a a mostrar el men´u y a pedir otra opci´on, hasta que el usuario decida salir del programa.
2.3.
Base
En este programa, las bases rebeldes tienen los datos que aparecen en el siguiente registro: struct Base { string name; int people; int equipment; double x,y; };
Donde “name” es el nombre de la base (que no puede repetirse), “people” es la cantidad de personas que hay en la base, “equipment” es la cantidad (en Kg) de material militar y civil que debe evacuarse con cada base, y “x” e “y” son las coordenadas de la base en el planeta.3
A la hora de mostrar por pantalla una base, se mostrar´a con el siguiente formato:4
[(main base) 1251 12345 (12.34,-7.89)]
Entre par´entesis se pondr´a el nombre de la base (“main base”), a continua-ci´on el n´umero de personas (“1251”), la cantidad de material que se debe evacuar (“12345”), y finalmente las coordenadas entre par´entesis (“(12.34,-7.89)”).
Para a˜nadir una nueva base al planeta, en la opci´on Add/modify base, se debe llamar a la funci´on createBase, en la que se debe pedir al usuario el nombre de la base con el siguiente mensaje:
Enter base name:
Si el nombre de la base no existe, se pedir´a a continuaci´on los datos de la base, empezando por el n´umero de personas:
Enter base people:
Si el n´umero de personas es menor o igual que 0, el programa debe emitir el error ERR_WRONG_NUMBER, y salir de la funci´on (o funciones) hasta volver al bucle del men´u principal, sin a˜nadir la base al planeta. Si no se emite dicho error, a continuaci´on se comprobar´a si el n´umero de personas es menor que 50 y en ese caso se emitir´a el errorERR_LOW_PEOPLEy se saldr´a de la funci´on.
Si el n´umero de personas es correcto, se pedir´a la cantidad de material:
2En la web de la asignatura se publicar´a un fichero fuente,evacuationOfHoth.cc, en el que estar´an definidos los errores que debe emitir el programa, y la funci´on de error, adem´as de registros, constantes y funciones que se deben usar para hacer la pr´actica.
3Se utilizan coordenadas en un plano (x,y) en vez de coordenadas de latitud y longitud por simplificar.
4Si no se sigue exactamente este formato, la correcci´on autom´atica fallar´a y la nota de la pr´actica ser´a cercana a la temperatura ambiente del planeta Hoth.
Enter base equipment (Kg):
Como en el caso del n´umero de personas, si la cantidad introducida es me-nor o igual que 0 se emitir´a el error ERR_WRONG_NUMBER y se volver´a al men´u principal.
Si la cantidad es correcta, se pedir´an las coordenadas de la base con los siguientes mensajes:
Enter base coordinate x: Enter base coordinate y:
No es necesario filtrar las coordenadas, cualquier n´umero es v´alido como coordenada. Una vez introducidos todos los datos, se a˜nadir´a la base al final del vector de bases del planeta (v´ease en la secci´on 2.5 la estructura de datos del planeta).
Nota de implementaci´on: cuando el programa intenta leer un n´umero, en-tero o real (con “cin >> numero;”), si se introduce algo que no es un n´umero se produce un fallo no controlable y el programa funcionar´a mal, por lo que en las pruebas que se van a utilizar para corregir la pr´actica nunca se probar´an datos de tipo incorrecto, es decir, si el programa espera un n´umero entero, se intro-ducir´a un n´umero entero, que puede ser incorrecto en alg´un contexto, como-27
en el n´umero de personas, pero que ser´a un n´umero legible con la instrucci´on “cin >> numero;”.
Por otro lado, si al introducir el nombre de la base resulta que la base ya existe en el planeta, se mostrar´an los datos de la base y se preguntar´a al usuario si desea modificarlos:
[(main base) 2500 25670 (0.676,-2.43)] Modify base data (Y/N)?
Si el usuario introduce el car´acter “Y” (en may´uscula), se entender´a que desea modificar la base, y si introduce cualquier otro car´acter (“N” o cualquier otro), se entender´a que no quiere modificarla y se volver´a al men´u principal.
Para modificar la base se debe pedir al usuario el dato a modificar:
Which base data (p/e/c)?
Si se introduce una “p” se pedir´a el n´umero de personas (como se explica m´as arriba), si se introduce “e” se pedir´a la cantidad de material, y si se introduce “c” se pedir´an las coordenadas. Si el n´umero de personas o la cantidad de material son incorrectos, se emitir´a el error correspondiente y no se modificar´a la base. Finalmente, si el car´acter introducido no es ninguno de los posibles “p”, “e” o “c”, se emitir´a el error ERR_UNKNOWN_OPTION y se volver´a al men´u sin modificar la base. Si no hay errores en los datos de entrada, se modificar´a el dato correspondiente de la base del planeta, y se volver´a al men´u.
2.4.
Nave
Las naves de evacuaci´on tendr´an un nombre (name), una cantidad m´axima de personas que pueden llevar (maxpeople), una cantidad m´axima de material
que pueden transportar (maxequipment) y, cuando se ponga en marcha el plan de evacuaci´on, tendr´an un vector de bases que deben evacuar (bases), y una cantidad de personas (curPeople) y una cantidad de material (curEquipment) que deben evacuar. Se representar´an con el siguiente registro:
struct Ship { string name; int maxPeople; int maxEquipment; int curPeople; int curEquipment; vector<Base> bases; };
La informaci´on de la nave se mostrar´a en pantalla como en el siguiente ejemplo:
[(Corellian cruiser Princess Leia) 300{0} 45000{0}]
Donde primero aparece el nombre de la nave entre par´entesis, el n´umero m´aximo de personas, seguido del valor del campo “curPeople” entre llaves, y la cantidad m´axima de material seguida del campo “curEquipment” entre llaves.
Cuando el usuario elige la opci´onAdd shipdel men´u, el programa debe lla-mar a la funci´oncreateShip, que pedir´a el nombre de la nave con este mensaje:
Enter ship name:
Si el nombre de la nave no existe, se pedir´an el n´umero m´aximo de personas y la cantidad m´axima de material con los siguientes mensajes:
Enter ship maximum people: Enter ship maximum equipment:
Como en la introducci´on de datos de la base, si el n´umero m´aximo de per-sonas no es mayor que 0 se debe emitir el error ERR_WRONG_NUMBER y volver al men´u (sin llegar a pedir la cantidad m´axima de material); despu´es, si el n´umero introducido es mayor que 0 pero es menor que 100 se emitir´a el error
ERR_LOW_PEOPLEy se volver´a al men´u. De igual manera, si la cantidad m´axima de material introducida por el usuario no es mayor que 0, se debe emitir el error correspondiente y volver el men´u. Si ambos datos son correctos, se introducir´a la nave al final del vector de naves del planeta, inicializando antes a 0 los campos “curPeople” y “curEquipment”.5
Si el nombre de la nave ya existe, se emitir´a elERR_WRONG_SHIP_NAMEy se volver´a al men´u. Al contrario que con las bases, no es posible modificar los datos de una nave (pero s´ı es posible borrarla y volverla a introducir).
2.5.
Planeta
El planeta tendr´a un nombre,6 un vector de bases y un vector de naves. El siguiente registro contendr´a la informaci´on del planeta:
5Estos campos se utilizar´an para almacenar la cantidad de personas y material ya asignadas a la nave.
6El programa de evacuaci´on se va a dise˜nar para el planeta helado Hoth, pero debe ser utilizable con otros planetas.
struct Planet { string name; vector<Base> bases; vector<Ship> ships; };
La informaci´on que se debe mostrar del planeta cuando el usuario elija la opci´onList infodel men´u es, por ejemplo:
Planet: Hoth Ships:
[(Corellian cruiser Princess Leia) 300{0} 45000{0}] [(Cargo ship Alderaan) 5000{0} 15000{0}]
[(Cargo ship D’Qar) 600{0} 12500{0}] Bases:
[(main base) 2500 25670 (0.676,-2.43)] [(logistic base) 259 8765 (12.22,-7.56)] [(dorm base) 78 3567 (13.05,4.56)]
Lo primero que aparece es el nombre del planeta (“Hoth” en el ejemplo), la informaci´on de las naves, y finalmente la informaci´on de las bases. Cuando se elige la opci´on List info se muestra la informaci´on como en el ejemplo anterior; sin embargo, cuando se muestra la informaci´on del planeta mientras se est´a aplicando el algoritmo para la evacuaci´on, las naves pueden tener una o m´as bases asignadas que deben mostrarse junto con el resto de informaci´on de la nave. M´as adelante, en la secci´on 2.7, se muestra un ejemplo con bases asignadas a una nave.
2.6.
Borrado de bases y naves
Cuando el usuario elija una de las opciones “Delete base” o “Delete ship”, el programa debe comprobar que hay bases o naves, respectivamente, y emitir el error ERR_NO_BASES o ERR_NO_SHIPSsi no hay naves o bases, seg´un corres-ponda, y volver al men´u. Si hay alguna base o nave (siempre seg´un la opci´on elegida), se debe pedir el nombre de la base o nave con el mensaje correspon-diente (el mismo que se usa para la introducci´on de datos), y a continuaci´on debe buscar esa base o nave en el planeta. Si no se encuentra, se debe emitir el error ERR_WRONG_BASE_NAME o ERR_WRONG_SHIP_NAME, y volver al men´u. Si el nombre existe, se debe mostrar la informaci´on de la base o nave, y pedir confirmaci´on, como en este ejemplo:
[(Cargo ship D’Qar) 600{0} 12500{0}] Delete (Y/N)?
Si el usuario confirma el borrado (como cuando se confirma la modificaci´on de datos de una base o nave, es decir, si se introduce una “Y”), se borrar´a la base o nave del planeta y se volver´a al men´u; si no se confirma el borrado, simplemente se volver´a al men´u sin hacer nada.
2.7.
Algoritmo del plan de evacuaci´
on
El algoritmo del plan de evacuaci´on trata de asignar de forma eficiente las bases del planeta a las diferentes naves, utilizando un criterio de proximidad. Cada base ser´a asignada ´unicamente a una nave, y una nave puede tener varias bases asignadas. El algoritmo se puede describir como sigue:
1. De todas las naves disponibles en el planeta, se tomar´a aquella que no tenga bases asignadas y que tenga la m´axima capacidad para transportar personas; si hay dos o m´as naves con esa misma m´axima capacidad, se tomar´a la que aparezca primero en el vector de naves del planeta. Si no hay naves disponibles, el algoritmo terminar´a. Antes de continuar con el algoritmo, el programa debe mostrar la informaci´on de la nave selecciona-da:
Chosen ship: [(Cargo ship Alderaan) 5000{0} 15000{0}]
2. De todas las bases del planeta (no asignadas ya a naves) que puedan ser asignadas a la nave, es decir, aquellas cuyo n´umero de personas sea menor o igual que el espacio que tenga la nave (el espacio para personas es el n´umero m´aximo de personas menos el n´umero de personas asignadas, “curPeople”), y cuya cantidad de material sea menor o igual que el espacio disponible para material en la nave, se tomar´a la base que tenga mayor n´umero de personas y se asignar´a a la nave elegida en el paso anterior; si hay m´as de una base con ese mismo m´aximo n´umero de personas, se tomar´a la primera base del vector de bases del planeta. Para ello la base debe borrarse del vector de bases del planeta e introducirse al final del vector de bases de la nave, actualizando los datos de la nave (los campos “curPeople” y “curEquipment”). Si no hay ninguna base que cumpla las condiciones para entrar en la nave, el algoritmo terminar´a.
3. Una vez elegida la primera base que se asigna a la nave, las siguientes bases se elegir´an siguiendo un criterio de proximidad (siempre que cumplan las condiciones para entrar en la nave), de esta manera:
a) Se elegir´a la siguiente base como aquella que cumpla las condiciones y sea la m´as cercana al centroide o punto medio de las posiciones de las otras bases de la nave. El centroide denpuntos es un punto que se calcula de la siguiente manera (en 2 dimensiones):
Dadosnpuntos con coordenadas (xi, yi),1≤i≤n, el punto centroide (xc, yc) es aquel en el que:
xc= n X i=1 xi n yc= n X i=1 yi n
Obviamente, si la nave s´olo tiene una base, el centroide ser´a la posi-ci´on de dicha base. Para calcular la distancia entre dos puntos (x1, y1) y (x2, y2) se debe usar la distancia eucl´ıdea:7
d=p(x1−x2)2+ (y1−y2)2
b) Cuando no se encuentre ninguna base que pueda ser asignada a la nave (porque no cabe en la nave o porque ya no quedan bases por asignar), se terminar´a de asignar bases a la nave.
7Las funcionespow() ysqrt() de la cabeceracmathse pueden utilizar para calcular la distancia eucl´ıdea.
4. Una vez se han asignado todas las bases posibles a la nave elegida, se mostrar´a la informaci´on del planeta8 como en el siguiente ejemplo y se volver´a al primer paso del algoritmo, donde se elegir´a la siguiente nave.
Planet: Hoth Ships:
[(Corellian cruiser Princess Leia) 300{0} 45000{0}] [(Cargo ship Alderaan) 5000{337} 15000{12332}]
[(logistic base) 259 8765 (12.22,-7.56)] [(dorm base) 78 3567 (13.05,4.56)] [(Cargo ship D’Qar) 600{0} 12500{0}] Bases:
[(main base) 2500 25670 (0.676,-2.43)]
Cuando el algoritmo termine, todas las bases asignadas se devolver´an al vector de bases del planeta. Para ello se recorrer´a el vector de naves y para cada nave se devolver´an las bases asignadas una a una al final del vector de bases del planeta. Cuando se termine de recorrer el vector de bases de una nave, se borrar´a dicho vector. Adem´as, los campos “curPeople” y “curEquipment” de todas las naves se pondr´an a 0.
3.
Implementaci´
on
Para implementar la pr´actica debes tener en cuenta las siguientes observa-ciones:
1. En la web de la asignatura se publicar´an varios ficheros:
evacuationOfHoth.cc : debes basarte en este fichero para realizar tu pr´actica. Tendr´as que a˜nadir m´as funciones y constantes adem´as de las que aparecen en ´el. Este fichero contiene lo siguiente:
a) Tipos definidos que es necesario utilizar, entre los que est´an los registros (struct) para las bases (Base), las naves (Ship) y el planeta (Planet).
b) Una funci´on para emitir mensajes de error, y un tipo enumerado con los errores que se deben emitir.
c) Una funci´on que muestra el men´u del programa.
d) Los prototipos de las funciones que se debe implementar9. e) Una funci´onmainque implementa la gesti´on del men´u.
autocorrectorP2p1.tgz : autocorrector para probar la pr´actica con al-gunas pruebas. La correcci´on autom´atica de la pr´actica se realizar´a con un corrector similar.
2. Las funciones que se debe implementar son (est´an incluidas en el fichero
evacuationOfHoth.cc):
8Siempre que se haya podido asignar al menos una base, es decir, si el algoritmo ha termi-nado antes porque no ha encontrado ninguna base adecuada, no se mostrar´a la informaci´on del planeta.
void printBase(const Base &base); // prints base info void printShip(const Ship &ship); // prints ship info void printPlanet(const Planet &planet); // prints planet info void createBase(Planet &planet); // Creates/modifies a base void createShip(Planet &planet); // Creates a ship
void deleteBase(Planet &planet); void deleteShip(Planet &planet); void evacuationPlan(Planet &planet);
3. En la correcci´on de la pr´actica se introducir´an datos del tipo correcto siempre, aunque con valores que pueden ser incorrectos. Por ejemplo, si se pide el n´umero de personas, se introducir´a siempre un valor entero, que podr´ıa ser-1237o0, pero nunca se introducir´a un valor de otro tipo (car´acter, string o n´umero real).
4. El resto de decisiones en la implementaci´on de la pr´actica quedan a tu criterio, pero ten en cuenta que el c´odigo fuente de la pr´actica ser´a revisado por tu profesor de pr´acticas siguiendo la gu´ıa de estilo publicada en la web de la asignatura, y parte de la nota de la pr´actica depende de dicha revisi´on. Ten en cuenta especialmente estas recomendaciones:10
El sangrado del c´odigo debe ser adecuado, siguiendo uno de los estilos recomendados en la gu´ıa de estilo. Usa 2 o 3 espacios en vez de tabuladores.
Los ficheros fuente deben estar adecuadamente documentados, con comentarios donde se considere necesario, en aquellos puntos del c´ odi-go que sean m´asoscuros (pero sin poner comentarios obvios).11 En Programaci´on 2 no se pueden utilizar variables globales de nin-guna clase, los ´unicos s´ımbolos globales permitidos son las funciones, los tipos definidos por el programador y las constantes. Aunque en cursos anteriores no se permit´ıa el uso debreakycontinuepara sa-lir de bucles, ni poner m´as de unreturnpor funci´on, a partir de este curso se pueden usar esas caracter´ısticas del lenguaje si es necesario. Los nombres de constantes, variables y funciones deben ser adecua-dos, y deben informar sobre su contenido.
Las funciones deben tener un tama˜no adecuado; si una funci´on es demasiado grande (p.ej. no cabe en una pantalla normal), proba-blemente se deber´ıa dividir en dos o m´as funciones. Nunca se debe duplicar (copy/paste) c´odigo.
10Recuerda una cita famosa de John Woods:Always code as if the guy who ends up main-taining your code will be a violent psychopath who knows where you live.
11Muchos programadores consideran que los comentarios no deber´ıan existir, si el c´odigo est´a bien escrito no es necesario poner comentarios.