DS sokoban_v4

Transcription

DS sokoban_v4
DUT 2A
2012-2013
26/10/2012
DS cpt JAVA
Durée: 2 heures.
Documents (notes et polycopiés) autorisés
La rigueur et la propreté seront prises en compte dans l'évaluation.
Les questions posées sont en grande partie indépendantes les unes des autres. Vous
penserez à garder les mêmes noms pour les méthodes et les attributs. Pour plus de
facilité dans l'écriture, les attributs sont supposés public.
Vous pouvez commenter votre code dès que vous jugerez utiles certaines explications.
Dans ce DS, on souhaite modéliser un jeu de type Sokoban. Il s'agit d'un jeu vidéo à base de Puzzle
inventé au Japon. Dans ce jeu, le joueur contrôle un personnage qui se déplace dans un entrepôt. Cet
entrepôt contient plusieurs caisses et le personnage doit les amener à leur destination en les
poussant au cours de son déplacement. La difficulté réside dans le fait que le personnage ne peut
pas tirer les caisses et peut donc se retrouver bloqué quand les caisses se trouvent devant un
obstacle (que ce soit un mur ou une autre caisse).
Personnage
Caisses
Destination
Ce sujet vous propose
• dans un premier temps d'établir les bases de test permettant de vérifier que le jeu fonctionne
correctement (partie 2) ;
• dans un second temps, de modéliser le jeu en complétant des classes fournies (partie 3) ;
• puis dans une troisième étape de structurer votre application à l'aide d'une approche MVC
(partie 4).
1 – Présentation des classes de Jeu
Le premier objectif de ce sujet va consister à examiner le squelette des classes de Jeu fournies (cf
annexes 1 et 2).
1/5
Le package game fourni contient deux classes :
•
•
la classe Point qui a pour objectif de représenter des positions dans l’entrepôt ;
la classe Entrepot qui décrit l’entrepôt à un instant donné.
La classe Point
Cette classe contient deux attributs x et y correspondant à une position dans l'entrepôt. La classe
Point a pour objectif de gérer facilement des coordonnées. Ses attributs sont déclarés en public
pour simplifier l'utilisation de la classe (cf annexe 1).
La classe Entrepôt
La classe Entrepot a pour objectif de représenter la situation du jeu (cf annexe 2). Cette classe
est caractérisée par plusieurs attributs
•
un attribut laby qui décrit la configuration de l’entrepôt. laby est un tableau à deux
dimensions d'entiers. La case du tableau d'indice [i][j] correspond au contenu de la position
(i,j) de l'entrepôt. Elle prend ses valeurs parmi les constantes entières MUR (quand il y a un
mur sur la case), VID (quand la case est vide) et CAI (quand la case contient une caisse);
•
un attribut heros de type Point qui décrit la position du héros dans l’entrepôt;
•
un tableau destination de Point correspondant aux différents lieux de destination des
caisses.
La classe Entrepot propose aussi plusieurs méthodes
•
un constructeur vide donné qui construit un entrepôt initial.
•
une méthode donnée int[] nextPos(int direction) qui fournit les variations de
coordonnées de la case de destination en fonction de la direction passée en paramètre (un
entier correspondant à une des constantes NORD, SUD, EST ou OUEST). Cette méthode
permet de construire facilement les coordonnées de la case de destination en fonction d'une
direction donnée.
◦ Par exemple, pour la direction Nord, la méthode nextPos retourne (0,-1) et la case à
laquelle on arrive en partant de la case (8,10) et en suivant la direction Nord sera
(8+0,10-1) = (8,9) .
Plusieurs méthodes à compléter
◦ une méthode deplacePJ destinée à déplacer le personnage (et les caisses de l’entrepôt
que le personnage parviendra à pousser) en fonction de la position du personnage et de
la direction de son déplacement.
•
◦ une méthode fin qui détecte la fin du jeu et retourne un booléen. Ce booléen vaut vrai
si et seulement si toutes les caisses du labyrinthe sont sur un point de destination.
Ces méthodes seront à compléter dans la partie 3. La première étape du DS va consister à bâtir des
tests.
2- Classe Test
Validité d'un niveau
On souhaite vérifier que le niveau est un niveau valide. Pour cela, il faut vérifier à chaque instance
de jeu que le nombre de caisses d'un niveau correspond effectivement au nombre de destinations.
2/5
Q1 - Pensez vous plutôt utiliser un test unitaire ou une assertion ? Expliquez la différence et
justifiez.
Q2 - Écrivez le test / l'assertion correspondante et précisez où et comment l'insérer dans les classes
fournies.
Validité de la méthode deplacerPersonnage
Lorsqu'un personnage se déplace dans une direction donnée, plusieurs cas peuvent se produire. Il
peut se déplacer sans problème si la case de destination est vide. Si un mur se trouve devant lui, le
personnage ne peut pas se déplacer. Enfin, si une caisse est devant lui, il avance et pousse la caisse
sauf si un obstacle l'en empêche (un mur ou une autre caisse). Si le déplacement de la caisse n'est
pas possible le personnage ne peut pas avancer et rien n'est déplacé.
On ne s’intéressera qu'aux déplacements vers la direction NORD, les autres déplacements étant
supposés gérés de manière analogue.
Nous allons tout d'abord nous intéresser au moyen de vérifier le bon comportement de la méthode
déplacer à l'aide de tests unitaires.
Q3 – Écrivez le test correspondant au cas où le héros avance vers une case vide en prenant soin de
vérifier toutes les conséquences de l'action effectuée.
Vous déclarerez la classe de test et y insérerez la méthode de test.
Q4 – Décrivez les tests unitaires permettant de vérifier les autres cas qui pourraient se produire pour
la méthode deplacePJ. Désormais, on ne demande plus d’écrire les tests en java, mais de décrire
rapidement (un dessin ou une ligne peuvent suffire) les différentes situations à tester et les résultats
attendus à vérifier.
Tests à l'exécution
On souhaite vérifier à l’exécution que le programme fonctionne correctement et que le personnage
ne se trouve jamais à la même position qu'un mur ou qu'une caisse.
Q5 - Écrire l'assertion correspondante.
Q6 – Où cette assertion doit-elle être placée dans le programme (éventuellement à plusieurs
endroits)? (Précisez le nom de la classe et les lignes). Justifiez en quelques mots votre réponse.
3 - Construction classe Entrepôt
En pensant aux réponses données aux questions précédentes, complétez la classe Entrepot.
Q7 - Écrire la méthode fin() qui permet de tester la fin de partie. Cette méthode renvoie vrai si
et seulement si chaque caisse est placée sur une case de destination – on supposera qu'il y a bien un
nombre de caisses égal au nombre de destinations (assuré par votre réponse à la question 2).
Q8 - Écrire la méthode déplacerPj() qui permet de déplacer un personnage en utilisant la
méthode direct et en prenant en compte les différents cas qui peuvent se présenter.
4 - Modèle-Vue-Controleur
Cette partie va consister à greffer une interface graphique et un contrôleur pour permettre de jouer
avec le clavier. L'application sera structurée selon une approche MVC.
3/5
Modèle
Q9 – Quelle classe constitue le Modèle ? La classe Point doit-elle hériter de Observable ? La
classe Entrepot doit-elle hériter de Observable ? Justifiez vos réponses
Q10 - Indépendamment de la vue, comment faut-il modifier le modèle pour que les vues se mettent
correctement à jour ? Où doivent se faire ces modifications dans le code qui vous a été fourni ?
Vue
Dans un package vue, on souhaite développer une vue graphique héritant d'un JPanel. Le début
de la classe vous est fourni en Annexe (cf annexe 4). On souhaite que le constructeur de la classe
VueGraphique gère entièrement le lien entre le modèle et la vue.
le main (cf annexe 3) doit s'écrire de la manière suivante et n'est pas modifiable.
package main;
import game.Entrepot;
import vue.Controleur;
import vue.VueGraphique;
public class Principale {
public static void main(String[] args) {
//creation de l'entrepot
Entrepot j=new Entrepot();
//creation et ajout de la vue
VueGraphique vg=new VueGraphique(j);
//recuperation du controleur associé
Controleur c=vg.getControleur();
//activation du controleur
c.active();
}
}
Q11 - Écrivez le constructeur de la classe VueGraphique qui créé la JFrame, l'affiche et fait le
lien avec le modèle.
Q12 – Écrivez le contenu de la méthode update de la classe VueGraphique.
Controleur
On souhaite pouvoir gérer plusieurs Contrôleurs selon le même modèle.
Pour cela on propose l'interface Controleur avec la méthode abstraite void active() qui
active le contrôleur. Cette méthode active() aura bien entendu un fonctionnement différent en
fonction du type de contrôleur (cf annexe 5).
Q13 - Écrire une classe CText qui implémente Controleur, qui demande lorsqu'elle est
activée un entier correspondant à la direction souhaitée du personnage et qui déplace le personnage.
On fournit la classe CClavier correspondant à Controleur construit à partir d'un
KeyListener(cf annexe 6). On souhaite ajouter une méthode getControleur dans la classe
4/5
VueGraphique. Cette méthode retourne un Controleur en lien avec la vue.
Q14 - Ecrire la méthode getControleur de Vuegraphique qui retourne un contrôleur
CClavier adapté et la méthode active() de CClavier qui ajoute le KeyListener à la
vue.
Lancement
Supposons que toutes vos classes se situent dans un fichier sokoban.jar sans point d’accès et
que les packages correspondent aux packages présentés dans le sujet.
Q15 - Comment lancer l’exécution de la classe Principale située dans le package main ?
5/5

Documents pareils