Aller au contenu

TP 1

Implementation partielle du modele Skyjo.

Meta

  • Date limite: 15 février, 23:59
  • Remise: GitLab
  • Equipes: Triplets d'étudiants, tels qu'annonces en classe
  • Remise en retard: Impossible. Vous serez evalues selon le contenu present sur votre branche main a la date limite

Il est de votre responsabilite de remettre le code a temps. N'attendez pas a la derniere minute, GitLab peut echouer.

Objectifs d'apprentissage

Dans ce TP, vous acquerrez une experience pratique de l'utilisation d'une configuration de systeme de build Maven fournie, d'un depot Maven tiers, d'interfaces fournies et de tests fournis. Vous pratiquerez le développement en environnement existant (brownfield development), c'est-a-dire la creation d'une solution qui s'integre a un logiciel existant, en implémentant des classes de solution qui respectent les interfaces fournies et qui passent les tests fournis.

Contexte

Skyjo, en tant que jeu de cartes, se prête parfaitement au patron MVC, c'est-a-dire qu'une implementation correspondante se compose de trois packages: Modele, Vue et Contrôleur.

  • Modèle: représente l'etat, mais n'offre aucune protection, c'est-a-dire que toute personne ayant accès au modele peut manipuler l'etat dans n'importe quelle direction, y compris effectuer des changements qui violent les règles du jeu.
  • Contrôleur: sert de proxy pour modifier l'etat du modele de manière controlee, c'est-a-dire en respectant les regles du jeu.
  • Vue: affiche l'etat du modele et les options du joueur, et transmet les actions du joueur au contrôleur.

La vue a un accès limite au modele

Le principe meme du MVC est de proteger l'etat du modele contre des modifications illegales. Cela inclut la vue. La vue ne doit jamais avoir un acces direct en ecriture au modele et doit plutot passer par le controleur. Pour faire respecter ce principe, la vue ne connait le modele que par son interface en lecture seule.

  • Tout au long de la session, vous allez implementer les composants Modele et Contrôleur du jeu de cartes Skyjo. La vue est entièrement fournie.
  • Dans ce TP, il vous est demande de realiser la creation du "modele par défaut" ainsi que l'accès en lecture au modele.
  • Vous remarquerez que les artefacts fournis contiennent deux interfaces de modele:
    • Une pour l'accés en lecture
    • Une pour l'accés en écriture
  • Dans ce TP, nous nous intéressons uniquement aux methodes des interfaces en lecture seule. Vous pouvez laisser toutes les méthodes d'écriture vides ou sous forme de stubs - elles ne seront pas testees.

Le modele par défaut fait reference a un etat de modele de test initial qui ne représente aucune forme d'aléatoire, c'est-a-dire:

  • Les noms des joueurs sont codes en dur comme suit:
    1. "Max"
    2. "Ryan"
    3. "Maram"
    4. "Quentin"
  • Initialement, toutes les cartes sont placées sur la pile, de la plus basse a la plus elevee:
    • Les cartes les plus basses dans la pile sont les -2.
    • Les cartes tout en haut de la pile sont les 12.
  • Ensuite, les cartes sont distribuées aux joueurs:
    • Un joueur a la fois.
    • De haut a gauche vers le bas a droite, ligne par ligne.
  • Finalement, une seule carte est révélée à partir de la pile de cartes fraiches et placée sur la pile de défausse.

La construction du modele par défaut est déterministe, c'est-a-dire que, peu importe la manière dont vous implementez la creation du modele, une fois que vous affichez votre modele avec la vue fournie, vous devez voir ceci:

Round:            1
Deck   (101):  [??]
Discard ( 1):  [ 8]
Cache:         [--]

MAX  (23)             Ryan  (21)            Maram  (19)           Quentin  (17)         
[12] [??] [??] [??]   [11] [??] [??] [??]   [10] [??] [??] [??]   [ 9] [??] [??] [??]   
[??] [??] [??] [??]   [??] [??] [??] [??]   [??] [??] [??] [??]   [??] [??] [??] [??]   
[??] [??] [??] [11]   [??] [??] [??] [10]   [??] [??] [??] [ 9]   [??] [??] [??] [ 8]   

