Teaching - 2i002 - (TME: sujets)


2i002 : Introduction à la programmation Objet

La pêche aux canards

Des personnes jouent à la pêche aux canards... Il y a plusieurs types de personnes : les joueurs qui pêchent et les animateurs qui ajoutent des animaux dans la mare au fur et à mesure. De la même manière, il y a plusieurs animaux dans la mare: des canards , évidemment, mais aussi des lapins (plus étrangement). Chaque animal vaut un certain nombre de points... Mais certain animaux peuvent aussi faire perdre la partie. Au bout d'un certain nombre de tours, on regarde le total de points des joueurs et on détermine le vainqueur.

Exercice 1 : Les animaux

Question 1 :

Un Animal est un concept abstrait qui possède pour attributs:

  • pts un nombre de points (entier)
  • perdu un booléen qui fait perdre la partie au joueur qui le pêche s'il est à true (quels que soient les autres animaux tirés)
  • representation , une chaine de caractère réduite (3 lettres) permettant de représenter l'animal.

Donner le code de la classe contenant un constructeur à 3 arguments, des accesseurs, une méthode toString() retournant la représentation et une méthode abstraite getType() retournant le type de l'animal en chaine de caractère.

Question 2 :

Le Canard est l'animal de base du jeu. Un compteur cpt permet d'identifier chaque canard par un numéro unique. La représentation du canard est donnée sur 3 caractères de la forme C01 (pour le premier canard), il donne 1, 2 ou 3 points (aléatoirement) et ne fait jamais perdre la partie. Le type associé à la classe est tout simplement "canard" .
Donner le code de la classe Canard .

Rappel pour générer la chaine: String.format("C%02d",cpt)

Question 3 :

Le Lapin est plus vicieux. Il est aussi identifié par un compteur et sa représentation est donnée sur 3 caractères de la forme L01 . Il donne 5 points mais 30% des lapins font perdre la partie (tirer le booléen aléatoirement pour obtenir true dans 30% des cas). Donner le code de la classe Lapin .

Question 4 :

Créer une classe Test et vérifier que vous êtes capables de créer et afficher des animaux.

Exercice 2 : le stand

Représentation d'un stand à 20 cases: 10 cases forment l'arrière boutique, 10 cases constituent la facade. Les animateurs seront à l'arrière pour ajouter des animaux, les joueurs devant pour pêcher les canards. L'ensemble des 20 cases seront gérées dans 1 seul tableau.
Les personnes seront gérées dans une ArrayList .

Question 1 :

[préliminaire] Créer une classe abstraite Personne entièrement vide pour permettre la compilation de la classe Stand dans cet exercice. Les personnes seront complétées dans le prochain exercice.

Question 2 :

Code attributs & constructeur. La classe Stand contient les attributs suivants:

  • personnes : une ArrayList de Personne qui contiendra toutes les personnes intervenants sur le stand,
  • round : un tableau d'Animal dont la taille sera donnée en argument du constructeur,
  • deux entiers indexFront et indexBack permettant de gérer le défilement des animaux en rond.

Le constructeur à 1 argument (la taille de la mare) initialise les attributs ( indexFront =0 et indexBack =taille/2 ) et instancie les tableaux.

NB: durant tout le tme, on veillera à donner une taille paire pour ne pas provoquer de problème. On ne fait pas de test spécifique.

Question 3 :

Code pour la gestion de la mare (qui est en fait plutôt une rivière): afin de faire défiler les animaux devant les joueurs, on a choisi une stratégie de rotation d'indices. Les deux index définis en attributs vont permettre de simuler la rotation. Les méthodes suivantes permettent respectivement de faire avancer la rotation d'une case, de récupérer l'ensemble des indices de la facade et de l'arrière boutique.

    public void avance(){ // avance la rotation d'un cran
        indexFront++;
        indexBack++;
        if (indexBack == round.length)
            indexBack = 0;
        if (indexFront == round.length)
            indexFront = 0;
    }
    private ArrayList<Integer> indexBack(){ // tous les indices de l'arrière boutique (là où les animateurs ajoutent des animaux)
        ArrayList<Integer> index = new ArrayList<Integer>();
        if(indexBack>indexFront){
            for (int i=indexFront-1; i>=0 ; i--)
                index.add(i);
            for (int i=round.length-1; i>= indexBack; i--)
                index.add(i);
        }
        else{
            for (int i=indexFront-1; i>= indexBack; i--)
                index.add(i);
        }
        return index;
    }
    private ArrayList<Integer> indexFront(){ // tous les indices de la facade (là où les joueurs pêchent)
        ArrayList<Integer> index = new ArrayList<Integer>();
        if(indexBack<indexFront){
            for (int i=indexFront; i< round.length; i++)
                index.add(i);
            for (int i=0; i< indexBack; i++)
                index.add(i);
        }
        else{
            for (int i=indexFront; i< indexBack; i++)
                index.add(i);
        }
        return index;
    }

Question 4 :

