TP2
Dans ce TP2, on vous demande d’effectuer les tâches suivantes :
- (Finalisez l’implémentation de votre modèle, si ce n’est pas déjà fait)
- Migrez votre projet vers Maven
- Remplacez les copies précédentes des interfaces par une référence à une bibliothèque
- Intégrez le plugin
exec, afin que votre code soit exécutable
- Implémentez un contrôleur pour :
- L’initialisation du modèle (à l’aide d’une
factory) - Le transfert d’état du modèle à l’aide de commandes. Au minimum :
- Retirer une carte de la pile
- Rejeter une carte
- Révéler une carte non divulguée
- L’initialisation du modèle (à l’aide d’une
Pensez au contrôleur comme à un gestionnaire de jeu invisible, qui veille au respect des règles pendant la partie.
Le code est une condition préliminaire à la note
Votre note dépendra de votre capacité à expliquer et à raisonner à propos de votre code soumis, lors de l’examen oral subséquent. Un code fonctionnel est une condition préliminaire pour passer l’examen oral : bien que des fonctionnalités manquantes entraînent une réduction de la note, aucun point n’est accordé uniquement pour le code soumis.
Interfaces
Comme la dernière fois, vous travaillerez avec des interfaces fournies, afin de rester sur la bonne voie.
- La dernière fois, les interfaces étaient fournies sous forme de code.
- Cette fois, elles sont fournies sous forme de bibliothèque Maven, accompagnée d’une documentation en ligne.
Migration vers Maven
Pour le TP2, il vous est demandé de passer d’une structure de projet Java standard à Maven. Concrètement, cela signifie :
- Vous devez ajuster la structure des dossiers.
- Vous devez créer un fichier
pom.xml.
Utilisez un gabarit (template)
Si vous ne savez pas par où commencer, créez un nouveau projet Maven à partir d’un gabarit (vous avez vu la commande au dernier cours), puis copiez les fichiers sources de votre TP1 dans ce projet gabarit. Cela vous fournira également un fichier pom.xml par défaut.
Structure du projet
Comme vu en classe, les projets Maven doivent suivre une structure spécifique.
- Modifiez la structure de votre projet pour qu’elle soit conforme à Maven.
- Créez un fichier
pom.xml - Assurez-vous que le projet compile avec la commande
mvn compile.
Interfaces en tant que bibliothèque
- Pour ce deuxième TP, votre projet ne doit contenir que vos propres classes.
- Autrement dit, vous devez supprimer toutes les interfaces fournies ainsi que le paquet
view. - Ces classes restent néanmoins disponibles pour votre usage ! Pour y accéder sous forme de bibliothèque, utilisez la
configuration suivante :
repositoryindique à Maven où télécharger les interfaces / classes (elles ne sont pas sur les serveurs Maven officiels).dependencyindique à Maven quoi télécharger exactement.
...
<repositories>
<repository>
<id>Max's third party repo on a UQAM GitLab file server</id>
<url>https://max.pages.info.uqam.ca/inf2050repo/</url>
</repository>
</repositories>
<dependencies>
<!-- DO NOT ADD ANY OTHER DEPENDENCIES HERE!-->
<dependency>
<groupId>ca.uqam.info.mgl7010.max</groupId>
<artifactId>skyjo-interfaces</artifactId>
<version>f25-1.0</version>
</dependency>
</dependencies>
...
Plugin Exec
- Par défaut, les projets Maven ne sont pas exécutables (Maven ne peut pas savoir s’il s’agit de programmes ou de bibliothèques).
- Ajoutez le plugin
execà la configuration de votre fichierpom.xmlafin d’ajouter une configuration de lancement. - Faites-le pointer vers le code de lancement TP2 fourni (voir l’exemple de code plus bas), afin qu’il soit exécuté avec
la commande
mvn exec:java.
Contrôleur
Dans le TP précédent, tout votre code se trouvait dans un seul paquet : model.
modelsert uniquement à stocker l’état du jeu.- Dans ce TP2, vous gérez les interactions des joueurs (qui modifient l’état), vous devez donc créer un nouveau
paquet :
controller.
Initialisation du modèle
- Créez une nouvelle classe
LauncherTP2.javadans votre nouveau paquetcontroller. - Utilisez le code d’exemple ci-dessous pour lancer votre logiciel...
- Vous devrez implémenter une nouvelle classe
ControllerImplqui implémente l’interfaceControllerfournie, afin que cela fonctionne. - Assurez-vous que c’est votre
controllerqui gère toute la logique nécessaire pour instancier de nouveaux modèles (controller.initializeModel(ModelPreset.DEFAULT, players)). Cela nécessitera un certain remaniement de votre code du TP1, où vous avez probablement placé toute la logique dans le constructeur de la classe Model. Par logique, on entend par exemple la création du paquet de cartes, le mélange des cartes, etc.
- Vous devrez implémenter une nouvelle classe
public static void main(String[] args) {
// Visual parameters and player names (hard coded for TP2)
boolean useTtyColours = true;
String[] players = new String[] {"Max", "Ryan", "Maram", "Quentin"};
// Initialize a new game
Controller controller = new ControllerImpl();
controller.initializeModel(ModelPreset.DEFAULT, players);
// Register UI to automatically refresh on model updates
CommandSelector controller.addModelObserver(new TextualVisualizer(controller.getModel(), useTtyColours));
// Initialize commandSelector for interactive / TTY mode
commandSelector = new TextualCommandSelector(useTtyColours, false);
// Play the game :)
playUntilGameEnd(controller);
}
/**
* Note: This method is not concerned with updating model state representations, for the model
* adheres to the observer pattern for this purpose.
* This loop is only about retrieving user inputs until game end. The model is automatically
* rendered after each executed command.
*
* @param controller as the MVC controller allowing to progress the game command by command.
* Note that the view has no direct access to the model, and can only
* manipulate model state by executing commands.
*/
private static void playUntilGameEnd(Controller controller) {
// Initialize options for game start
Command[] options = controller.getCurrentPlayerCommands();
// Keep playing until controller offers no more options (game end)
while (options.length > 0) {
// Request a choice from robot / human player
int selectedCommand = commandSelector.selectCommand(options, controller.isUndoAvailable());
// Execute choice (this implicitly re-renders the model)
controller.doCommand(selectedCommand);
// Update options
options = controller.getCurrentPlayerCommands();
}
}
La deuxième méthode implémente la logique du jeu.
- Par défaut, elle utilise l’interface utilisateur textuelle fournie pour demander des choix aux utilisateurs.
- Vous n’avez pas besoin d’implémenter de fonctionnalités d’interface utilisateur, tout est déjà fourni avec la bibliothèque Maven.
Testez en sélectionnant automatiquement la première option
Vous pouvez ignorer les invites utilisateur en choisissant automatiquement la première option (0) comme selectedCommand. Ainsi, votre jeu avancera automatiquement jusqu’à la fin sans interaction humaine, ce qui vous permettra de vérifier votre implémentation.
Transfert d’état du modèle avec des commandes
La boucle de contrôle principale ci-dessus exige que votre ControllerImpl détermine quelles actions de joueur sont
possibles.
- Pour faire avancer le jeu, vous répartirez la logique du jeu sur plusieurs
objets
Command, chaque commande étant un objet qui modifie l’état du jeu. - Vous en apprendrez davantage sur les commandes dans un cours ultérieur. Pour l’instant, il suffit de savoir que chaque commande correspond à une action de joueur.
Pour ce TP2, vous n’avez pas besoin d’implémenter le jeu complet. Il suffit de limiter les actions des joueurs à :
- Prendre une carte de la pile (
RevealFreshCardCommand implements Command) - Rejeter la carte révélée (
RejectCard implements Command) - Révéler une des cartes du joueur encore cachées (
RevealCard implements Command)
Ces commandes sont suffisantes, car la séquence des trois définit un tour de jeu valide.
Ignorez undo
Il n'est pas nécessaire d'implementer undo à ce stade. Vous serez invités à les implémenter plus tard.
Ne vous préoccupez pas des autres commandes
Les commandes ci-dessus suffisent pour jouer une partie valide de Skyjo. Ne vous occupez pas des autres pour le moment, vous serez invités à les implémenter plus tard.
Déclaration de contribution
Incluez un fichier PDF contenant les informations et la déclaration suivantes :
Informations
Pour chaque membre de l’équipe :
- Le pourcentage du travail auquel il ou elle a contribué.
- 2 classes / méthodes pour lesquelles il ou elle se déclare expert désigné.
Déclaration
Incluez cette déclaration dans votre soumission, signez-la à la main, prenez une photo et ajoutez-la à votre soumission.
Nous déclarons par la présente n’avoir utilisé aucune intelligence artificielle générative pour produire le contenu de ce TP, et n’avoir copié aucun code provenant d’autres sources sans en indiquer la provenance dans les commentaires du programme.
Nous comprenons que l’inclusion de contenu généré par IA ou la copie de code étranger sans mention appropriée constitue une faute académique grave qui sera signalée à la commission universitaire du plagiat, ce qui pourrait mener à notre expulsion du programme d’études.
- Signature : ____
- Signature : ____
-
Signature : ____
-
Date : ____
Remise
La remise est prévue pour le vendredi 07-11-2025 samedi 15-11-2025, avant 23h59, par courriel à
schiedermeier.maximilian@uqam.ca.
- Sujet : TP2
- Contenu :
- Un seul fichier ZIP contenant le projet Maven :
pom.xml- Dossier
src
- Déclaration de contribution signée.
- Un seul fichier ZIP contenant le projet Maven :
Ne soumettez pas votre dossier
target.
Réductions de points
Bien que votre note repose sur votre capacité à expliquer votre code, vous pouvez perdre des points (c’est-à-dire que la note maximale sera réduite) si certaines exigences sont ignorées dans votre solution :
Réductions liées à l’implémentation
- Pas de Maven : -100 %, à éviter absolument.
- Pas de contrôleur / 3 commandes de base non implémentées : -100 %, à éviter absolument.
- Aucune déclaration de contribution : -100 %, à éviter absolument.
- Interfaces fournies modifiées ou non utilisées, c’est-à-dire absence de
implements Controller: -100 %, à éviter absolument. - Code ne compilant pas avec
mvn clean compile, version 24 : -100 %, à éviter absolument. - Code qui plante à l’exécution avec
mvn exec:java, version 24 : -100 %, à éviter absolument. - Dépendances supplémentaires non-JDK ou bibliothèques tierces ajoutées (sauf interfaces fournies) : -100 %, à éviter absolument.
- Jeu de cartes non implémenté avec une structure de données propre : -30 %
- État codé en dur / ne change pas au redémarrage : -20 %
- Méthodes du modèle manquantes ou incomplètes : -10 % par méthode manquante ou incomplète.
- Méthodes inutilement complexes : -5 % par méthode dépassant 25 lignes (hors commentaires).
Réductions liées à la remise
- Remise en retard : -30 % dès le dépassement de l’échéance, puis -20 % supplémentaires par 24 h de retard.
- La soumission contient des fichiers inutiles/temporaires ou binaires (
.class) : -5 % par fichier inutile.
DIVERS
Questions
- Pour les questions relatives aux exigences du TP, veuillez utiliser le forum Mattermost.
- Ne partagez pas de code ni de parties de votre solution sur Mattermost.
Suggestions
Bien que cela ne soit pas une exigence stricte ni directement lié à des points bonus, il est toujours bon d’améliorer l’humeur du professeur avec quelques bonnes pratiques :
- Vérifiez votre soumission avant de l’envoyer :
- Envoyez-la d’abord à un membre de l’équipe. Laissez-le extraire le ZIP, compiler le code, etc., sur une autre machine.
- Si tout fonctionne, transférez ensuite le courriel au professeur.
- Formatez votre code : utilisez le formateur de code d’IntelliJ, afin que votre code soit plus lisible.
- Revisitez les laboratoires : certaines parties des solutions de ce TP ont été subtilement couvertes dans les laboratoires. Si vous pensez qu’une solution de labo peut être réutilisée, indiquez-le dans un commentaire dans votre code.
- Commentez votre code : utilisez Javadoc
/** ... */pour les méthodes, et des commentaires réguliers//en ligne.
Habituez-vous aux commentaires et conventions de nommage en anglais
Vous avez le droit de commenter en français, et la langue utilisée pour vos commentaires n’aura absolument aucun impact sur votre note.
Cependant, gardez à l’esprit que l’informatique est une discipline internationale et que, sur le long terme, vous devrez probablement commenter en anglais. Autant vous y habituer tôt.
Même chose pour les noms de variables et de méthodes : adoptez les noms en anglais, cela facilite énormément la collaboration à long terme.
J’ai déjà travaillé dans une équipe internationale où chaque stagiaire ajoutait des commentaires et des noms dans sa langue maternelle : anglais, allemand, français, espagnol, voire chinois. Sans surprise, cela a nui au projet.