Ne reinventez pas la roue

L'objectif de ce TP est moins de developper beaucoup de nouveau code que de s'integrer aux artefacts fournis. Ceux-ci contiennent plus que de simples interfaces, par exemple une implementation de Stack qui peut etre utilisee telle quelle. Ne reinventez pas la roue - familiarisez-vous avec les artefacts fournis et leur fonctionnement en lisant leur documentation avant de commencer a coder.

Mise en place du projet

  • Ne creez pas un nouveau projet - acceptez l'invitation GitLab (envoyee par courriel) des que vous la recevez.
  • Utilisez la commande git clone https://gitlab.info.uqam.ca/inf2050/2026-hiver/skyjoXX.git pour telecharger une copie, ou XX est votre numero d'equipe.

Ne modifiez pas la structure du projet

Ne supprimez pas, ne renommez pas et ne modifiez aucune partie de la structure fournie. Vous devez uniquement ajouter de nouveaux fichiers. Si vous modifiez la structure du projet ou les fichiers fournis, il est presque certain que votre projet ne pourra pas etre evalue et que vous ne recevrez aucun retour.

Implementation

  • Vous pouvez utiliser IntelliJ pour developper votre code, mais votre code sera teste en ligne de commande, en utilisant la commande maven.
    • D'autres IDE peuvent etre utilises, mais ne sont pas recommandes. Plus tard dans ce cours, vous aurez besoin de fonctionnalites specifiques a IntelliJ.
    • Il est fortement recommande de tester votre code en ligne de commande avant la remise, puisque c'est de cette maniere que votre solution sera evaluee.
  • Verifiez attentivement votre version de java et de maven. Si elles ne correspondent pas, il est probable que votre programme ne se comporte pas correctement lors de l'evaluation.

Dependances

Le projet doit etre configure pour utiliser les interfaces java fournies, les classes utilitaires et les tests comme dependances maven.

  • Definition du depot tiers:
<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>

Ceci n’est pas un lien vers une page web. Il est normal de voir une page vide ou une erreur si vous le copiez-collez dans votre navigateur.

  • Interfaces et classes utilitaires fournies:
<dependency>
    <groupId>ca.uqam.info.max</groupId>
    <artifactId>skyjo-interfaces</artifactId>
    <version>tp1-01</version>
</dependency>

Code source et documentation fournies pour votre commodite.

  • Tests abstraits fournis:
<dependency>
    <groupId>ca.uqam.info.max</groupId>
    <artifactId>skyjo-tests</artifactId>
    <version>tp1-01</version>
    <scope>test</scope>
</dependency>

Code source fourni pour votre commodite.

Rappel

A part les deux dependances autorisees et le depot tiers, ne faites aucun changement au fichier pom.xml. Pour ce TP, votre remise ne sera pas evaluee si vous ajoutez des bibliotheques, des plugins, etc.

Classes d'implementation

Vous devez fournir une implementation des classes suivantes pour votre nouveau package source modele. Vos classes * doivent* implementer les interfaces fournies.

Construisez une solution selon les exigences fournies, pas l'inverse

Votre code doit respecter les interfaces fournies. Il vous est interdit de modifier, ignorer ou remplacer les interfaces.

Aperçu des interfaces:

Qu'en est-il de la factory

Vous remarquerez aussi une interface de controleur fournie: une factory pour creer des objets modele. Pourquoi est-elle incluse ? Essentiellement, en implementant cette interface vous pouvez reduire la quantite de code dans votre classe Modele. L'idee est de garder le constructeur model libre de trop de logique, et de laisser la factory faire le travail principal. La factory jouera un role plus important dans les TPs suivants, donc c'est un choix strategique de placer autant de logique de creation de modele que possible dans la classe factory.

