Explorer les Livres électroniques
Catégories
Explorer les Livres audio
Catégories
Explorer les Magazines
Catégories
Explorer les Documents
Catégories
. DEV2 – Développement
Projet
Le jeu Diamant
1 Présentation 2
2 Le jeu « Diamant » 8
3 Itération 1 9
4 Itération 2 18
5 Itération 3 28
6 Remise du projet 32
7 Le mot de la fin 32
Échéances
Date Étape
18 mars Publication de l’énoncé
Semaine du 26 mars Remise de l’itération 1
Semaine du 23 avril Remise de l’itération 2
Semaine du 7 mai Remise de l’itération 3
Ce document est distribué sous licence Creative Commons Paternité - Partage à l’Identique 2.0 Belgique
(http://creativecommons.org/licenses/by-sa/2.0/be/).
Les autorisations au-delà du champ de cette licence peuvent être obtenues à esi-bru.be - .
Version du document : 15 mars 2018
1 Présentation
1.1 Le projet
Ce projet vous permettra de mettre en œuvre la plupart des concepts vus pendant
cette première année : programmation orientée objet, utilisation du langage Java,
tests unitaires et documentation d’une application Java.
Nous allons coder une application permettant de gérer le jeu « Diamant » dont les
règles sont présentées dans un document que vous pourrez trouver sur poÉsi.
Il va se dérouler en 4 phases en suivant un mode de développement itératif. Nous
veillerons à ce que chacune de ces phases soient strictement personnelles.
1. L’itération 1 représente une version jouable du jeu, mais avec très peu de règles
implémentées ;
2. L’itération 2 représente une version jouable avec la plupart des règles implé-
mentées ;
3. L’itération 3 représente une version complète du jeu ;
4. Défense du projet où il vous sera demandé de réaliser une petite modification.
1.3 Échéances
Les professeurs de java ont décidé de vous enseigner à programmer dans l’environ-
nement de développement intégré (EDI) Netbeans. Ceci devrait être pour la plupart
d’entre vous une grande facilité.
Le corollaire de cette facilité seront des exigences plus importantes. Certaines, notées
par ♣, sont rédhibitoires : si l’exigence n’est pas satisfaite, le code n’est pas relu et
la note est zéro.
Ces exigences sont présentées ci-dessous :
. ♣ le code doit être convenablement indenté (Pressez Shift-Alt-F qui indente
automatiquement le code) ;
. ♣ le code doit compiler (aucune erreur ne doit être présente lors de la compi-
lation) ;
. ♣ la Javadoc doit être complète. Chaque méthode de chaque classe doit posséder
une Javadoc ;
. ♣ toutes les méthodes pour lesquelles des tests sont demandés doivent posséder
des tests unitaires ;
. tout écart par rapport à l’énoncé (ajout d’une méthode non privée, modification
du comportement d’une méthode demandée) devra être validé au préalable par
votre professeur qui jugera de sa pertinence ;
. utilisez les éléments de langage les plus appropriés à ce que vous devez faire :
par exemple, un foreach quand c’est possible ;
. tout le développement est en anglais : le code, la Javadoc ; vous pouvez cepen-
dant écrire la documentation complémentaire dans le code ainsi que l’interaction
avec l’utilisateur en français ;
. les méthodes doivent être courtes sauf cas particuliers rares. Vous écrirez donc
les méthodes complémentaires nécessaires pour satisfaire cette condition ;
. le respect attentif des conventions de codage Java 2 ;
. l’orthographe est une des marques de l’attention que vous attachez à votre
travail. Dans cette mesure, elle peut compter et des points vous seront retirés
s’il y a trop de fautes ;
2. Le document qui les décrit est disponible sur poÉSI.
1.6 Évaluation
L’évaluation du projet portera sur ce que vous avez remis. Pour que vos travaux
soient évalués, il faut que les points marqués ♣ soient satisfaits. S’ils ne le sont pas,
nous ne ferons pas l’effort de lire et commenter vos travaux. Par exemple, il faut que
les tests soient présents, c’est-à-dire que des fichiers de tests unitaires pour toutes
les méthodes pour lesquels des tests sont mentionnés existent. Selon la qualité et
la pertinence de ces tests, vous aurez plus ou moins de points. Mais donc zéro dès
qu’un de ces fichiers n’est pas présent.
Pour rappel, le projet compte pour 24% de la cote finale de l’UE DEV2. Chaque
remise sera prise en compte avec la pondération ci-dessous.
Remise 1 5/20
Remise 2 6/20 (+2/20 pour l’amélioration de la remise 1)
Remise 3 5/20 (+2/20 pour l’amélioration de la remise 2)
Si une partie n’est pas remise, l’étudiant peut continuer son projet mais, bien sûr,
il recevra 0 pour cette partie non remise.
La cote est attribuée au terme de la défense orale, faite à l’école, sur une machine
de laboratoire aléatoire et sur linux1. La défense est obligatoire pour recevoir
une cote de projet.
Les professeurs considèrent que tout doit être fait, fonctionnel, maitrisable complète-
ment par vous sur ces environnements (PC de labos et linux1) à l’école. Manquer
à l’un des 2 est synonyme d’échec.
Pour la première itération, les tests vous sont offerts. Prenez exemple sur ceux-ci,
afin de choisir méthodologiquement le nom de vos méthodes de tests de manière à
retrouver la méthode testée ainsi que la description du cas :
test<NomMéthode><descriptionDuCas>()
Exemple pour une méthode isFree(Coordinates position) qui retourne true si
la position donnée en paramètre est libre, sinon false.
1 @Test
2 public void testIsFreeWhenPosIsFree() {
3 ...
4 assertTrue(instance . isFree (position ));
5 }
Astuce Netbeans
Lorsque vous voulez renommer une variable avec Netbeans :
Le projet consiste à implémenter le jeu « Diamant » dont vous trouverez les règles
sur poÉsi via le document Diamant.pdf 4 .
La partie modèle (model) contiendra pour nous les classes qui définissent les
éléments ainsi que la logique principale de l’application. Ces classes seront regroupées
dans un package spécifique : g12345.diamond.model 6 .
Nous voici à la première itération de notre projet. Cette itération a pour objectif de
fournir une version très simplifiée du jeu Diamant (V0.1). Cette itération permettra :
3.1 Le modèle
Explorer
- pseudonym Cave
- bag : Bag enum
- state : State State
- lastDiscoveredTreasure : Treasure
+ Explorer(pseudonym : String) LEAVING
EXPLORING + Cave()
+ getPseudonym() : String
+ getLastDiscoveredTreasure() : Treasure
+ takeDecisionToLeave()
+ discoverNewTreasure(explorers : Explorer[*])
+ addToBag(nbRubies : Int)
+ getBag() : Bag
+ getState() : State
0
*
1
Treasure
Bag
- nbRubies : Int
- nbRubies : Int
∼ Treasure(rubies : Int)
+ Bag()
+ Treasure()
+ addRubies(nbRubies : Int)
+ getInitNbRubies() + getRubies() : Int
+ getNbRubies() : Int
+ explore(explorers : Explorer[*]) : Int
Dans le jeu, les gemmes ramassées dans une grotte sont posées à côté du coffre du
joueur en attendant d’être définitivement gagnées. Ici, nous les placerons dans un
sac représenté par la classe Bag. Cette classe sera donc utilisée pour représenter
l’ensemble des rubis récoltés par les joueurs au cours de l’exploration d’une entrée
Attributs
. private int nbRubies : représente les rubis contenus dans le sac.
Constructeur
. Bag() : lorsqu’il est créé, un sac ne contient aucun rubis.
Méthodes
. addRubies(int nbRubies) : permet d’ajouter plusieurs rubis dans le sac ;
. int getNbRubies() : retourne le nombre de rubis contenus dans le sac.
Cette classe va permettre de représenter nos explorateurs. Chacun d’eux sera diffé-
rencié grâce à son pseudonyme.
Attributs
. pseudonym : pseudonyme du joueur ;
. bag : sac du joueur ;
. state : sert à identifier l’état de l’explorateur.
Méthodes
. Un getter pour chacun des attributs de la classe 7 ;
. addToBag(nbRubies: int) : permet d’ajouter un nombre donné de rubis dans
le sac du joueur ;
. takeDecisionToLeave() : permet d’indiquer que l’explorateur décide de quit-
ter la grotte. Elle change son statut en conséquence.
7. Pour rappel, un clic-droit/Insert Code... vous permettra de générer facilement les méthodes
les plus courantes ;)
Une fois, cette option cochée, Netbeans affichera une petite ampoule
devant le premier élément mal placé et vous proposera de réorganiser
toute la classe.
Les tuiles trésors (Treasure) ont la particularité de contenir des rubis à partager
équitablement entre les explorateurs qui explorent la salle.
Attributs
. private int rubies : représente le nombre de rubis présents sur la tuile.
. private final int initNbRubies : représente le nombre de rubis présents
lors de sa création.
Constructeur
. Treasure(int rubies) : initialisation des attributs de la classe avec un nombre
de rubis donné.
. Treasure() : Initialisation des attributs de la classe avec un nombre compris
entre 1 et 15 généré aléatoirement.
Méthodes
. Ajoutez un accesseur pour chacun des deux attributs.
. explore(List<Explorer> explorers) : lors de l’exploration d’une tuile tré-
sor, les rubis trouvés par les explorateurs sont partagés entre ceux-ci de manière
équitable. Les rubis non distribués sont laissés sur place.
Attribut
. Treasure lastDiscoveredTreasure : dernière tuile trésor découverte.
Constructeurs
. Cave() : vide.
Méthodes
. Un accesseur pour l’attribut lastDiscoveredTreasure ;
. discoverNewTreasure(List<Explorer> explorers) : fait découvrir aux ex-
plorateurs passés en paramètre une nouvelle salle aux trésors. Les richesses
disposées sur celle-ci sont partagées équitablement.
Allez ! On vous le rappelle encore une fois : vous devez faire des commits réguliers.
La classe Game est la classe qui assemble tous les éléments du jeu déjà codés. Elle
agit comme une façade 8 c’est-à-dire que c’est uniquement avec cette classe que la
vue va interagir pour faire évoluer le jeu, sans appeler directement les autres classes
du modèle.
Interface L’interface 9 Model définit les méthodes que doit fournir la façade Game.
Elle agit comme une sorte de contrat. Le voici :
1 public interface Model {
2 void addExplorer(Explorer explorer);
3 void moveForward();
4 boolean isOver();
5 Cave getCave();
6 List<Explorer> getExplorers();
7 List<Explorer> getExploringExplorers();
8 void handleExplorerDecisionToLeave(Explorer explorer);
9 }
Ce code est présent sur poÉsi (vous devrez adapter le nom du package). Nous vous
invitons à lire la javadoc fournie pour comprendre ce que doivent faire les méthodes.
Celles de la forme get... sont là pour permettre à la vue d’interroger l’état du jeu
afin de donner des informations pertinentes à l’utilisateur. Les autres font évoluer le
jeu.
Constructeurs
. Game() : Ce constructeur permet de créer le jeu et d’instancier les attributs.
Au début du jeu, il n’y a pas encore d’explorateurs ; ils devront s’inscrire par
la suite.
Méthodes. Vous devez coder toutes les méthodes imposées par l’interface. Faites
bien attention à ce que vos méthodes vérifient et imposent le respect des règles.
8. https://en.wikipedia.org/wiki/Facade_pattern
9. Au sens Java, pas en tant qu’interface utilisateur
3.2 La vue
Attribut
. Scanner in : permet d’obtenir les informations des utilisateurs.
. Model game : instance du jeu à afficher avec lequel l’utilisateur va interagir.
Constructeurs
. View(Model game) : permet d’initialiser les attributs de la classe.
Méthodes
. Explorer askExplorer() : instancie un explorateur sur base d’un pseudonyme
demandé à l’utilisateur.
. boolean isThereNewExplorerToAdd() : permet de demander à l’utilisateur
s’il y a encore un explorateur à ajouter.
. boolean askExplorerChoiceToContinue(Explorer explorer) : permet de
demander, pour chaque explorateur, s’il désire ou non continuer l’exploration.
. void displayGame() : permet d’afficher l’état du jeu. Ceci comprend la der-
nière tuile trésor explorée ainsi que chacun des explorateurs.
. displayEnd() : permet d’afficher à l’utilisateur que le jeu est terminé et d’af-
ficher les explorateurs.
Attribut
. Model game : l’instance du jeu à piloter
. View view : la vue du jeu.
Constructeur
. Controller(Model game, View view)
Méthodes
. void startGame() : permet de démarrer une partie du jeu.
1. Les explorateurs doivent être ajoutés dans le jeu ;
2. tant que le jeu n’est pas terminé , une nouvelle salle aux trésors est explorée
et les explorateurs présents peuvent décider de rester ou partir ;
3. une fois terminé, la fin du jeu est affichée.
3.5 V0.1
Félicitations, vous avez développé une version allégée du jeu « Diamant ». Vérifiez
les points suivants :
. Tous les tests passent avec succès ?
. Votre jeu tourne convenablement ?
. Votre code est documenté et lisible ?
Si tous ces points sont vérifiés, vous pouvez envoyer votre projet à votre professeur
pour qu’il puisse faire un retour dans les meilleurs délais.
Astuce Netbeans
[Alt][Shift]F permet de mettre correctement le code en forme.
Si des lignes sont sélectionnées, c’est le bloc qui est reformaté sinon,
c’est toute la classe. Plus d’excuse d’avoir un code mal indenté.
Maintenant que la première partie est fonctionnelle, nous pouvons ajouter les fonc-
tionnalités une à une. À chaque fois que l’une de ces fonctionnalités est ajoutée, nous
marquerons l’avancée du projet par un tag correspondant à une nouvelle version.
. V0.1.1 - Amélioration de la gestion des erreurs ;
. V0.1.2 - 3 à 8 joueurs ;
. V0.1.3 - Désignation du vainqueur ;
. V 0.1.4 - Gestion du retour des explorateurs ;
. V 0.1.5 - Ajout des 5 entrées dans la grotte ;
. V 0.1.6 - Gestion du paquet de tuiles ;
. V 0.1.7 - Ajout des tuiles danger ;
. V 0.2 - Fuite des explorateurs.
Prêtez toujours une attention particulière à la robustesse de votre code. Veillez à
documenter et à tester (tests unitaires) vos méthodes et classes.
Cette modification a pour but d’améliorer la gestion des exceptions présente et futur.
Nous vous demandons d’ajouter la classe GameException. Cette classe hérite de la
classe RuntimeException.
Dans la classe Model, il est indiqué qu’une exception de type RuntimeException doit
être lancée par la méthode handleExplorerDecisionToLeave si l’appel se fait avec
un explorateur qui ne fait pas partie de l’instance Game courante. Modifiez cela et
indiquez que l’exception lancée doit être de type GameException. Modifiez la classe
Game en conséquence afin de respecter votre interface.
Astuce Netbeans
Netbeans permet de générer très rapidement une exception — une
classe héritant de Exception — et réécrivant deux constructeurs. Pour
ce faire,
Nous allons maintenant limiter le nombre de joueurs afin de respecter les règles du
jeu. Dans celles-ci, le nombre de joueurs doit être compris entre 3 et 8 joueurs.
Dans le contrôleur, utilisez les nouveaux éléments disponibles afin de démarrer une
partie avec le bon nombre d’explorateurs. Réfléchissez afin d’éviter de faire des de-
Dans cette section, nous détaillons les modifications nécessaires afin de permettre
la désignation d’un vainqueur. L’explorateur qui gagne une partie est celui ayant
récolté le plus de rubis.
Astuce Netbeans
Parfois il manque des import, parfois il y en a trop parce que l’on utilise
une classe à un moment et, plus tard, on décide de ne plus l’utiliser.
Netbeans peut vérifier la liste des import, ajouter les manquants et sup-
primer les inutiles.
[Ctrl][Shift]I ou Source / Fix import dans le menu.
10. Voir section 1.8.3. Pensez au clic-droit/Refactor/Rename... pour le faire simplement en mini-
misant le risque d’erreur.
Attention, le partage des tuiles est ici simplifié par rapport aux règles du jeu. Les
rubis non partagés restent sur la tuile où ils sont apparus.
Dans l’algorithme de votre contrôleur, après avoir demandé aux explorateurs s’ils
souhaitent quitter, appelez la méthode makeExplorerLeave().
Dans le but de faire des tests unitaires plus complets, ajoutez à la classe Cave,
la méthode addTreasureToPath(Treasure treasure) ; celle-ci ne sera pas appelée
par une classe en dehors des classes de tests. Dès lors, sa visibilité peut être package.
Rappel :
. N’oubliez pas de tester, documenter et faire des commits/pushs réguliers de
votre code source.
. N’oubliez pas d’amender les méthodes toString(), equals() lorsque cela est né-
cessaire.
Dans les règles du jeu, la grotte est constituée de 5 entrées. Ce que nous considérions
jusqu’à maintenant comme une grotte n’est en réalité qu’une seule de ses entrées.
Pour la suite, nous parlons de phase d’exploration ou encore de phase de jeu. Une
phase d’exploration représente la période dans le jeu qui démarre dès qu’une entrée
est ouverte et qui se termine lorsque l’entrée est condamnée. Nous parlons également
de tour. Un tour représente la découverte d’une nouvelle salle aux trésors, de son
partage, et de la prise en considération du choix des joueurs de continuer ou de
stopper l’exploration.
11. Ceux dans l’état LEAVING.
Attributs
. private int nbExploredEntrance : représente le nombre d’entrées explorées.
Une entrée est explorée lorsqu’elle est condamnée (locked).
. private CaveEntrance currentEntrance : représente la dernière entrée ou-
verte. Nous ne retiendrons que celle là !
Constructeur
. Cave() : initialise l’attribut nbExploredEntrance à 0.
Méthodes
. ajoutez les accesseurs des attributs nbExploredEntrance et currentEntrance.
. boolean hasNewEntranceToExplore() : retourne vrai si moins de 5 entrées
ont été explorées ;
. openNewEntrance() : permet d’ouvrir une nouvelle entrée de la grotte. Une
exception est lancée si la précédente phase de jeu n’est pas terminée 13 . Une
exception sera aussi lancée s’il y a une tentative d’ouvrir plus de 5 entrées ;
. lockOutCurrentEntrance() : permet de condamner l’entrée courante de la
grotte et d’incrémenter le nombre de grottes explorées. Une exception est lancée
si une phase de jeu n’est pas en cours ;
Attention, suite au refactoring, certaines classes ont été modifiées alors qu’elles
ne le devaient pas.
. Dans Model, la méthode CaveEntrance getCave() doit être renommée en Cave
getCave().
. Dans Game, l’attribut de type CaveEntrance doit être de type Cave ce qui
implique quelques adaptations :
12. Ne le faites pas à la main ; utilisez l’outil de refactorisation de Netbeans
(clic-droit/Refactor/Rename...).
13. C’est-à-dire, s’il y a une entrée qui a été ouverte précédemment et que celle-ci n’a pas été
condamnée.
Cette itération vise à respecter la règle des 15 tuiles trésors par l’utilisation d’un
paquet de tuiles trésors. Ce paquet de tuiles doit permettre de :
. générer les 15 tuiles trésors ;
. piocher une tuile trésor ;
. réinitialiser les tuiles.
Nous allons créer la classe Deck afin de représenter notre paquet de tuiles.
Attributs
. List<Treasure> tiles : représentera la liste des tuiles trésors.
Constructeur
. Deck() : permet d’initialiser la liste des tuiles trésors. Intialement, le paquet
contient 15 tuiles trésors de valeur : {1, 2, 3, 4, 5, 5, 7, 7, 9, 11, 11, 13, 14, 15, 17}.
Méthodes
. getTreasure() : permet de retourner une carte au hasard parmi la liste de
tuiles.
. putBack(Treasure treasure) : permet de replacer une carte dans le paquet.
Dans la classe Treasure, ajoutez une méthode restore() qui réinitialise la valeur
du trésor à sa valeur initiale.
Dans la classe Cave, ajoutez un attribut Deck ainsi que son accesseur.
Dans la classe CaveEntrance nous avons besoin d’utiliser le paquet de tuiles de
la grotte. Ajoutez un attribut de classe Cave cave qui permet à toute entrée de
connaitre la grotte à laquelle elle est associée et ainsi, avoir accès au paquet de la dite
grotte. Initialisez cet attribut dans le constructeur. Modifiez l’implémentation de la
méthode discoverNewTile. Celle-ci ne crée plus une carte aux trésors aléatoirement,
mais la pioche dans le paquet de la grotte. Ajoutez également un accesseur pour le
chemin.
Dans la classe Game, modifiez endExlorationPhase() pour replacer les tuiles de
type Treasure après les avoir restaurées.
Rappel : n’oubliez pas de tester, documenter et faire des commits/pushs réguliers
de votre code source.
Cette itération vise à ajouter les tuiles de type danger. Pour l’instant, nous allons
simplifier les règles et remettre les tuiles dans le paquet à chaque fin de phase.
Commençons par définir les différents types par la création d’une énumération
HazardType avec les valeurs : STONE_BALL, GIANT_SPIDERS, SNAKES, BATTERING_RAM
et LAVA_FIELD.
Créez l’interface Tile
Modifiez la classe Treasure pour indiquer qu’elle implémente l’interface Tile. Spé-
cifiez que la méthode explore de Treasure est une implémentation de celle de l’in-
terface par l’ajout d’un @Override.
Créez une classe Hazard afin de représenter une salle danger. Elle implémente aussi
l’interface Tile.
Attributs
. HazarType type : le type de danger de la tuile.
Méthodes
. L’accesseur de type.
. explore() : cette méthode ne fait rien.
Il est maintenant temps de modifier l’ensemble du code pour ne plus directement
interagir avec des tuiles Treasure.
. Deck : la liste de Treasure devient une liste de Tile. Renommez getTreasure()
en getTile().
. CaveEntrance : l’attribut Path est composé de Tile. Renommez
. lastDiscoveredTreasure() en lastDiscoveredTile() ;
. discoverNewTreasure en discoverNewTile ;
. addTreasureToPath en addTileToPath ;
. getLastDiscoverTreasure en getLastDiscoveredTile.
. Game : dans endExplorationPhase, getPath() retourne une collection de Tile.
Ajoutez une condition pour restaurer la tuile s’il s’agit d’une instance Treasure.
Maintenant que cette modification est faite, nous allons ajouter les tuiles dangers
dans le jeu. Modifiez la classe Deck de manière à ajouter les tuiles de type Hazard.
Pour rappel, 3 occurrences de chaque type de danger doivent être présentes dans le
paquet de tuiles.
Rappel : n’oubliez pas de tester, documenter et faire des commits/pushs réguliers
de votre code source.
Nous allons maintenant provoquer la fuite des explorateurs lorsque deux tuiles d’un
même danger auront été découvertes par ceux-ci lors d’une phase d’exploration.
Dans CaveEntrance,
. ajoutez l’attribut boolean unsafe qui indique si le chemin est toujours sécurisé
ou non.
. modifiez la méthode discoverNewTile(). Quand un danger est pioché, elle
doit vérifier qu’il n’a pas déjà été pioché dans cette entrée de grotte auquel cas
l’entrée est déclarée non sure (unsafe ← true).
Dans Cave,
. ajoutez la méthode isLastEntranceUnsafe() qui retourne vrai si la dernière
entrée est déclarée dangereuse.
Il faut maintenant permettre la fuite des explorateurs. Lors de sa fuite, un explora-
teur perd le contenu de son sac.
. Dans la classe Bag, ajoutez une méthode loseContent() qui va vider le contenu
du sac.
. Dans la classe Explorer, ajoutez la méthode runAway(). Elle vide le sac et lui
fait atteindre le camp.
Dans la classe Game,
. modifiez la méthode moveForward(). Si la grotte est déclarée unsafe après avoir
découvert une nouvelle tuile, les explorateurs en cours d’exploration doivent
prendre la fuite.
. Ajoutez une méthode isExplorationPhaseAborted() qui retourne vrai si l’en-
trée de la grotte en cours d’exploration est déclarée unsafe, faux sinon.
Ajoutez une méthode displayRunAway() qui permet d’avertir les utilisateurs que
l’exploration est terminée.
Dans les règles du jeu, lorsqu’un danger provoque la fuite des explorateurs, il n’est
pas remis dans le paquet de tuiles à la fin de la phase d’exploration. Nous allons
modifier notre code en vue d’implémenter cette règle.
Attention, dans la classe Deck, lors de la création des tuiles dangers, veillez à ce
que chaque tuile soit une instance distincte des autres.
Dans cette section, nous allons commencer le développement visant à ajouter les
tuiles reliques. Nous allons nous contenter ici de rendre notre programme plus orienté
objet en ajoutant une énumération pour les types de gemmes présents dans le jeu.
Ajoutez l’énumération Gem qui contient les deux éléments DIAMOND et RUBY.
Attribut
. final int value : valeur de la gemme. Le diamant a pour valeur 5 et le rubis
a pour valeur 1.
Méthodes
. L’accesseur de l’attribut.
Dans la classe Bag, remplacez l’attribut nbRubies par l’attribut List<Gem> gems
et ajoutez son accesseur. Modifiez le constructeur de sorte à initialiser ce nouvel
attribut. Modifiez addRubies(int nbRubies) en addGem(Gem gem). Remplacez la
méthode getNbRubies() par la méthode int getValue() qui calcule la valeur to-
tale des gemmes contenues dans le sac. Finalement, modifiez également la méthode
loseContent() afin de vider la liste de gemmes.
Dans la classe Explorer, modifiez la méthode addToBag(int nbRubies) en addTo-
Bag(Gem gem). La gemme passée en paramètre doit être placée dans le sac de l’ex-
plorateur. La méthode getFortune() doit être modifiée pour utiliser la méthode
getValue de Bag.
Dans la classe Treasure, renommer la variable initNbRubies en initNbGems. Rem-
placez l’attribut rubies par l’attribut List<Gem> gems. Modifiez le constructeur
pour qu’il y ait initNbGems rubis dans gems. Ajoutez un accesseur pour gems et sup-
primez celui de rubies. Modifiez également les méthodes restore() et explore(...).
Dans cette section, nous allons ajouter la gestion des reliques. Chaque relique aura
la même valeur, nous ferons évoluer la valeur des reliques, telle que définie dans les
règles, dans la section suivante.
Dans cette dernière section réservée à l’ajout de la gestion des reliques, nous allons
faire en sorte qu’à partir de la quatrième relique sortant de la grotte, la valeur des
reliques soit de 2 diamants.
Nous allons ajouter un compteur dans la classe Cave afin de connaitre le nombre
de tuiles reliques enlevées par les explorateurs. Ensuite, nous allons ajouter une
méthode dans la classe Relic afin de permettre la modification de sa valeur.
Dans les règles du jeu, une fois le partage des rubis d’une salle aux trésors réalisé, le
reste est disposé sur une unique tuile afin de partager l’ensemble du reste des rubis
comme un tout.
Dans notre implémentation, nous allons déposer le reste des rubis sur la première
carte trésor découverte lors de la phase de jeu courante. Pour ce faire, il est nécessaire
de pouvoir déplacer les rubis d’une tuile trésor à une autre.
Attributs
. boolean treasureFound : permet de savoir si une carte trésor a déjà été dé-
couverte sur le chemin.
. Treasure firstTreasureTile : est la première tuile trésor découverte sur le
chemin.
Dans le constructeur, initialisez l’attribut treasureFound à faux.
Modifiez la méthode discoverNewTile(), pour modifier les nouveaux attributs
lorsque cela est nécessaire.
Ajoutez la méthode makeLastTileExplored(). Si la dernière tuile du chemin est de
type Treasure, les rubis doivent être déplacés vers la première tuile trésor.
Dans la classe Game, modifiez la méthode makeExplorersLeave() afin d’appeler la
méthode makeLastTileExplored() de CaveEntrance avant tout autre chose.
Nous avons jusqu’à maintenant omis le développement d’un élément important des
règles du jeu. Une fois cet ajout réalisé, nous aurons implémenté toutes les règles du
jeu.
Dans la classe Bag(), modifiez la visibilité de l’attribut gems pour qu’il soit accessible
dans une classe qui hérite de la classe Bag.
Créez une classe Chest() qui hérite de la classe Bag. Faites en sorte que le construc-
teur de la classe mère soit appelée dans celui de la classe fille et ajoutez la méthode
saveBag(Bag bag) qui fait le transfert des gemmes contenues dans le sac vers le
coffre.
Dans la classe Explorer, ajoutez un attribut Chest chest qui doit être instancié
dans le constructeur. Pour finir, ajoutez dans la méthode reachCamp() le transfert
des gemmes du sac vers le coffre.
Modifiez votre vue. Dorénavant, celle-ci ne peut plus comporter d’appel à une mé-
thode toString().
La première phase est terminée. Il est temps de nous remettre une version complète
de votre projet. Nous vous conseillons de faire l’expérience de le cloner sur une autre
machine que celle que vous avez utilisée pour développer afin de vous assurer qu’il
est bien complet.
La phase suivante est la défense ; nous vous demanderons de pouvoir expliquer votre
code et d’être en mesure d’y apporter des modifications.
7 Le mot de la fin
Félicitations d’être arrivé au bout de ce projet. Nous espérons que vous vous êtes
bien amusé et que vous avez appris avec intérêt et motivation.