You are on page 1of 6

Travaux Pratiques Numro 3 : Le jeu de la bataille Navale

Objectifs : 1. Programmer un jeu en Java 2. Matriser la classe Vector 3. Hritage et Polymorphisme On voudrait raliser un jeu de bataille navale. Un jeu de bataille navale se compose d'un tableau et d'un ensemble de bateaux, chaque bateau se compose d'un ensemble de taille fixe d'lements. Un croiseur comprend 3 lments, un escorteur 2 et un sous-marin un seul lment. Chaque lment est caractris par sa position et par son tat: sain ou touch. Les sous-marins ont la possibilit de plonger. Lorsqu'ils plongent ils ne peuvent pas tre touchs. Un tableau contient un ensemble de bateaux. Un bateau est caractris par l'ensemble de ses lments. Voici comment on instancie une flotte de bateaux (qui correspond la figure 3):

Bateau b1 =new Croiseur(1,1,true);//un croiseur horizontal dont le premier lment est en 1,1 (les coordonnes ont leur origine en 0,0). Bateau b2 =new Escorteur(2,5,false);//un escorteur vertical dont le premier lment est en 2,5 Bateau b3 =new SousMarin(4,2,true);//un sous-marin en 4,2 et en surface (false =en plonge). Tableau t1 =new Tableau(7,9); t1.ajouterBateau(b1); t1.ajouterBateau(b2); t1.ajouterBateau(b3); On vous donne ci-dessous les classes correspondantes ce jeu et on souhaite maintenant crire un excutable correspondant au Jeu. 1. Le jeu se joue contre lordinateur. Le tableau est de taille (10,10). 2. Au dpart lordinateur (mthode initialise dans la classe Jeu) positionne de manire alatoire ces vaisseaux voir ci-dessous. - Un Croiseur Horizontal - Un Croiseur vertical - Un Escorteur Vertical - Deux sous Marin en surface 3. Avec la saisie clavier vous essayer de deviner le placement des bateaux 4. Tant que vous navez pas coul tous les bateaux le jeu nest pas fini. 5. A la fin du jeu on vous affiche : Bravo, vous avez gagn en par exemple 20 coups.

Manipulation 1 : La mthode initialise


Ecrire la classe excutable Jeu et se mthode initialise() qui permet lordinateur de placer ces bateaux comme expliqu ci-dessus (point 2). Utiliser la classe Tableau. Remarquer que cette classe instancie un Vector. Utiliser la mthode x = (int)Math.random()*ValeurXMax, y= (int)Math.random()*ValeurYMax pour placer les bateaux. Attention si par exemple cest un croiseur horizontal VXmax doit tre gale a nombre de lignes-3 et pour un croiseur vertical cest la mme chose mais avec VYmax-3. Afficher sur la console les coordonnes des bateaux choisis par lordinateur pour vrification uniquement.

Manipulation 2 : La classe java.util.Vector et la mthode equals


Toujours dans la mthode initialise placer deux bateaux identiques avec la mthode ajouterBateau . Est-ce que les deux bateaux sont effectivement rajouts dans le Vector mme si ils sont identiques ? Mme chose faites le test avec la methode enleverBateau. Le bateau dont l'instance est pass en paramtre et pas la rfrence est il effectivement supprim ? Pourquoi cela ne marque pas ? Lire la documentation de la mthode contains de la classe Vector, su quelle autre mthode se base t-elle pour faire la recherche ? ajouter la mthode equals et refaites les tests.

Manipulation 2 : La mthode jouer


Ecrire la mthode qui contient une boucle ne sarrtant que si tous les bateaux sont tous couls. Dans ce cas on sort de la boucle en affichant le message au vainqueur. A chaque fois on demande au joueur de donner les coordonnes x,y du point quil veut bombarder. Pour cela utiliser les mthodes d'interactions clavier avec l'utilisateur. Si ce point est un lment dun bateau on affiche le message : bateau touch . Si tous les lments prcdents de ce bateau on dj t touch n affiche Bateau coul : Escorteur . Quand le jeu est fini n affiche Bravo vus avez gagn Voici le squelette de la mthode joue complter :

public void joue() {while (t.bateaux.size()!=0) {} } Il faut savoir que la mthode int coupe(int px, int py) de la classe Tableau renvoie 0 si le coup est dans leau, renvoie 1 si l bateau est touch pour la premire fois, 2 sil est touch pour une deuxime fois, et 3 sil est coul. Ci-dessous quelques lments pour vous aider :

class Element { int x, y; boolean touche= false; Element(int x, int y) { this.x= x; this.y= y; } void avancer(int dx, int dy) { x= x + dx; y= y + dy; } int estTouche(int px, int py) { if ((x == px) && (x == py)) { if (touche) return 1; else { touche= true; return 2; } } else return 0; } } class Bateau { boolean horizontal= true; Element[] elements; int cpt=0 ; Bateau(int x, int y, boolean horiz, int taille) { horizontal= horiz; elements= new Element[taille]; for (int i= 0; i < taille; i++) { if (horizontal) elements[i]= new Element(x + i, y); else elements[i]= new Element(x, y + i); } } int estTouche(int px, int py) { int res= 0; for (int i= 0; i<elements.length; i++) { int r= elements[i].estTouche(px, py); if (r == 1) { res= 1; cpt++; } else if(r == 2) { res= 2; cpt++; } } if (cpt == elements.length) return 3; else return res; } void avancer(int dx, int dy) {

} }