Classes de test

  • Pour l'instant, vous n'êtes pas oblige de créer vos propres tests.
  • Cependant, votre solution sera testee avec une serie de tests predetermines, qui servent aussi de guide pour implementer votre solution.
  • Pour activer ces tests, il suffit de les etendre:
    • Tous vos tests vont dans les sous-repertoires src/test/... (ne pas melanger avec le code de production)
    • Les tests fournis sont tous abstraits, c'est-a-dire qu'ils ne testent rien tant que vous ne les etendez pas
    • Etendre les tests est aussi simple que de creer une nouvelle classe dans votre repertoire src/test/.../model, en utilisant la syntaxe class YourTest extends AbstractProvidedTest.
    • Vous n'aurez besoin de definir qu'une seule methode, qui fournit une instance de ce qui doit être teste a la classe abstraite.
  • Votre solution ne peut pas être testee si vous n'étendez pas les tests fournis.
    • Intuitivement, cela peut sembler bien: apres tout, pas de tests = rien ne peut échouer
    • En réalite, éviter les tests est un no-go en genie logiciel: Non teste == l'auteur ne peut pas assumer la résponsabilite de son code == le client ne paiera pas.
    • Les remises qui n'implémentent pas toutes les classes de tests abstraites fournies sont considerées en dessous de l'acceptable, c'est-a-dire qu'elles ne recoivent aucun retour au-dela de "0 points".
C'est un peu complique, pourquoi dois-je encore etendre une classe abstraite ?

Les classes de tests fournies testent contre les interfaces fournies, c'est-a-dire qu'elles verifient si ce que vous avez implementé respecte le comportement attendu. Malheureusement, les interfaces ne peuvent pas definir de constructeurs, donc nous avons besoin d'un mecanisme additionnel pour acceder a ce qui doit etre teste. C'est la methode imposee par la classe abstraite.

Configuration du lanceur

  • Le projet initialisé contient un lanceur.
  • Il ne compilera pas et ne s'exécutera pas. C'est normal, il appelle la partie que vous devez encore développer.
  • Ne modifiez pas le lanceur, il est correct tel quel. Construisez votre solution pour qu'elle fonctionne avec le lanceur fourni.
  • Le projet est configuré pour s'exécuter seulement une fois que tous les tests passent:
    • Exécutez votre code avec: mvn clean package exec:java
    • Alternativement, construisez un jar autonome et lancez-le avec: mvn clean package; java -jar target skyjo.jar
package ca.uqam.info.max.skyjo.view;

import ca.uqam.info.student.skyjo.controller.ModelFactoryImpl;
import ca.uqam.info.max.skyjo.controller.ModelPreset;
import ca.uqam.info.max.skyjo.model.SkyjoModelReadOnly;

/**
 * Launcher for TP1. You may edit SkyjoModelImpl constructor, but the rest should not be touched,
 * to ensure compatibility with upcoming TPs.
 *
 * @author Maximilian Schiedermeier
 */
public class LauncherTp1 {

  /**
   * Default constructor, as imposed by javadoc.
   */
  public LauncherTp1() {
  }

  /**
   * Main method, starting up TP1 code.
   *
   * @param args not used.
   */
  public static void main(String[] args) {

    // Create a model, using your model constructor.
    // Make sure your model implements the provided model readonly interface
    String[] playerNames = new String[] {"Max", "Ryan", "Maram", "Quentin"};

    /*
     This next line requires YOUR implementation of a ModelFactory to work.
     Make sure the returned model implements the SkyjoModelReadOnly interface and is a default
     model. See handout for definition of what a default model is.
     */
    SkyjoModelReadOnly model =
        new ModelFactoryImpl().createModel(ModelPreset.DEFAULT, playerNames, null);

    // Test model printing (you do not need to implement anything for this part to work, all view
    // concerns are provided).
    // If you're on windows, please set ttyColours to false, because
    // windows does not support them reliably:
    boolean useTtyColours = true;
    TextualVisualizer visualizer = new TextualVisualizer(model, useTtyColours);
    visualizer.refresh();
  }
}

