INFORMATIQUE Examen Semestre II

Transcription

INFORMATIQUE Examen Semestre II
EIDGENÖSSISCHE TECHNISCHE HOCHSCHULE – LAUSANNE
POLITECNICO FEDERALE – LOSANNA
SWISS FEDERAL INSTITUTE OF TECHNOLOGY – LAUSANNE
Faculté Informatique et Communication
Cours d’Informatique à la section SV
Sam J.
ÉC O L E P O L Y T E C H N I Q U E
FÉ DÉR A L E D E L A U S A N N E
INFORMATIQUE
Examen Semestre II
Instructions :
–
Vous disposez de une heure quarante cinq minutes pour faire cet examen (10h15
- 12h).
–
Nombre maximum de points: 80 points (+ 35 en bonus).
– Indiquez votre NUMÉRO SCIPER sur chacune des feuilles. Une feuille sans identification ne
sera pas corrigée.
–
Toute documentation est autorisée, hormis les corrigés des anciens tests ;
–
Répondez sur les feuilles qui vous sont distribuées à cet effet (utilisez aussi le
verso des feuilles si nécessaire). Ne répondez pas sur l’énoncé.
–
Vous pouvez répondre aux questions en français ou en anglais.
–
Veillez à ne traiter qu’un exercice par feuille.
–
L’examen compte 3 exercices indépendants.
Vous pouvez commencer par celui que vous souhaitez
– Exercice 1: 48 points (+ 10 en bonus).
– Exercice 2: 32 points.
– Exercice 3: 25 points (bonus).
SU
JE
T
À
LA
PA
GE
SU
IV
AN
TE
3
Exercice 1 : Conception de programme et programmation [48 points]
Vous êtes engagé pour développer le prochain jeu de stratégie de Blizzard Inc.
Le monde de votre jeu sera peuplé d’avatars.
Chaque avatar :
– occupe une position dans le jeu,
– a un âge et un niveau d’énergie.
Il y aura pour commencer trois sortes d’avatars: des magiciens, des orcs et des elfes.
La seule fonctionnalité publiquement accessible pour un avatar sera la méthode simulant son évolution
dans le jeu.
L’algorithme d’évolution prend en paramètre une liste d’avatars (les voisins de l’avatar courant). Il se
formule comme suit:
1. l’avatar avance;
2. si un de ses voisins est suffisamment proche il le combat;
3. en cas de victoire (son adversaire meurt) et il gagne des unités d’énergie;
4. il vieillit (âge incrémenté d’une unité);
Les contraintes suivantes seront respectées:
– un type prédéfini Vec2d sera utilisé pour modéliser la position;
– un avatar meurt lorsque son niveau d’énergie est nul;
– la méthode de combat est spécifique à chaque catégorie et ne peut pas être définie concrètement pour
un avatar quelconque;
– Les orcs disposent d’un bâton et les magiciens d’une baguette;
– un bâton et une baguette seront simplement modélisés au moyen d’entiers (représentant les dommages
que cette arme peut infliger);
– les orcs sont caractérisés par le nombre, point victoire, de points d’énergie qu’ils gagnent en cas de
victoire (propre à chaque orc);
– un orc qui combat fait perdre à son adversaire autant d’énergie que la valeur de son bâton. S’il gagne
(son adversaire meurt), il augmente son niveau d’énergie de point victoire;
– un magicien qui combat fait perdre autant d’énergie que la valeur de sa baguette. S’il gagne (son
adversaire meurt), il augmente son niveau d’énergie de la valeur de sa baguette.
– un elfe qui ”combat” s’envole selon une méthode qui lui est propre et gagne 1 point d’énergie;
– un orc vieillit deux fois plus vite que le reste des avatars.
Le jeu enfin sera modélisé comme :
– un ensemble d’avatars;
– une méthode permettant de faire évoluer chaque avatar (en lui passant la liste de tous les autres);
la liste des avatars sera donnée à la construction du jeu.
suite ☞
QU
ES
TI
ON
S
À
LA
PA
GE
SU
IV
AN
TE
5
Question 1 : Conception [42 points]
On vous demande de :
1. définir deux types Baton et Baguette synonymes du type int;
2. définir la (ou les) classe(s) permettant de représenter le problème ci-dessus en un programme C++
orienté objets (et en utilisant les deux synonymes de type précédents) ;
3. donner les prototypes de ces classes (attributs et méthodes) nécessaires pour effectuer les opérations
demandées, en notant en commentaire les significations des arguments et des valeurs de retour des
méthodes. Vous pouvez, au choix, le faire sous forme de schéma ou sous forme de code C++, mais
vous devez impérativement indiquer toutes les dépendances, attributs, méthodes et droits d’accès.
Les contraintes à respecter sont :
1. vous n’utiliserez pas de fonctions globales (mais uniquement des méthodes de classes) ;
2. votre conception ne doit pas nécessiter de dupliquer du code ;
3. elle ne doit surtout pas nécessiter de faire des tests sur le type des objets pour réaliser les traitements
souhaités ;
4. vous ne prévoirez comme getters/setters que ceux utiles aux traitements souhaités ;
5. vous porterez une attention particulière à la nature des méthodes (normales, const, virtuelles ou
virtuelles pures), ainsi qu’aux droits d’accès aux attributs et aux méthodes.
On ne vous demande pas d’écrire de programme complet, ni le corps des méthodes, mais
uniquement leurs prototypes. Les prototypes des constructeurs devront figurer dans votre description.
Question 2 : Programmation [6 points]
Donnez le code :
– des méthodes de combat de la hiérarchie.
Question 3 : Conception [10 points, bonus]
Supposons maintenant qu’un avatar ne combatte un autre avatar que si ce dernier est dangereux pour
lui et que :
– un orc est dangereux pour tous les avatars sauf les orcs;
– un magicien est dangereux pour les orcs;
– un elfe n’est dangereux pour personne.
Expliquez comment vous procéderiez pour implémenter la méthode
bool estDangereux(Avatar* other) const permettant à un avatar de tester si other est dangereux
pour lui, sans faire de test de type.
Vous donnerez le code C++ nécessaire. Si le principe se répète dans des classes particulières vous ne
donnerez le code que pour une seule classe en guise d’exemple.
suite ☞
6
Exercice 2 : Questions sur les concepts [32 points]
Répondez clairement et succinctement aux questions suivantes :
① [3 points] Considérez le code ci-dessous :
1. class A {
2. public:
3.
A() {}
4.
A(int x = 3) : y(x) {}
5.
protected:
6.
int y;
7. };
Lesquelles des options ci-dessous sont correctes ?
(a) Le code compile et, à la ligne 9, le constructeur
A() est appelé.
(b) Le code compile et, à la ligne 9, le constructeur
A(int) est appelé.
(c) Le code compile, mais produit un erreur si on
l’exécute.
8. int main() {
9.
A a1(4);
10. return 0;
}
(d) Le code ne compile pas.
Justifiez brièvement votre réponse.
② [6 points] Soit le programme suivant (on suppose que toutes les inclusions nécessaires sont faites) :
class M {
public:
virtual void display() const = 0;
};
class N : public M {
public:
N(size_t n):mySet(n)
{
for (auto& elt : mySet)
elt = new int(3);
}
~N() {
cout << "faire le vide" << endl;
for (auto& elt : mySet){
delete elt;
}
}
protected:
vector<int*> mySet;
}; // Fin de la classe N
int main(){
void display() const {
for (auto elt : mySet){
cout << *elt << endl;
}
M* m(new N(8));
m->display();
delete m;
}
return 0;
// Suite du code
à droite -->
}
(a) Indiquez ce qu’il affiche.
(b) Il comporte un problème. Lequel ?
(c) Indiquez comment le rectifier.
(d) Quel problème se pose si l’on remplace le constructeur de la classe N par ce code :
N(size_t n):mySet(n, new int(3))
suite ☞
7
③ [3 points] Le programme suivant signale une erreur à la compilation :
1.
2.
3.
class A {
public:
A(int unA):a(unA){}
4.
5.
6.
protected:
int a;
};
7.
8.
9.
class B : public A {
public:
B(int unA, int unB) :a(unA), b(unB) {}
10. protected:
11.
int b;
12. };
(a) Quelle est cette erreur ? (indiquez la nature de l’erreur et la ligne où elle se manifeste).
(b) Comment la corriger ?
④ [5 points] Soit le programme suivant (on suppose que toutes les inclusions nécessaires sont faites) :
1. class A {
2. public:
3.
virtual void f1() const = 0;
4.
virtual void f2() const = 0;
5. };
6.
7.
8.
class B : public A {
public:
virtual void f1(){cout << "B" << endl;}
9.
virtual void f2() const {f1();}
10. };
11. int main() {
12.
13.
B unB;
unB.f1();
14.
return 0;
15. }
(a) Ce programme produit deux erreurs à la compilation : indiquez la nature de ces erreurs et les
lignes où elles se manifestent.
(b) Comment les corriger ?
suite ☞
8
⑤ [5 points] Soit le programme suivant (on suppose que toutes les inclusions nécessaires sont faites) :
0. class Avatar {
1.
2.
public:
virtual void display() const {}
3.
//pleins d’autres attributs et méthodes
4.};
5. class Orc : public Avatar {
6.
// plein d’autres choses ...
7.
public:
8.
void display() const
9.
{cout << "Je suis un Orc" << endl;}
10.};
12.class Magicien : public Avatar {
13.
//...
14.
public:
15.
void display() const
16.
{cout << "Je suis un Magicien" << endl;}
17.};
18.int main() {
19. list<Avatar*> personnages = {new Orc(), new Magicien()};
20. for (auto p : personnages) p->display();
21. // instruction de gestion de la mémoire ici, sans affichage
22. return 0;
23.}
(a) Qu’affiche-t-il ?
(b) Qu’affiche-t-il si la ligne 2 est remplacée par :
virtual void display() const = 0;
(c) Quels sont les avantages à procéder à ce changement ?
suite ☞
9
⑥ [5 points] Le programme suivant signale une erreur à la compilation :
1.
2.
3.
class Obstacle {
public: virtual void draw() const = 0;
};
4.
5.
6.
class Animal : public Obstacle {
public: void draw() const {...}
};
7.
8.
9.
class Food : public Obstacle {
public: void draw() const {...}
};
10. class Prey : public Food, public Animal
11. {};
12. int main() {
13.
Prey prey;
14.
prey.draw();
15.
return 0;
16. }
(a) Quelle est cette erreur ? (indiquez la nature de l’erreur et la ligne où elle se manifeste).
(b) Comment la corriger ? (s’il existe plusieurs façons de le faire indiquez-les en précisant laquelle
vous semble la meilleure)
⑦ [5 points] Soit le programme suivant (on suppose que toutes les inclusions nécessaires sont faites) :
1.
2.
3.
4.
5.
int main() {
ofstream f_out("sortie.txt");
ifstream f_in("entree.txt");
unsigned int numero;
f_in >> numero;
6.
7.
string adresse;
getline(f_in, adresse);
8.
f_out << numero << " " << adresse << endl;
9.
10.
f_out.close();
f_in.close();
11.
return 0;
12. }
(a) Quel est le contenu du fichier sortie.txt si le fichier entree.txt contient les lignes suivantes:
12
Chemin du Lys
(b) Quelles critiques pouvez vous formuler sur le programme ? Indiquez comment vous proposez
de l’améliorer (le cas échéant, indiquez quelles portions de code vous proposez d’ajouter et à
quels endroits)
10
Exercice 3 : Déroulement de programme [25 points] (bonus)
Le programme suivant compile et s’exécute sans erreurs. Qu’affiche-t-il ?
Justifiez votre réponse en expliquant les points importants (on ne vous demande pas ici de paraphraser
le code, mais bien de montrer que vous avez compris !).
#include <iostream>
#include <vector>
using namespace std;
class A {
public:
A(int x = 2, int y = 3) : a(x), b(y) {}
virtual int m1() { return 2*a; }
int m2() { return 3*b; }
protected:
int a;
int b;
};
class B : virtual public A {
public:
B(int x = 3, int y = 4) : A(x,y) {}
int m1() { return 3*a; }
virtual int m2() { return 7*b; }
};
class C : virtual public A {
public:
C(int x = 2, int y = 3, int z = 5)
: A(x,y), c(z) {}
int m1() { return 10*a; }
int m2() { return 3*b+c; }
private:
int c;
};
class D : public B, public C {
public:
int m1() { return B::m1(); }
int m2() { return C::m2(); }
};
int main() {
unsigned int k(0);
A a(1,2);
A* pa(&a);
cout << ++k << ") "
cout << ++k << ") "
cout << ++k << ") "
cout << ++k << ") "
B b;
pa = &b;
cout << ++k << ") "
cout << ++k << ") "
cout << ++k << ") "
cout << ++k << ") "
C c;
pa = &c;
cout << ++k << ") "
cout << ++k << ") "
cout << ++k << ") "
cout << ++k << ") "
D d;
pa = &d;
B* pb(&d);
cout << ++k << ") "
cout << ++k << ") "
cout << ++k << ") "
cout << ++k << ") "
cout << ++k << ") "
cout << ++k << ") "
a = d;
pa = &a;
cout << ++k << ") "
cout << ++k << ") "
cout << ++k << ") "
cout << ++k << ") "
return 0;
}
<<
<<
<<
<<
a.m1()
a.m2()
pa->m1()
pa->m2()
<<
<<
<<
<<
endl;
endl;
endl;
endl;
<<
<<
<<
<<
b.m1()
b.m2()
pa->m1()
pa->m2()
<<
<<
<<
<<
endl;
endl;
endl;
endl;
<<
<<
<<
<<
c.m1()
c.m2()
pa->m1()
pa->m2()
<<
<<
<<
<<
endl;
endl;
endl;
endl;
<<
<<
<<
<<
<<
<<
d.m1()
d.m2()
pa->m1()
pa->m2()
pb->m1()
pb->m2()
<<
<<
<<
<<
<<
<<
endl;
endl;
endl;
endl;
endl;
endl;
<<
<<
<<
<<
a.m1()
a.m2()
pa->m1()
pa->m2()
<<
<<
<<
<<
endl;
endl;
endl;
endl;