for (int i=0; i < elements.length; i++) elements[i].avancer(dx, dy);

class Croiseur extends Bateau{ Croiseur(int x,int y,boolean horiz){ super(x,y,horiz,3); } } class Escorteur extends Bateau{ Escorteur(int x,int y,boolean horiz){ super(x,y,horiz,2); } }

class SousMarin extends Bateau { boolean enPlongee; SousMarin(int x, int y, boolean plongee) { super(x, y, true, 1); enPlongee= plongee; } int estTouche(int px, int py) { if (enPlongee) return 0; else return (super.estTouche(px, py)); } void avancer(int dx, int dy) { if (!enPlongee) { super.avancer(dx, dy); } } }

import java.util.*; class Tableau { int colonnes; int lignes; Vector bateaux; Tableau(int l, int c) { colonnes = c; lignes = l ; bateaux= new Vector(); } void ajouterBateau(Bateau b) { if (!bateaux.contains(b)) bateaux.add(b); } int coup(int px, int py) {

} void enleverBateau(Bateau b) { bateaux.remove(b);}}

if ((px < 0) || (px >= colonnes) || (py < 0) || (py >= lignes)) return 0; else { for (int i= 0; i < bateaux.size(); i++) { Bateau b= (Bateau) bateaux.get(i); int r= b.estTouche(px, py); if (r != 0) { if (r == 3) enleverBateau(b); return r; } } return 0; }

Variante
On peut aussi ne pas considrer les lments comme des entits et tout grer partir dun tableau de boolens associ aux bateaux. Ici on calcule chaque appel de estTouche le fait quun bateau soit coule ou non. On peut le calculer une fois pour toutes et laisser cette information dans un attribut boolean coule ddi cette effet. Notes Notez le fait que lon utilise pleinement la classe Element. La tendance des dbutants en objet est de considrer de telles classes comme de simples structures de donnes passives. Au contraire, cest en grant pleinement la classe Element comme une entit part entire que lon simplifie des mthodes telles que estTouche ou avancer. Les mthodes estTouche et avancer sont redfinies dans SousMarin et font appel au code standard. Cela simplifie le code.

Recommandations
Voici un ensemble de recommandations qui sadressent non seulement ceux qui nont pas russi lexamen, mais aussi ceux qui lont pass. Car pratiquement aucun tudiant na rellement appliqu ces recommandations dans leur intgralit. 1. Lcriture dun programme est un art (au sens ancien du mtier artisanal) qui rclame un certain tour de main (mme si ce tour de main est videmment trs intellectuel en informatique). La programmation est certainement lune des rares activits industrielle qui sexprime encore comme un art (au m me titre quun architecte par exemple). Comme dans toute qualit ncessitant un tour de main (pensez aux compagnons du tour de France) un travail bien fait se reconnat au fait quil a t conu intelligemment (et non pas cod toute vitesse dans tous les sens) et que sa structure prsente une certaine harmonie. Utilisez votre sens esthtique pour dterminer si un programme est correct ou non : un beau programme a plus de chance de tourner et dtre volutif que du code jet la va vite.. 2. Il faut que le code des classes soit cohrent avec le diagramme. Pensez aussi limplmentation des relations. Pour une association ou une agrgation avec une cardinalit *, utilisez un Vector. Si au contraire le nombre des lments est fixe, utilisez un tableau. 3. Il faut toujours rechercher la gnricit dans un programme. Ecrivez toujours un programme comme si vous deviez le modifier et ltendre le lendemain pour lui ajouter des fonctionnalits. En particulier : vitez les structures de donnes inutiles, toutes les techniques ad hoc que lon nutilise que pour rsoudre un tout petit cas particulier. 4. Entre autre : ne JAMAIS mettre des constantes en dur dans le code ! (dans lexemple prcdent, ne pas faire des choses du genre : for(int i=0 ;i < 7 ; i++). Le code ne sera jamais extensible 5

5. Recherchez la simplicit et la lisibilit de votre programme. Un bon programme est un programme simple. Moins il y a de lignes de code, tout en tant lisible (pas dastuces qui diminuent en fait la lisibilit du code), plus votre programme a de chances dtre extensible et donc rapidement fonctionnel. La simplicit et la lisibilit sont les clefs de la bonne programmation. 6. En programmation objet : toujours rechercher utilisez la hirarchie des classes et len voi de message. Cest un mcanisme trs puissant. En particulier nutilisez JAMAIS un champ type (ou nature ou sorte) avec des mthodes qui font des tests sur ces types, utilisez toujours lhritage la place. 7. Ne pas confondre hritage avec composition. Lhritage rpond la question sorte de (un chien est une sorte de animal), alors que lagrgation (et la composition) rpond la question partie de (la tte dun chien est une partie de ce chien). 8. Essayez que vos objets agissent par eux mmes : pensez que chaque objet est un petit tre qui agit par lui mme. Nagissez pas sur les objets comme sil sagissait de structures de donnes passives, demandez aux objets dagir ! Jespre que ces recommendations vous permettront de mieux russir dans vos examens futurs, mais aussi tout simplement dcrire des programmes mieux conus et plus objet .

You might also like