Programmation en equipe

  • Pour les prochains TPs, vous developperez sur plusieurs machines en parallele et fusionnerez votre code avec git.
  • Pour l'instant, je recommande la programmation en equipe :
    • Devéloppez ensemble devant une seule machine ou en utilisant la programmation virtuelle en equipe. Une personne code, les deux autres aident mais ne touchent pas au clavier.
    • Changez de place toutes les 15 minutes.
  • Si vous ne pouvez pas vous rencontrer physiquement : Utilisez la fonction code-with-me d'IntelliJ
    • Cette fonctionnalité n'est incluse que dans la version ultimate. (Voir les instructions d'installation dans le premier cours.)
  • Si vous voulez vraiment alterner les machines :
    • Poussez tout sur la premiere machine (git add .; git commit -m "..."; git push)
    • Tirez tout sur la deuxième machine (git pull)

DIVERS

Desordre

  • Gardez votre depot sans désordre. (Voir TP0)
  • Ne commitez pas de fichiers binaires ou generes (.class, dossier target, javadoc genèré)
  • N'incluez aucune instruction System.out.println dans votre code, cela cassera la fonctionnalité dans les prochaines étapes du TP et rendra la sortie de la vue moins jolie.
  • N'incluez aucune bibliotheque tierce / il ne doit y avoir aucune dependance supplémentaire dans votre projet, au delà de ce qui est demandé.

Tricherie et aide

Obtenir de l'aide legitime :

  • Si vous avez bien lu le document, participe a la presentation du TP en classe, et que quelque chose reste flou :
    • Demandez sur Mattermost.
  • Si vous suspectez un probleme, par ex. un test fourni, une documentation, etc.
    • Demandez sur Mattermost.

Si vous bloquez en programmation :

  • Vous pouvez consulter Internet pour trouver de l'inspiration ou mieux comprendre, mais il est recommande de ne jamais copier-coller du code sans le comprendre complétement et citer la source originale. Il est aussi recommande de toujours fournir une reference / commentaire vers la source originale :
    • Le copier-coller est rarement votre ami si vous etes responsable de votre code.
    • Utilisez un commentaire Java // ... pour fournir la source, par ex. le post exact sur StackOverflow.
  • Merci de ne pas partager votre code avec d'autres équipes, cela nuit a leur apprentissage.
    • Vous pouvez discuter des idees, dessiner des concepts sur papier, mais ne jamais passer du code.

Tricherie :

  • Ce TP est votre preparation a l'examen.
  • Les retours que je fournis indiquent a quel point vous avez compris les concepts pertinents pour l'examen.
  • Plus vous vous investissez, plus vous obtiendrez de points a l'examen.
  • Utiliser une IA generative pour produire du code nuit presque certainement a votre comprehension.
  • Je vous recommande de ne pas vous tricher vous-meme, mais je ne vous empecherai pas non plus.

Tableau

Item Criteres Pourcentage max
1 Tests fournis passent 60%
2 Depot tiers et dependances ok (pom) 15%
3 mvn clean package passe, jar fonctionne 15%
4 Pas de desordre dans le depot 10%

Rejet automatique

Voici encore la checklist de ce qu'il faut éviter si vous voulez un retour sur la qualité de votre travail. Si au moins un item de la checklist s'applique, votre remise sera rejetee automatiquement. D'autres critères de rejet peuvent exister.

  • Solution non fournie dans le repertoire GitLab dédie.
  • Le depot contient un fichier zip ou un autre fichier binaire au lieu du code.
  • Le code ne compile pas avec la commande maven fournie.
  • Les classes fournies n'implémentent pas les interfaces fournies.
  • Structure du projet non respectée.
  • Implementation des classes de test abstraites non fournie dans le package test.
  • pom.xml a ete modifie, autre que le depot tiers et les deux dépendances fournies.
  • Le programme tente une communication réseau a l'exécution.
  • Le programme tente d'accéder au systeme de fichiers.
  • Le programme se bloque a l'exécution.