Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

exercices

Télécharger au format pdf ou txt
Télécharger au format pdf ou txt
Vous êtes sur la page 1sur 19

10/30/2016 Héritage et base du polymorphisme

Exercice 2: Que de véhicules (Héritage, Niveau 1)


2.1 La classe Vehicule

Définissez une classe Vehicule qui a pour attributs des informations valables pour tout type de
véhicule : sa marque , sa date d'achat, son prix d'achat et son prix courant.

Solution :

class Vehicule {

private String marque;


private int dateAchat;
private double prixAchat;
private double prixCourant;

Ces attributs sont private pour assurer une bonne encapsulation.

Définissez un constructeur prenant en paramètres la marque, la date d'achat et le prix d'achat.

Une solution possible: :

public Vehicule(String marque, int date, double prix) {


this.marque = marque;
dateAchat = date;
prixAchat = prix;
prixCourant = prix;
}

Définissez une méthode publique affiche() qui affiche la valeur des attributs.

public void affiche() {


System.out.print("marque : " + marque +
", date d'achat : " + dateAchat +
", prix actuel : " + prixCourant);
System.out.println();
}

2.2 La classe Voiture et la classe Avion

Définissez deux classes Voiture et Avion, héritant de la classe Vehicule et ayant les attributs
supplémentaires suivants :

Commençons par la classe Voiture. Elle doit hériter de la classe Vehicule :

class Voiture extends Vehicule {

On ajoute ensuite les champs spécifiques à la classe Voiture :

private double cylindree;


private int nbPortes;
private double puissance;
private double kilometrage;

Pour la classe Avion, on procède de même :

http://icwww.epfl.ch/~sam/ipo/series/serie07/solution_print.html 1/19
10/30/2016 Héritage et base du polymorphisme
class Avion extends Vehicule {

private String moteur;


private int heuresVol;

Définissez maintenant un constructeur pour Voiture, ainsi qu'une méthode affichant la valeur des
attributs.

public Voiture(String marque, int date, double prix,


double cylindree, int portes, double cv, double km) {
super(marque, date, prix);
this.cylindree = cylindree;
nbPortes = portes;
puissance = cv;
kilometrage = km;
}

public void affiche() {


System.out.println(" ­­­­ Voiture ­­­­");
super.affiche();
System.out.println(cylindree + " litres, "
+ nbPortes + " portes, "
+ puissance + " CV, "
+ kilometrage + " km.");
}

Ces deux méthodes doivent, bien entendu, être publiques puisqu'elles sont précisément faites pour
être utilisées hors de la classe.

Notez que pour le constructeur de Voiture, on fait appel au constructeur de Vehicule . On fait
également appel à la méthode d'affichage de la super­classe dans la méthode affiche de Voiture.

Les méthodes de la classe Avion s'implémentent de même :

public Avion(String marque, int date, double prix, String moteur, int heures) {
super(marque, date, prix);
this.moteur = moteur;
heuresVol = heures;
}

public void affiche() {


System.out.println(" ­­­­ Avion à " + moteur + "­­­­");
super.affiche();
System.out.println(heuresVol + " heures de vol.");
}

Encore des méthodes

Ajoutez une méthode void calculePrix() dans la classe Vehicule


Le prix doit rester positif (donc s'il est négatif, on le met à 0).

public void calculePrix(int anneActuelle) {


double decote = (anneActuelle ‐ dateAchat) * 0.01;
prixCourant = Math.max(0.0, (1.0 ‐ decote) * prixAchat);
}

Redéfinissez cette méthode dans les deux sous­classes Voiture et Avion.

Les entêtes sont les mêmes pour Voiture et Avion que pour Vehicule, par contre les définitions
diffèrent.

http://icwww.epfl.ch/~sam/ipo/series/serie07/solution_print.html 2/19
10/30/2016 Héritage et base du polymorphisme

Voiture:

public void calculePrix(int anneActuelle) {


double decote = (anneActuelle ‐ getDateAchat()) * .02;
// On force le type en int de manière arrondir le résultat
// On verra dans quelques semaines une manière plus élégante de faire
// ce genre de choses...
decote += 0.05 * (int)(kilometrage / 10000);
if ((getMarque() == "Fiat") || (getMarque() == "Renault")) {
decote += 0.1;
} else if ((getMarque() == "Ferrari") || (getMarque() == "Porsche")) {
decote ‐= 0.2;
}
setPrixCourant(Math.max(0.0, (1.0 ‐ decote) * getPrixAchat()));
}

On se rend compte ici que l'on a besoin d'accèder à des attributs privés de la super­classe, ou de les
modifier (dateAchat, marque, prixAchat et prixCourant). Il faut donc enrichir la classe Vehicule des
"getters/setters" nécessaires :

public int getDateAchat(){


return dateAchat;
}
public String getMarque(){
return marque;
}
public double getPrixAchat(){
return prixAchat;
}
public void setPrixCourant(double prix){
prixCourant = prix;
}

Il aurait été possible de déclarer les attributs nécessaires comme protected dans la classe Vehicule
pour s'éviter la peine de définir les getters/setters. Ceci peut cependant nuire à une bonne
encapsulation : un autre programmeur peut hériter de votre classe Vehicule. Il aurait alors accès aux
détails d'implémentation et vous ne pourriez plus modifier librement cette implémentation sans
potentiellement causer du tort à ses programmes ! Voici enfin la méthode calculePrix pour les
avions :

public void calculePrix(int anneActuelle) {


double decote;
if (moteur == "HELICES") {
decote = 0.1 * heuresVol / 100.0;
} else {
decote = 0.1 * heuresVol / 1000.0;
}
setPrixCourant(Math.max(0.0, (1.0 ‐ decote) * getPrixAchat()));
}

http://icwww.epfl.ch/~sam/ipo/series/serie07/solution_print.html 3/19
10/30/2016 Héritage et base du polymorphisme

Pour finir, ceux qui le souhaitent peuvent trouver ici le code complet.

Exercice 3: Héritage de variables (Héritage, Niveau 1)


1. System.out.println(x.a)
Correct, car une variable d'instance a est déclarée dans la classe de x (E1).

2. System.out.println(y.c)
Faux, car la classe de y (E2) ne dispose pas de la variable d'instance c qui est déclarée dans
une sous­classe (E3).

3. System.out.println(z.b)
Correct, car la variable d'instance b est héritée de la super­classe (E2) de z (qui est de type
E3).

4. System.out.println(v.e)
Faux, car la classe de v (E4) ne dispose pas de la variable d'instance e qui est déclarée dans
une classe parallèle (E3).

5. System.out.println(w.a)
Correct, car la variable d'instance a est héritée d'une super­classe (E1) de w (qui est de type
E5).

Exercice 4: EPFLiens (Héritage, Niveau 2)


Le code complet est fourni ci­dessous.

Direction.java
1
2
http://icwww.epfl.ch/~sam/ipo/series/serie07/solution_print.html 4/19
10/30/2016 Héritage et base du polymorphisme

3
4 class Direction
5 {
6 public static void main(String[] args) {
7 Ecole epfl = new Ecole(5);
8 epfl.add(new EtudiantRegulier("Gaston Peutimide", 2008, "SSC", 6.0));
9 epfl.add(new EtudiantRegulier("Yvan Rattrapeur", 2009, "SSC", 2.5));
10 epfl.add(new EtudiantEchange("Bjorn Borgue", 2010, "Informatique", "KTH"));
11 epfl.add(new Enseignant("Mathieu Matheu", 1998, "LMEP", 10000, "Physique"));
12 epfl.add(new Secretaire("Sophie Scribona", 1995, "LMT", 5000));
13 epfl.afficherStatistiques();
14 epfl.afficherEpfliens();
15 }
16
17 }
18
19
20 class Ecole {
21 private int nbEtudiants;
22 private int nbTotal;
23 private Epflien [] gens;
24
25 public final static int ANNEE = 2012;
26
public Ecole(int nbPersonnes) {
27
gens = new Epflien[nbPersonnes];
28
nbEtudiants = 0;
29
nbTotal = 0;
30
}
31
32
public void add(Epflien personne)
33
{
34 if (nbTotal < gens.length)
35 {
36 gens[nbTotal] = personne;
37 ++nbTotal;
38 if (personne.estEtudiant())
39 {
40 ++nbEtudiants;
41 }
42 }
43 }
44
45 public void afficherStatistiques() {
46 int nbAnneesTotal = 0;
47 for (int i = 0; i < gens.length; i++) {
48 nbAnneesTotal = nbAnneesTotal + (ANNEE ‐ gens[i].getAnnee());
49 }
50 System.out.println("Parmi les " + gens.length + " EPFLiens, " +
51 nbEtudiants + " sont des etudiants.");
52 double moyen = (double) nbAnneesTotal / gens.length;
53 System.out.println("Ils sont ici depuis en moyenne " + moyen + " ans");
54 }
55
public void afficherEpfliens() {
56
System.out.println("Liste des EPFLiens: ");
57
for (int i = 0; i < gens.length; i++)
58
gens[i].afficher();
59
}
60
}
61
62
63 class Epflien {
64 private String nom;
http://icwww.epfl.ch/~sam/ipo/series/serie07/solution_print.html 5/19
10/30/2016 Héritage et base du polymorphisme

64 private String nom;


65 private int annee;
66
67 public Epflien(String nom, int annee) {
68 this.nom = nom;
69 this.annee = annee;
70 }
71
72 public void afficher() {
73 System.out.println(" Nom : " + getNom());
74 System.out.println(" Annee : " + getAnnee());
75 }
76
public String getNom() {
77
return nom;
78
}
79
80
public int getAnnee() {
81
return annee;
82
}
83
84
85 public boolean estEtudiant ()
86 {
87 return false;
88 }
89
90 }
91
92 class Etudiant extends Epflien {
93 private String section;
94
95 public Etudiant(String nom, int annee, String section) {
96 super(nom, annee);
97 this.section = section;
98 }
99
100 public void afficher() {
101 super.afficher();
102 System.out.println(" Section : " + getSection());
103 }
104
public String getSection() {
105
return section;
106
}
107
108 public boolean estEtudiant()
109 {
110 return true;
111 }
112
113 }
114
115 class EtudiantRegulier extends Etudiant {
116 private double prope1;
117
118 public EtudiantRegulier(String nom, int annee, String section, double prope1) {
119 super(nom, annee, section);
120 this.prope1 = prope1;
121 }
122
123 public void afficher() {
124 System.out.println("Etudiant regulier:");
125 super.afficher();
http://icwww.epfl.ch/~sam/ipo/series/serie07/solution_print.html 6/19
10/30/2016 Héritage et base du polymorphisme

125 super.afficher();
126 System.out.println(" Prope I : " + getPrope1());
127 }
128
129 public double getPrope1() {
130 return prope1;
131 }
132 }
133
134 class EtudiantEchange extends Etudiant {
135 private String uniOrigine;
136
public EtudiantEchange(String nom, int annee, String section, String uniOrigine) {
137
super(nom, annee, section);
138
this.uniOrigine = uniOrigine;
139
}
140
141 public void afficher() {
142 System.out.println("Etudiant d'echange:");
143 super.afficher();
144 System.out.println(" Uni d'origine : " + getUniOrigine());
145 }
146
147 public String getUniOrigine() {
148 return uniOrigine;
149 }
150 }
151
152 class Personnel extends Epflien {
153 private String labo;
154 private int salaire;
155
156 public Personnel(String nom, int annee, String labo, int salaire) {
157 super(nom, annee);
158 this.labo = labo;
159 this.salaire = salaire;
160 }
161
162 public void afficher() {
163 super.afficher();
164 System.out.println(" Laboratoire : " + getLabo());
165 System.out.println(" Salaire : " + getSalaire());
166 }
167
public String getLabo() {
168
return labo;
169
}
170
171 public int getSalaire() {
172 return salaire;
173 }
174 }
175
176 class Enseignant extends Personnel {
177 private String section;
178
179 public Enseignant(String nom, int annee, String labo, int salaire, String section) {
180 super(nom, annee, labo, salaire);
181 this.section = section;
182 }
183
184 public void afficher() {
185 System.out.println("Enseignant:");
186 super.afficher();
http://icwww.epfl.ch/~sam/ipo/series/serie07/solution_print.html 7/19
10/30/2016 Héritage et base du polymorphisme

186 super.afficher();
187 System.out.println(" Section d'enseignement : " + getSection());
188 }
189
190 public String getSection() {
191 return section;
192 }
193 }
194
195 class Secretaire extends Personnel {
196 public Secretaire(String nom, int annee, String labo, int salaire) {
197 super(nom, annee, labo, salaire);
198 }
199
public void afficher() {
200
System.out.println("Secretaire:");
201
super.afficher();
202
}
203 }
204
205
206
207

http://icwww.epfl.ch/~sam/ipo/series/serie07/solution_print.html 8/19
10/30/2016 Héritage et base du polymorphisme

Exercice 5: Boîte aux lettres (Héritage, algorithme, Niveau 2)


Une version possible du corrigé est fournie ci­dessous.

Poste.java
1
2
3
4
5 /* Classe pour représenter le courrier
6 */
7
8 class Courrier {
9 // retourne le montant n'ecessaire pour affranchir le courrier
10 // en mode d'exp'edition normal
11
12 // on va faire une chose tre`s vilaine parcequ'on ne connait pas les
13 // m'ethodes abstraites : on va lui donner un corps arbitrairement
14 // d'efini (car on ne sait pas la d'efinir proprement
15 // a` ce niveau de la hi'erarchie
16 public double affranchirNormal(){return 0;};
17 // la bonne solution consiste a` d'eclarer cette m'ethode comme suit:
18 // abstract private double affranchirNormal();
19 // lorsque vous aurez vu le cours 8, expliquez pourquoi...
20
21 // les attributs (communs aux lettres et colis):
22 private double poids;
23 private boolean express;
24 private String adresse;
25
26 // un constructeur possible pour la classe
27 public Courrier(double poids, boolean express, String adresse) {
28 this.poids = poids;
29 this.express = express;
30 this.adresse = adresse;
}
31
32
// un getter pour le poids (car utile dans les sous­classe)
33
public double getPoids() {
34
return poids;
35
}
36
37 // retourne le montant n'ecessaire pour affranchir le courrier.
38 // elle appelle affranchirNormal et retourne le double de ce montant
39 // si le mode d'exp'edition est express ('eviter la duplication du code
40 // qui double le montant dans les m'ethodes affranchir­normal
41 // des sous­classes)
42 public double affranchir() {
43 if (! valide())
44 {
45 return 0;
46 }
47 else
48 {
49 double total = affranchirNormal();
50 if (express) {
51 total *= 2;
52 }
53 return total;

http://icwww.epfl.ch/~sam/ipo/series/serie07/solution_print.html 9/19
10/30/2016 Héritage et base du polymorphisme
54 }
55 }
56
57 // un courrier est invalide si l'adresse de destination est vide
58 // methode utilis'ee par Boite::affranchir et
59 // Boite::courriersInvalides
60 public boolean valide() {
61 return adresse.length() > 0;
62 }
63
64 @Override
65 public String toString() {
66 String s = "";
67 if (!valide())
68 {
s+= "(Courrier invalide)\n";
69
}
70
s+= " Poids : " + poids + " grammes\n";
71
s+= " Express : " + (express ? "oui" : "non") + "\n";
72
s+= " Destination : " + adresse + "\n";
73
s+= " Prix : " + affranchir() + " CHF\n";
74
return s;
75
}
76
77 }
78
79 /* Une classe pour repr'esenter les lettres
80 */
81
82 class Lettre extends Courrier {
83
84 //attributs sp'ecifiques aux lettres:
85 private String format = "";
86
87 public Lettre(double poids, boolean express, String adresse, String format){
88 super(poids, express, adresse);
89 this.format = format;
90 }
91
92 // red'efinit affranchirNormal()
93 public double affranchirNormal() {
94 double montant = 0;
95 if (format.equals("A4")){
96 montant = 2.0;
97 } else {
98 montant = 3.5;
99 }
100 montant += getPoids()/1000.0;
101 return montant;
102 }
103
104 // inutile de red'efinir la méthode valide() pour les lettres
105
106 @Override
public String toString() {
107
String s = "Lettre\n";
108
s += super.toString();
109
s += " Format : " + format + "\n";
110
return s;
111
}
112
113 }
114 /* Une classe pour repr'esenter les publicit'es
http://icwww.epfl.ch/~sam/ipo/series/serie07/solution_print.html 10/19
10/30/2016 Héritage et base du polymorphisme
115 */
116
117 class Publicite extends Courrier {
118
119 public Publicite(double poids, boolean express, String adresse){
120 super(poids, express, adresse);
121 }
122
123 // redéfinit affranchirNormal()
124 public double affranchirNormal() {
125 return getPoids()/1000.0 * 5.0;
126 }
127
128
// inutile de red'efinir la méthode valide() pour les publicités
129
130
@Override
131
public String toString() {
132
String s = "Publicité\n";
133
s += super.toString();
134 return s;
135 }
136
137 }
138
139 /* Une classe pour repr'esenter les colis
140 */
141 class Colis extends Courrier {
142
143 //attributs sp'ecifiques aux colis:
144 private double volume;
145
146 public Colis(double poids, boolean express, String adresse, double volume) {
147 super(poids, express, adresse);
148 this.volume = volume;
149 }
150
151 // redéfinit affranchirNormal();
152 public double affranchirNormal() {
153 // affranchit les colis selon une formule pr'ecise
154 return 0.25 * volume + getPoids()/1000.0;
155 }
156
157 // ici il faut red'efinir (sp'ecialiser) la re`gle de validit'e des colis
158 // un colis est invalide s' il a une mauvaise adresse
159 //ou depasse un certain volume
160 public boolean valide(){
161 return (super.valide() && volume <= 50);
162 }
163
@Override
164
public String toString() {
165
String s = "Colis\n";
166
s += super.toString();
167
s += " Volume : " + volume + " litres\n";
168
return s;
169
}
170
171
172 }
173
174 /* Une classe pour repr'esenter la boite aux lettre
175 */
http://icwww.epfl.ch/~sam/ipo/series/serie07/solution_print.html 11/19
10/30/2016 Héritage et base du polymorphisme
176
177 class Boite {
178
179 private Courrier[] contenu;
180 private int index;
181
182 // constructeur
183 public Boite(int max) {
184 contenu = new Courrier[max];
185 index = 0;
186 }
187
188 // la méthode demand'ee
189 public double affranchir() {
190 double montant = 0.0;
191 for(int i=0; i < index; ++i){
192 Courrier c = contenu[i];
193 montant += c.affranchir();
}
194
return montant;
195
}
196
197 public int size() {
198 return index;
199 }
200
201 public Courrier getCourrier(int index) {
202 if (index < contenu.length)
203 return contenu[index];
204 else
205 return null;
206 }
207
208 // autre m'ethode demandée dans l'interface
209 // d'utilisation de la classe
210 public int courriersInvalides() {
211 int count = 0;
212 for (int i = 0; i < index; i++) {
213 if (!contenu[i].valide())
214 count++;
215 }
216 return count;
217 }
218
219 // difficile de fonctionner sans
220 public void ajouterCourrier(Courrier unCourrier) {
221 if (index < contenu.length){
222 contenu[index] = unCourrier;
223 index++;
224 } else {
225 System.out.println("Impossible d'ajouter un nouveau courrier. Boite pleine !");
226 }
227 }
228
public void afficher() {
229
for (int i = 0; i < index; i++) {
230
System.out.println(contenu[i]);
231
}
232
}
233
234 }
235
236
// PROGRAMME PRINCIPAL (non demandé)
http://icwww.epfl.ch/~sam/ipo/series/serie07/solution_print.html 12/19
10/30/2016 Héritage et base du polymorphisme
237 // PROGRAMME PRINCIPAL (non demandé)
238 class Poste {
239
240 public static void main(String args[]) {
241 //Cr'eation d'une boite­aux­lettres
242 Boite boite = new Boite(30);
243
244 //Creation de divers courriers/colis..
245 Lettre lettre1 = new Lettre(200, true, "Chemin des Acacias 28, 1009 Pully", "A3");
246 Lettre lettre2 = new Lettre(800, false, "", "A4"); // invalide
247
248 Publicite pub1 = new Publicite(1500, true, "Les Moilles 13A, 1913 Saillon");
249 Publicite pub2 = new Publicite(3000, false, ""); // invalide
250
251 Colis colis1 = new Colis(5000, true, "Grand rue 18, 1950 Sion", 30);
252 Colis colis2 = new Colis(3000, true, "Chemin des fleurs 48, 2800 Delemont", 70); //Colis invalide !
253
254 boite.ajouterCourrier(lettre1);
255 boite.ajouterCourrier(lettre2);
boite.ajouterCourrier(pub1);
256
boite.ajouterCourrier(pub2);
257
boite.ajouterCourrier(colis1);
258 boite.ajouterCourrier(colis2);
259
260
261 System.out.println("Le montant total d'affranchissement est de " +
262 boite.affranchir());
263 boite.afficher();
264
265 System.out.println("La boite contient " + boite.courriersInvalides()
266 + " courriers invalides");
267 }
268 }
269
270
271
272

Exercice 6: Puissance 4 (Héritage, algorithme, Niveau 3)


Une version simple du Puissance4 vous est fournie. Une bonne extension consiste à essayer de coder
des stratégies de jeu un peu plus élaborées.

Puissance4.java
1
2
3
4
5
6 import java.util.Scanner;
7 /**
8 * Classe principale
9 */
10 class Puissance4 {
11 protected static Scanner scanner = new Scanner(System.in);
12 public static void main(String[] args) {
13 System.out.println("Entrez votre nom: ");
14 String nom = scanner.nextLine();
15 System.out.println("­­");

16 Partie p = new Partie(new Ordinateur(Jeu.BLEU),


http://icwww.epfl.ch/~sam/ipo/series/serie07/solution_print.html new Humain(nom, Jeu.ROUGE)); 13/19
10/30/2016 Héritage et base du polymorphisme

16 Partie p = new Partie(new Ordinateur(Jeu.BLEU), new Humain(nom, Jeu.ROUGE));


17 p.joue();
18 }
19 }
20
21 class Partie {
22
23 private Joueur[] joueurs = new Joueur[2];
24 private Jeu jeu;
25
26 public Partie(Joueur joueur1, Joueur joueur2) {
27 joueurs[0] = joueur1;
28 joueurs[1] = joueur2;
29 jeu = new Jeu();
30 }
31
public void joue() {
32
int vainqueur = ‐1;
33
int cJoueur = 0;
34
35
while (vainqueur==‐1 && !jeu.estPlein()) {
36
joueurs[cJoueur].joue(jeu);
37 if (jeu.estPlein()) {
38 vainqueur = ‐1;
39 }
40
41 // Si 4 pions sont alignés, on a un vainqueur
42 // (même si le jeu est plein!)
43
44 if (jeu.cherche4()) {
45 vainqueur = cJoueur;
46 }
47
48 // On change de joueur pour l'itération suivante
49 cJoueur++;
50 cJoueur %= 2;
51 }
52
53 System.out.println("La partie est finie.");
54 jeu.afficher();
55 if (vainqueur == ‐1) {
56 System.out.println("Match nul.");
57 } else {
58 System.out.println("Le vainqueur est " + joueurs[vainqueur].getNom());
59 }
60 }
}
61
62
class Jeu {
63
// final static est une bonne maniere de
64
// definir des constantes (voir aux cours prochains)
65
public final static int VIDE = 0;
66
public final static int BLEU = 1;
67
public final static int ROUGE = 2;
68
69 private int taille;
70 private int[][] grille; // 0 = vide, 1 = joueur bleu, 2 = joueur rouge
71
72 public Jeu(int taille) {
73 initJeu(taille);
74 }
75
76 public Jeu() {
77 initJeu(8);
http://icwww.epfl.ch/~sam/ipo/series/serie07/solution_print.html 14/19
10/30/2016 Héritage et base du polymorphisme

77 initJeu(8);
78 }
79
80 private void initJeu(int taille) {
81 this.taille = taille;
82 grille = new int[taille][taille];
83 for (int col = 0; col < taille ; col++) {
84 for (int row = 0; row < taille; row++) {
85 grille[col][row] = VIDE;
86 }
87 }
88 }
89
public boolean joueCoup(int col, int joueur) {
90
if ((col < 0) || (col >= taille)) {
91
return false;
92
}
93
94 // Trouve la première place vide dans la colonne
95 for (int ligne = 0; ligne < taille; ligne++) {
96 if (grille[col][ligne] == VIDE) {
97 grille[col][ligne] = joueur;
98 return true;
99 }
100 }
101
102 // La colonne est pleine
103 return false;
104 }
105
106 /**
107 * Cette méthode vérifie toutes les lignes, colonnes et diagonales pour une série de 4 pions
108 * de la même couleur. Si une telle série existe, retourne true.
109 *
110 * Notez qu'il n'est pas nécessaire de retourner la couleur des 4 pions alignés,
111 * puisqu'il s'agit de celle de celui qui vient de jouer.
112 * @return true si le jeu contient 4 pions alignés
113 */
114 public boolean cherche4() {
115 // Vérifie les horizontales ( ­ )
116 for (int ligne = 0; ligne < taille; ligne++) {
117 if (cherche4alignes(0, ligne, 1, 0)) {
118 return true;
119 }
120 }
121
122 // Vérifie les verticales ( ¦ )
123 for (int col = 0; col < taille; col++) {
124 if (cherche4alignes(col, 0, 0, 1)) {
125 return true;
126 }
127 }
128
129 // Diagonales (cherche depuis la ligne du bas)
130 for (int col = 0; col < taille; col++) {
131 // Première diagonale ( / )
132 if (cherche4alignes(col, 0, 1, 1)) {
133 return true;
134 }
// Deuxième diagonale ( \ )
135
if (cherche4alignes(col, 0, ‐1, 1)) {
136
return true;
137
138 }
http://icwww.epfl.ch/~sam/ipo/series/serie07/solution_print.html 15/19
10/30/2016 Héritage et base du polymorphisme

138 }
139 }
140
141 // Diagonales (cherche depuis les colonnes gauches et droites)
142 for (int ligne = 0; ligne < taille; ligne++) {
143 // Première diagonale ( / )
144 if (cherche4alignes(0, ligne, 1, 1)) {
145 return true;
146 }
147 // Deuxième diagonale ( \ )
148 if (cherche4alignes(taille ‐ 1, ligne, ‐1, 1)) {
149 return true;
150 }
151 }
152
// On n'a rien trouvé
153
return false;
154
}
155
156
/**
157
* Cette méthode cherche 4 pions alignés sur une ligne. Cette ligne est définie par
158
* le point de départ, ou origine de coordonnées (oCol,oLigne), et par le déplacement
159
* delta (dCol,dLigne). En utilisant des valeurs appropriées pour dCol et dLigne
160
* on peut vérifier toutes les directions:
161
* ­ horizontale: dCol = 0, dLigne = 1
162
* ­ vérticale: dCol = 1, dLigne = 0
163
* ­ 1ère diagonale: dCol = 1, dLigne = 1
164
* ­ 2ème diagonale: dCol = 1, dLigne = ­1
165
*
166
* @param oCol Colonne d'origine de la recherche
167
* @param oLigne Ligne d'origine de la recherche
168
* @param dCol Delta de déplacement sur une colonne
169
* @param dLigne Delta de déplacement sur une ligne
170
* @return true si on trouve un alignement
171
*/
172
private boolean cherche4alignes(int oCol, int oLigne, int dCol, int dLigne) {
173
int couleur = VIDE;
174
int compteur = 0;
175
176 int curCol = oCol;
177 int curRow = oLigne;
178
179 while ((curCol >= 0) && (curCol < taille) && (curRow >= 0) && (curRow < taille)) {
180 if (grille[curRow][curCol] != couleur) {
181 // Si la couleur change, on réinitialise le compteur
182 couleur = grille[curRow][curCol];
183 compteur = 1;
184 } else {
185 // Sinon on l'incrémente
186 compteur++;
187 }
188
189 // On sort lorsque le compteur atteint 4
190 if ((couleur != VIDE) && (compteur == 4)) {
191 return true;
192 }
193
194 // On passe à l'itération suivante
195 curCol += dCol;
196 curRow += dLigne;
197 }
198
199 // Aucun alignement n'a été trouvé
http://icwww.epfl.ch/~sam/ipo/series/serie07/solution_print.html 16/19
10/30/2016 Héritage et base du polymorphisme

199 // Aucun alignement n'a été trouvé


200 return false;
201 }
202
203 /**
204 * Vérifie s'il est encore possible de placer des pions
205 * @return true si le tableau est plein
206 */
207 public boolean estPlein() {
208 // On cherche une case vide. S'il n'y en a aucune, le tableau est plein
209 for (int col = 0; col < taille; col++) {
210 for (int ligne = 0; ligne < taille; ligne++) {
211 if (grille[col][ligne] == VIDE) {
212 return false;
213 }
214 }
215 }
216
217 return true;
218 }
219
public int getTaille() {
220
return taille;
221
}
222
223 public void afficher() {
224 for (int ligne = taille ‐ 1; ligne >= 0; ‐‐ligne) {
225 for (int col = 0; col < taille; col++) {
226 switch (grille[col][ligne]) {
227 case VIDE:
228 System.out.print(' ');
229 break;
230 case ROUGE:
231 System.out.print('R');
232 break;
233 case BLEU:
234 System.out.print('B');
235 break;
236 }
237 }
238 System.out.println();
239 }
240
241 for (int i = 0; i < taille; ++i) {
242 System.out.print('­');
243 }
244 System.out.println();
245 for (int i = 1; i <= taille; ++i) {
246 System.out.print(i);
247 }
248 System.out.println();
249 }
250 }
251
class Joueur {
252
private String nom;
253
private int couleur;
254
255
public Joueur(String nom, int couleur) {
256
this.nom = nom;
257
this.couleur = couleur;
258 }
259
260 public String getNom() {
http://icwww.epfl.ch/~sam/ipo/series/serie07/solution_print.html 17/19
10/30/2016 Héritage et base du polymorphisme

260 public String getNom() {


261 return nom;
262 }
263
264 public int getCouleur() {
265 return couleur;
266 }
267
268 /**
269 * Cette méthode joue un coup avec le tableau reçu en paramètre.
270 * La méthode est vide car les sous­classes doivent l'implémenter.
271 * (Vous verrez prochainement comment gérer ce genre de cas plus proprement)
272 * @param jeu Le Jeu avec lequel jouer.
273 */
274 public void joue(Jeu jeu) {}
275
276 }
277
class Humain extends Joueur {
278
279
public Humain(String nom,int couleur) {
280
super(nom, couleur);
281
}
282
283 public void joue(Jeu jeu) {
284 jeu.afficher();
285
286 boolean valide;
287 do {
288 System.out.println("Joueur " + this.getNom() + ", entrez un numéro de colonne" +
289 " (entre 1 et " + jeu.getTaille() + ") : ");
290
291 int col = Puissance4.scanner.nextInt(); // on pourrait faire ici la validation de la lecture
292 col‐‐; // remet entre 0 et taille­1 (indice à la Java)
293
294 valide = jeu.joueCoup(col, this.getCouleur());
295 if (valide == false) {
296 System.out.println("­> Coup NON valide.");
297 }
298 } while (valide == false);
299 }
300 }
301
302 //======================================================================
303
304 class Ordinateur extends Joueur {
305
306 public Ordinateur(int couleur) {
307 super("Le programme", couleur);
308 }
309
public void joue(Jeu jeu) {
310
for (int col = 0; col < jeu.getTaille(); col++) {
311
if (jeu.joueCoup(col, this.getCouleur())) {
312
System.out.println(this.getNom() + " a joué en " + (col + 1));
313
return;
314
}
315
}
316
}
317 }
318
319

320
http://icwww.epfl.ch/~sam/ipo/series/serie07/solution_print.html 18/19
10/30/2016 Héritage et base du polymorphisme

320
321

http://icwww.epfl.ch/~sam/ipo/series/serie07/solution_print.html 19/19

Vous aimerez peut-être aussi