Coder des méthodes suivantes:

  • ajouterPersonne : ajoute une personne dans personnes
  • ajouterAnimal : ajouter un animal dans la première case disponible (=valeur null ) coté arrière boutique (si toutes les cases sont prises, pas d'ajout)\\ NB: syntaxe élégante pour parcourir les index des cases de l'arrière boutique:
for(int i:indexBack()){ ...  
  • public int getTailleJeuVisible() : retourne la demi-longueur du tableau round
  • public Animal removeAnimal(int i) : dans le tableau round , enlève et retourne l'animal à la position i sur la façade de la boutique, c'est à dire à l'index: (indexFront + i)%round.length
    NB: s'il n'y a pas d'animal dans la case i , retourner null

Question 5 :

Méthode toString() . Après avoir créer une chaine vide, ajouter les représentations des cases de l'arrière boutique sur une ligne (soit la représentation de l'Animal , soit la chaine " . " correspondant à une case vide). Ajouter un saut de ligne, puis les représentations des cases de la façade de la boutique.

Optionnellement, vous pouvez ajouter une mention arrière/avant et un trait de séparation (comme sur la figure ci-dessus) pour mieux se repérer.

Question 6 :

Ajouter les commandes suivantes dans la classe Test pour vérifier le bon fonctionnement de la classe:

  • Création d'un Stand de taille 20.
  • Ajout de 3 Canard et 2 Lapin avec des appels aux fonctions d'affichage et d'avancement pour vérifier que tout se passe bien.

Exercice 3 : Les personnes

Question 1 :

Classe Personne . Reprendre la classe vide et la compléter pour que chaque Personne ait un nom. Chaque classe héritant de Personne devra (contractuellement) avoir une méthode void action(Stand s) qui permettra à la personne d'agir sur le stand.

Question 2 :

Classe Animateur . Un animateur EST UNE Personne construite en donnant son nom et qui a pour attribut une ArrayList<Animal> liste permettant de garder en mémoire tous les Animal qu'il a créé. Son action consiste à:

  • dans la moitié des cas: NE RIEN FAIRE (gérer cela avec Math.random() )
  • le reste du temps: créer un Canard ou un Lapin (80% de canard et 20% de lapin) et l'ajouter sur le stand. Penser également à l'ajouter dans la liste qu'il garde en attribut pour mémoire.
  • S'il crée un animal, l'animateur affiche un message explicite dans la console pour faciliter la compréhension de la simulation (et le débuggage).

L'animateur a une méthode toString() affichant son nom, sa fonction et le nombre d'animaux créés.

Question 3 :

Classe Joueur . Un Joueur EST UNE Personne créée à partir de son nom et d'un double txReussite . Le taux de réussite est un double entre 0 et 1: plus il est élevé, plus le joueur a des chances d'attraper des animaux. Le Joueur a également une ArrayList<Animal> liste en attribut lui permettant de stocker toutes ses prises.

Sous-question :

Son action consiste à:

  • S'il n'est pas en réussite (ie, si Math.random() est supérieur à son attribut ): NE RIEN FAIRE
  • le reste du temps, déterminer une case visée aléatoirement (entre 0 et la taille de la facade du stand) et récupérer l'Animal qui s'y trouve, s'il y en a un. En cas de succès, l'Animal extrait de la mare est ajouté à la liste et le joueur affiche un message dans la console.
Sous-question :

Le joueur possède une méthode int compterLesPoints() qui retourne le nombre de point du joueur.

NB: si un des animaux péchés fait perdre la partie, le nombre de point vaut 0

Sous-question :

La méthode toString() du joueur donne son nom, le nombre d'Animaux attrapés et le total de point du joueur.

Question 4 :

Modification du Stand . Le stand permet déjà d'ajouter des Personne ... Mais elles ne font rien. Nous allons remédier à cela en modifiant la méthode void avance() . Ajouter le code permettant de: parcourir la liste des personnes et les faire agir .

Question 5 :

Test des Personnes. Compléter la classe de Test pour créer des Joueur et des Animateur . Tester l'affichage des ces personnages puis insérer les dans le Stand et tester le bon fonctionnement de celui-ci.

Exercice 4 : Les raffinements possibles

Question 1 :

Le Joueur prudent.

Créer un joueur prudent qui ne pêche que les animaux qui ne font pas perdre (s'il tombe sur un mauvais, il ne fait rien).

Ajouter un code dans Test pour valider le bon fonctionnement.

Question 2 :

La détection des pervers

A la fin du jeu, on souhaite faire passer un test aux animateurs: si un animateur a créé 50% ou plus de lapin dans tous ses animaux, on le déclare pervers !

Ajouter une méthode dans la classe animateur qui affiche un message dans la console pour connaitre le statut de l'animateur. Ajouter un test après la partie en faisant passer tous les animateurs au détecteur.

A vous de récupérer les animateurs après la partie en ajoutant un accesseur aux personnes dans le stand, puis en filtrant, castant et testant les animateurs.

Question 3 :

Détermination du vainqueur

En utilisant le même principe que dans la question précédente, récupérer les joueurs et déterminer le vainqueur. Effectuer un affichage en conséquence.

Question 4 :

Le lapin magique

Le lapin magique donne 20 points et ne fait pas perdre la partie (mais c'est pourtant bien un lapin). Le lapin magique apparait sur le Stand indépendamment des animateurs avec une chance de 1%

Question 5 :

Dans la classe Stand , ajouter une méthode public BufferedImage makeImage() pour compléter toString() . La méthode crée une image de 400x110 pixels et imprime toString() à l'intérieur. Vous avez le droit d'utiliser la javadoc pour répondre à cette question.

Rappel de documentation:

dans une ArrayList<Object> , les méthodes suivantes sont utiles:

  • void add(Object o) : ajouter un élément à la fin
  • Object get(int i) : accesseur à l'item i
  • Object remove(int i) : retirer l'élément et renvoyer l'élément à la position i
  • int size() : retourner la taille de la liste

Il faut ajouter la commande import java.util.ArrayList; en début de fichier pour utiliser les ArrayList .