Programaci´ on 2 Curso 2015/2016 Pr´

Anuncio
Programación 2
Curso 2015/2016
Práctica 1
Imperial Commander (parte 1)
Esta práctica consiste en la realización de un programa que permita gestionar
la flota de cazas imperiales que lleva un destructor imperial en sus bodegas.
1.
1.1.
Normas generales
Entrega
1. El último dı́a para entregar esta práctica es el viernes 26 de febrero,
hasta las 23:59. No se admitirán entregas fuera de plazo.
2. La práctica debe tener sólo un fichero llamado “imperialCommander.cc”.
1.2.
Detección de plagios/copias
En el Grado en Ingenierı́a Informática, la Programación es una materia fundamental, que se aprende programando y haciendo las prácticas de las diferentes
asignaturas (y otros programas, por supuesto). Si alguien pretende aprobar las
asignaturas de programación sin programar (copiando), obviamente tendrá serios problemas en otras asignaturas o cuando intente trabajar. Concretamente,
en Programación 2 es muy difı́cil que alguien que no ha hecho las prácticas supere el examen de teorı́a, por lo que copiar una práctica es una de las peores
decisiones que se puede tomar.
La práctica debe ser un trabajo original de la persona que la entrega; en
caso de detectarse indicios de copia de una o más prácticas se suspenderá la
asignatura a todos los alumnos implicados (tanto al que copia como al que
se deja copiar), y se enviará un informe a la dirección de la EPS, para
que se tomen las medidas disciplinarias oportunas.
1.3.
Otras normas
1. La práctica se debe entregar exclusivamente a través del servidor de prácticas del departamento de Lenguajes y Sistemas Informáticos, al que se puede acceder desde la página principal del departamento ( www.dlsi.ua.es,
“Entrega de prácticas”) o directamente en la url http://pracdlsi.dlsi.
ua.es.
No se admitirán entregas por otros medios (correo electrónico, Campus Virtual, etc.).
El usuario y contraseña para entregar prácticas es el mismo que se
utiliza en el Campus Virtual.
La práctica se puede entregar varias veces, pero sólo se corregirá la
última entrega (las anteriores entregas no se borran).
2
INTRODUCCIÓN
2
2. El programa debe poder ser compilado sin errores con el compilador de
C++ existente en la distribución de Linux de los laboratorios de prácticas;
si la práctica no se puede compilar su calificación será 0. Se recomienda
compilar y probar la práctica con el autocorrector inmediatamente antes
de entregarla.
3. La corrección de la práctica se hará de forma automática, 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áctica, como en el siguiente ejemplo:
// NIF
12345678X
GARCIA GARCIA, JUAN MANUEL
5. El cálculo de la nota de la práctica y su influencia en la nota final de
la asignatura se detallan en las transparencias de la presentación de la
asignatura.
2.
Introducción
Esta práctica consiste en realizar un programa para ayudar al comandante
de un destructor imperial a gestionar la flota de cazas imperiales del destructor
en el transcurso de una batalla con una nave rebelde de similares caracterı́sticas.
Podrá añadir más cazas, reparar y mejorar las caracterı́sticas de los cazas,
y lanzar un caza a luchar contra un caza rebelde. En posteriores prácticas se
añadirán más funcionalidades a este programa.
2.1.
Caracterı́sticas de los cazas espaciales
Tanto los cazas imperiales como los rebeldes tienen las siguientes caracterı́sticas:
velocidad (velocity) : la velocidad máxima del caza
ataque (attack )
: poder de ataque sobre otras naves
escudo (shield )
: poder defensivo de los campos deflectores
coste (cost)
: coste en créditos del caza
Los cazas imperiales, junto con los valores de sus caracterı́sticas son:
Tipo
TIE-Fighter
TIE-Bomber
TIE-Interceptor
TIE-Advanced
Abreviatura
tf
tb
ti
ta
Velocity
150
80
180
160
Attack
75
150
65
80
Shield
30
45
30
90
Cost
45
75
55
95
Los cazas rebeldes son:
Tipo
X-Wing
Y-Wing
A-Wing
B-Wing
Abreviatura
xw
yw
aw
bw
Velocity
175
90
200
120
Attack
90
150
60
200
Shield
75
90
50
90
Cost
65
90
45
100
En el destructor imperial solamente se puede almacenar 30 cazas, y el co-
3
FUNCIONAMIENTO DEL PROGRAMA
3
mandante dispone inicialmente de 2000 créditos en la caja fuerte del destructor
para comprar cazas, o bien para reparar y mejorar los cazas disponibles. El programa debe almacenar también el número de victorias y derrotas del destructor
en los combates que se produzcan. Cuando un caza imperial destruya al caza
rebelde oponente, el Emperador recompensará automáticamente al comandante
con el coste del caza rebelde destruido, que incrementará la cantidad de créditos
disponible en la caja fuerte del destructor. La Alianza Rebelde recompensará de
la misma manera al comandante de la nave rebelde enemiga.
3.
Funcionamiento del programa
Inicialmente, el programa debe crear e inicializar dos naves, el destructor
imperial que gestionará el usuario, y una nave rebelde que gestionará el propio
programa. En la sección de implementación se describe con más detalle los datos
de cada nave:
ambas naves partirán de la misma cantidad de créditos inicial, 2000 créditos, para comprar su dotación inicial de cazas, comprar más cazas, y para
mejorarlos.
cada una tendrá diferente capacidad según sea una nave imperial o una
nave rebelde.
Cada nave tendrá inicialmente una dotación de cazas que deben añadirse
(en el orden que se indica) al crear la nave. El destructor imperial tendrá 10
TIE-Fighters, 5 TIE-Bombers, 5 TIE-Interceptors y 5 TIE-Advanced. La nave
rebelde tendrá 10 X-Wing, 5 Y-Wing, 8 A-Wing y 5 B-Wing (véase la sección
de implementación para más detalles acerca de cómo inicializar la dotación de
cazas).
Una vez creadas las naves e inicializadas (incluyendo las dotaciones de cazas
iniciales), el programa debe mostrar el siguiente menú:
1- List ship info
2- Add fighters
3- Repair/improve fighter
4- Launch fighter
5- List enemy info
q- Quit
Option:
La opción será siempre un único carácter, no es necesario comprobarlo (aunque irá seguido de un carácter de fin de lı́nea). Si el usuario introduce una opción incorrecta, el programa debe mostrar el mensaje de error UNKNOWN_OPTION
(véase la sección de implementación para más detalles sobre los mensajes de
error). Si el usuario elige la opción Quit, el programa terminará sin emitir ningún
mensaje.
Después de ejecutar alguna de las opciones (que pueden ir bien o generar
algún error), el programa volverá a mostrar el menú.
3.1.
Descripción de las opciones
List ship info/List enemy info : en ambas opciones se debe mostrar la información de la nave correspondiente por pantalla (utilizando exactamente
3
FUNCIONAMIENTO DEL PROGRAMA
4
la misma función). Por ejemplo, al comenzar el programa la información
del destructor imperial debe ser:1
Ship info: max. capacity=30, side=IMPERIAL, credits=425, wins=0, losses=0
[1] TIE-Fighter (v=150, a=75, s=30, c=45)
[2] TIE-Fighter (v=150, a=75, s=30, c=45)
...
[25] TIE-Advanced (v=160, a=80, s=90, c=95)
En el caso del jugador rebelde, la cadena a mostrar después de “side=”
será “REBEL”.
Add fighters : en esta opción se añadirán uno o más cazas del mismo tipo al
destructor imperial. Para ello, se debe pedir el tipo de caza, mostrando el
siguiente mensaje:
Enter fighter type (tf/tb/ti/ta):
A continuación, si el tipo introducido por el usuario (una cadena) coincide
con la abreviatura de alguno de los cazas definidos en la tabla de datos
de cazas y es un caza imperial (en otro caso se mostrará por pantalla el
mensaje de error WRONG_FIGHTER_TYPE y saldrá de la función, volviendo
al menú), entonces se pedirá el número de cazas mostrando el siguiente
mensaje:
Number of fighters:
Si el coste de los nuevos cazas es mayor que el número de créditos disponible en la caja fuerte de la nave, se mostrará el mensaje de error NO_FUNDS.
Si los nuevos cazas caben en la nave (en otro caso se mostrará el error
CAPACITY_EXCEEDED), se añadirán al final del vector de cazas de la nave,
y se descontará su coste de los créditos de la caja fuerte.
Repair/improve fighters : esta opción permite al comandante mejorar o reparar alguna de las caracterı́sticas de un caza. Para ello, se pedirá el número de caza a reparar o mejorar con el siguiente mensaje:
Select fighter number:
Si el número de caza es incorrecto se mostrará el error WRONG_NUMBER; si es
correcto, se pedirá el aspecto a mejorar o reparar con el siguiente mensaje:
What to improve (v/a/s)?
Se leerá la opción elegida (un carácter, seguido de un carácter de retorno de carro), y, si es correcta (en caso contrario se emitirá el error
UNKNOWN_OPTION y se saldrá de la función, volviendo a continuación al
menú), se pedirá la cantidad en que se quiere aumentar ese aspecto mediante el mensaje:
1 Por brevedad, solamente se muestran los 2 primeros cazas y el último, pero la práctica
debe mostrar todos los cazas.
3
FUNCIONAMIENTO DEL PROGRAMA
5
Amount:
Una vez leı́da la cantidad c (se puede asumir que c será mayor o igual que
cero, no es necesario comprobarlo), se calculará el coste de dicha mejora,
que será:
velocidad
ataque
escudo
2*c (2 créditos por unidad)
3*c (3 créditos por unidad)
(c+1)/2 (1 crédito por 2 unidades, redondeo al alza)
El coste de la mejora del escudo se redondea al alza porque en caso contrario las cantidades impares costarı́an lo mismo que la cantidad par inmediatamente inferior. En la implementación, la división debe ser entera
(si los dos operandos son enteros, la división será entera).
Si el coste no es mayor que los créditos disponibles en la caja fuerte de la
nave (en otro caso se mostrará el error NO_FUNDS y se saldrá de la función),
se mostrará el siguiente mensaje, y se pedirá confirmación:
That will cost you <cost> credits. Confirm? (y/n)
donde <cost> es el coste de la mejora. Si el usuario introduce el carácter
“y”, se realizará la mejora en el caza, se incrementará el coste del caza, se
restará el coste de los créditos de la caja fuerte, y se mostrará un mensaje
como el del siguiente ejemplo (en el que se ha aumentado 20 unidades la
velocidad de un TIE-Fighter):
Fighter improved: TIE-Fighter (v=170, a=75, s=30, c=85)
Si se introduce cualquier otro carácter (incluso “Y” o “s”) en la pregunta
de confirmación, se entenderá que no se ha confirmado y por tanto no se
realizará la mejora, y se saldrá de la función y se volverá al menú principal
sin mostrar ningún mensaje.
Launch fighter : en esta opción el comandante de la nave elige un caza de los
que tiene disponibles en la nave y lo envı́a a combatir con otro caza de la
nave enemiga.
Antes de empezar el combate, se debe comprobar que ambas naves, la
imperial y la rebelde, tienen al menos un caza. Si no es ası́, se emitirá el
error NO_FIGHTERS y se volverá al menú.
Una vez hecha esta comprobación, lo primero que se debe hacer es seleccionar el caza, mostrando el siguiente mensaje:
Select fighter number:
Si el número del caza es correcto (en caso contrario se emitirá el error
WRONG_NUMBER y se saldrá de la función, volviendo al menú), se almacenará en una variable el caza elegido y se eliminará del vector de cazas.
A continuación, se elegirá aleatoriamente un caza enemigo (generando un
número al azar entre 0 y el número de cazas enemigos menos 1), y se eliminará también del vector de cazas de la nave enemiga, y comenzará la lucha
3
FUNCIONAMIENTO DEL PROGRAMA
6
entre los dos cazas. Antes de comenzar el combate se debe mostrar los dos
cazas, con el mismo formato que en las opciones de 1 y 5 del menú (pero
sin el número de caza), y al terminar también.
El combate entre los dos cazas (el primero imperial y el segundo rebelde)
se simula de la siguiente manera:
1. Se genera un número aleatorio n entre 0 y 99, 0 ≤ n ≤ 99
2. Si n es menor que 5 o mayor que 95, el combate termina (se simula
que han intervenido otros cazas, o se ha alcanzado un campo de
asteroides, o que alguno de los cazas se retira).
3. Se calcula qué caza acierta en su ataque al caza contrario, obteniendo
un umbral u, que se calcula de la siguiente manera:
u=
100v1
v1 + v2
donde v1 es la velocidad del primer caza, y v2 la del segundo. Si n es
menor o igual que el umbral u, se supone que el caza que ha acertado
es el primero (el caza imperial), en caso contrario el caza que ha
acertado es el segundo.
4. Se calcula el daño d ocasionado al caza contrario, que se restará directamente de su escudo. La fórmula para calcular el daño es:
d=
(na1 )/f
((100 − n)a2 )/f
si n ≤ u
si n > u
donde a1 es el ataque del primer caza, y a2 el del segundo. El valor
f es una constante de valor 300.
5. Si el escudo de alguno de los cazas es 0 o negativo, el combate termina,
y se considera que dicho caza ha sido destruido. Solamente puede
resultar destruido uno de los dos cazas, no pueden destruirse los dos
en el mismo combate.
6. Si ambos cazas tienen todavı́a un valor positivo en su escudo, el
combate continua volviendo al paso 1.
Por ejemplo, si al principio del programa se lanza el primer caza imperial
de la nave (un TIE Fighter), la salida por pantalla deberı́a ser:
-- begin fight
TIE-Fighter (v=150, a=75, s=30, c=45)
B-Wing (v=120, a=200, s=90, c=100)
-TIE-Fighter (v=150, a=75, s=-4, c=45)
B-Wing (v=120, a=200, s=81, c=100)
-- end fight
Cuando termine el combate, se actualizarán los datos de créditos (se sumará a cada nave el coste de los cazas enemigos destruidos), victorias y
derrotas de las dos naves, y se devolverán los cazas supervivientes (puede ser uno o los dos) a su nave, añadiéndose al final del vector de cazas
correspondiente.
4
IMPLEMENTACIÓN
4.
7
Implementación
Para implementar la práctica debes tener en cuenta las siguientes observaciones:
1. En la web de la asignatura se publicarán varios ficheros:
imperialCommander.cc : debes basarte en este fichero para realizar tu
práctica. Puedes añadir más funciones y constantes si lo consideras
necesario. Este fichero contiene lo siguiente:
a) Tipos definidos que es necesario utilizar, entre los que están los
registros (struct) para los cazas (Fighter) y la nave (Ship).
b) La tabla de datos de cazas (4 imperiales y 4 rebeldes), y las
abreviaturas de los tipos de caza (que se utilizarán en la opción
Add fighter).
c) Constantes de las naves como la capacidad de cada nave, y las
dotaciones iniciales de cazas; en estos vectores se indica cuántos
cazas de la tabla tiene cada nave.
d ) Constantes y una función para emitir mensajes de error.
e) Una función para generar números aleatorios (que no debes modificar).
f ) Los prototipos de las funciones que se debe implementar2 .
g) Una función main que debes completar.
autocoP2p1.tgz : autocorrector para probar la práctica con algunas pruebas. La corrección automática de la práctica se realizará con un corrector similar.
2. La generación de números pseudo-aleatorios se realiza usando las funciones estándar de C/C++ rand (para generar números) y srand (para
establecer la semilla). Aunque se ha probado en varias versiones de Linux,
es posible que en otros sistemas (especialmente en Windows) no funcione exactamente de la misma manera, es decir, no se genere exactamente
la misma secuencia de números aleatorios, por lo que los autocorrectores
podrı́an fallar. Por tanto, es recomendable desarrollar la práctica en Linux
(preferiblemente en la distribución usada en los laboratorios), y se debe
probar con el autocorrector en las máquinas de los laboratorios antes de
entregarla.
3. Las funciones que se debe implementar son (están incluidas en el fichero
imperialCommander.cc):
void initializeShip(Ship &ship,bool side);
// Inicializa los datos de la nave
void listFighter(const Fighter &f);
// Muestra los datos de un caza
void listFighters(const vector<Fighter> &vf);
2 Seguramente necesitarás implementar alguna función adicional para que el código sea más
sencillo y legible.
4
IMPLEMENTACIÓN
8
// Muestra un vector de cazas
void listShip(const Ship &ship);
// Muestra los datos de una nave y de sus cazas
bool addFighter(Ship &ship);
// A~
nade uno o más cazas a la nave. Devuelve true si los ha a~
nadido
bool improveFighter(Ship &ship);
// Mejora o repara un caza. Devuelve \texttt{true} si lo ha mejorado o reparado
int fight(Fighter &fg1,Fighter &fg2);
// Simula un combate entre dos cazas. Devuelve -1 si gana el primero, 1 si gana el
// segundo, 0 si hay empate
void launchFighter(Ship &imperial,Ship &rebel);
// Simula el combate entre un caza imperial y uno rebelde
4. En la corrección de la práctica se introducirán datos del tipo correcto
siempre, aunque con valores que pueden ser incorrectos. Por ejemplo, si se
pide el número de cazas, se introducirá siempre un valor entero, que podrı́a
ser -1237 o 0, pero nunca se introducirá un valor de otro tipo (carácter,
string o número real).
5. El resto de decisiones en la implementación de la práctica quedan a tu
criterio, pero ten en cuenta que el código fuente de la práctica será revisado
por tu profesor de prácticas siguiendo la guı́a de estilo publicada en la
web de la asignatura, y parte de la nota de la práctica depende de dicha
revisión. Ten en cuenta especialmente estas recomendaciones:3
El sangrado del código 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ódigo que sean más oscuros (pero sin poner comentarios obvios).4
En Programación 2 no se pueden utilizar variables globales de ninguna clase, los únicos sı́mbolos globales permitidos son las funciones,
los tipos definidos por el programador y las constantes. Tampoco se
permite usar break para salir de bucles, ni usar return para salir de
funciones en mitad del código.5
Los nombres de constantes, variables y funciones deben ser adecuados, y deben informar sobre su contenido.
Las funciones deben tener un tamaño adecuado; si una función es
demasiado grande (p.ej. no cabe en una pantalla normal), probablemente se deberı́a dividir en dos o más funciones. Nunca se debe
duplicar (copy/paste) código.
3 Recuerda una cita famosa de John Woods: Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.
4 Muchos programadores consideran que los comentarios no deberı́an existir, si el código
está bien escrito no es necesario poner comentarios.
5 El objetivo de estas normas es afianzar el aprendizaje, en asignaturas de cursos superiores
sı́ se permite usar estas caracterı́sticas del lenguaje.
Descargar