Messages

ChaCuN – étape 7

1. Introduction

Le but principal de cette étape est d'écrire la classe permettant de générer les messages qui seront affichés sur le tableau d'affichage et dans d'autres parties de l'interface graphique.

Son but secondaire est de commencer à écrire le code de l'interface graphique du jeu, en écrivant des classes permettant de représenter les icônes des pions et des huttes des différents joueurs.

2. Concepts

2.1. Messages du tableau d'affichage

Comme nous l'avons dit à l'étape 4, au cours d'une partie de ChaCuN, des messages sont affichés sur le tableau d'affichage pour informer les joueurs des principaux événements qui se produisent — généralement des gains de points.

Les sections suivantes illustrent la forme que ces messages doivent avoir au moyen d'exemples qui pourraient être générés au cours d'une partie à quatre joueurs dont les noms seraient :

  • Dalia (couleur rouge),
  • Claude (couleur bleue),
  • Bachir (couleur verte),
  • Alice (couleur jaune).

2.1.1. Ordre et séparation des éléments

Lorsque plusieurs éléments apparaissent en séquence — p. ex. des noms de joueurs ou d'animaux — ils sont toujours triés. Une fois triés, les éléments sont séparés par une virgule et un espace, sauf les deux derniers qui sont séparés par le mot « et ».

Les joueurs sont triés par couleur, dans l'ordre rouge, bleu, vert, jaune et pourpre. Ainsi, dans notre partie d'exemple, si un message contient les noms de tous les joueurs sauf celui de couleur bleue — p. ex. car ces joueurs viennent de remporter ensemble un certain nombre de points — alors les noms de ces joueurs sont donnés comme « Dalia, Bachir et Alice ».

Les animaux sont triés par valeur décroissante, c.-à-d. dans l'ordre mammouths, aurochs et cerfs. Les smilodons ne sont jamais mentionnés dans les messages, car leur seul rôle dans le jeu est de manger des cerfs.

2.1.2. Fermeture d'une forêt contenant un menhir

Dans notre partie d'exemple, si la joueuse de couleur rouge ferme une forêt contenant un menhir, le message suivant est ajouté au tableau d'affichage :

Dalia a fermé une forêt contenant un menhir et peut donc placer une tuile menhir.

2.1.3. Fermeture d'une forêt

Dans notre partie d'exemple, si un joueur quelconque ferme une forêt composée de 3 tuiles, dénuée de champignons et dont le seul occupant majoritaire est le joueur de couleur bleue, le message suivant est ajouté au tableau d'affichage :

Claude a remporté 6 points en tant qu'occupant·e majoritaire d'une forêt composée de 3 tuiles.

Comme cet exemple l'illustre, le point médian (·) est utilisé pour tenir compte du fait que le genre des joueurs est inconnu. L'accord en nombre — c.-à-d. l'utilisation du singulier ou du pluriel — est par contre toujours fait conformément aux règles de la grammaire française.

Si les occupantes majoritaires sont les joueuses de couleur rouge et jaune, et que la forêt contient un groupe de champignons, le message ajouté est alors :

Dalia et Alice ont remporté 9 points en tant qu'occupant·e·s majoritaires d'une forêt composée de 3 tuiles et de 1 groupe de champignons.

2.1.4. Fermeture d'une rivière

Lorsqu'une rivière composée de trois tuiles mais dénuée de poissons est fermée et que ses occupants majoritaires sont les joueurs de couleur bleue et verte, le message suivant est ajouté au tableau d'affichage :

Claude et Bachir ont remporté 3 points en tant qu'occupant·e·s majoritaires d'une rivière composée de 3 tuiles.

Si l'occupante majoritaire est la joueuse de couleur jaune et que la rivière contient cinq poissons, le message ajouté est alors :

Alice a remporté 8 points en tant qu'occupant·e majoritaire d'une rivière composée de 3 tuiles et contenant 5 poissons.

2.1.5. Placement de la fosse à pieux

Dans notre partie d'exemple, si le joueur de couleur verte place la fosse à pieux et que son pré adjacent contient un mammouth, deux aurochs et trois cerfs, le message suivant est ajouté au tableau d'affichage :

Bachir a remporté 10 points en plaçant la fosse à pieux dans un pré dans lequel elle est entourée de 1 mammouth, 2 aurochs et 3 cerfs.

2.1.6. Placement de la pirogue

Dans notre partie d'exemple, si la joueuse de couleur jaune place la pirogue dans un réseau hydrographique contenant quatre lacs, le message suivant est ajouté au tableau d'affichage :

Alice a remporté 8 points en plaçant la pirogue dans un réseau hydrographique contenant 4 lacs.

2.1.7. Pré

Si, à la fin de notre partie d'exemple, la joueuse de couleur rouge est l'occupante majoritaire d'un pré ne contenant aucun autre animal qu'un cerf, alors le message suivant est ajouté au tableau d'affichage :

Dalia a remporté 1 point en tant qu'occupant·e majoritaire d'un pré contenant 1 cerf.

Si les joueurs de couleur verte et bleue sont les occupants majoritaires d'un autre pré contenant un mammouth et deux cerfs mais aucun auroch, alors le message suivant est ajouté au tableau d'affichage :

Claude et Bachir ont remporté 5 points en tant qu'occupant·e·s majoritaires d'un pré contenant 1 mammouth et 2 cerfs.

2.1.8. Réseau hydrographique

Si, à la fin de notre partie d'exemple, la joueuse de couleur jaune est l'occupante majoritaire d'un réseau hydrographique contenant neuf poissons, alors le message suivant est ajouté au tableau d'affichage :

Alice a remporté 9 points en tant qu'occupant·e majoritaire d'un réseau hydrographique contenant 9 poissons.

Si tous les joueurs sauf la joueuse de couleur jaune sont les occupants majoritaires d'un réseau hydrographique contenant un poisson, alors le message suivant est ajouté au tableau d'affichage :

Dalia, Claude et Bachir ont remporté 1 point en tant qu'occupant·e·s majoritaires d'un réseau hydrographique contenant 1 poisson.

2.1.9. Grande fosse à pieux

Si, à la fin de notre partie d'exemple, les joueurs de couleur jaune et verte sont les occupants majoritaires d'un pré contenant la grande fosse à pieux, et que dans son pré adjacent se trouvent deux mammouths, deux aurochs et deux cerfs, le message suivant est ajouté au tableau d'affichage :

Bachir et Alice ont remporté 12 points en tant qu'occupant·e·s majoritaires d'un pré contenant la grande fosse à pieux entourée de 2 mammouths, 2 aurochs et 2 cerfs.

Si la joueuse de couleur rouge est l'unique occupante majoritaire d'un pré contenant la grande fosse à pieux et que dans son pré adjacent ne se trouve aucun autre animal qu'un auroch, alors le message ajouté est :

Dalia a remporté 2 points en tant qu'occupant·e majoritaire d'un pré contenant la grande fosse à pieux entourée de 1 auroch.

2.1.10. Radeau

Si, à la fin de notre partie d'exemple, les joueurs de couleur rouge et bleue sont les occupants majoritaires d'un réseau hydrographique contenant le radeau et dix lacs, le message suivant est ajouté au tableau d'affichage :

Dalia et Claude ont remporté 10 points en tant qu'occupant·e·s majoritaires d'un réseau hydrographique contenant le radeau et 10 lacs.

Si la joueuse de couleur jaune est l'unique occupante majoritaire d'un réseau hydrographique contenant le radeau et un lac, alors le message ajouté est :

Alice a remporté 1 point en tant qu'occupant·e majoritaire d'un réseau hydrographique contenant le radeau et 1 lac.

2.1.11. Victoire

Si le joueur de couleur verte est l'unique gagnant de la partie avec un total de 111 points, alors le message suivant est ajouté au tableau d'affichage :

Bachir a remporté la partie avec 111 points !

Si les joueuses de couleur rouge et jaune sont ex æquo et remportent donc ensemble la partie avec 123 points, alors le message suivant est ajouté au tableau d'affichage :

Dalia et Alice ont remporté la partie avec 123 points !

2.1.12. Ajout et suppression d'occupants

Lorsque le joueur courant a la possibilité d'ajouter ou de reprendre un occupant, un message est affiché non pas sur le tableau d'affichage, mais à la place de l'image de la tuile à placer — étant donné qu'il n'y en a alors pas.

Lorsque le joueur peut placer un occupant, le message affiché est :

Cliquez sur le pion ou la hutte que vous désirez placer, ou ici pour ne pas en placer.

tandis que lorsque le joueur peut reprendre un pion — suite à la pose de la tuile contenant le chaman — le message affiché est :

Cliquez sur le pion que vous désirez reprendre, ou ici pour ne pas en reprendre.

2.2. Icônes des occupants

Comme nous l'avons dit à l'étape 1, les occupants des différents joueurs sont représentés par des icônes colorées, visibles ci-dessous.

pawns-huts.svg
Figure 1 : Icônes représentant les occupants

L'apparence de ces icônes est décrite au moyen de chemins SVG (SVG paths), qui sont des descriptions textuelles concises d'une séquence d'opérations à effectuer pour dessiner un objet. La syntaxe exacte de ces chemins ne sera pas décrite ici, mais les personnes désirant en savoir plus pourront se rapporter à la page les décrivant du Mozilla Developer Network. L'éditeur en ligne SvgPathEditor permet de visualiser et éditer graphiquement des chemins SVG.

Le chemin SVG représentant un pion est (voir sur SvgPathEditor) :

M -10 10 H -4 L 0 2 L 6 10 H 12 L 5 0 L 12 -2 L 12 -4 L 6 -6
L 6 -10 L 0 -10 L -2 -4 L -6 -2 L -8 -10 L -12 -10 L -8 6 Z

tandis que celui représentant une hutte est (voir sur SvgPathEditor) :

M -8 10 H 8 V 2 H 12 L 0 -10 L -12 2 H -8 Z

3. Mise en œuvre Java

Cette étape est la première de la seconde partie du projet, durant laquelle vous serez plus libres et moins guidés que durant la première.

En particulier, vous avez maintenant le droit de modifier ou augmenter l'interface publique des classes et interfaces proposées, pour peu bien entendu que vous ayez une bonne raison de le faire. Pour faciliter la correction, nous vous demandons néanmoins de respecter les noms de paquetages et de classes, interfaces, enregistrements et types énumérés donnés.

D'autre part, nous nous attendons à ce que vous lisiez et compreniez la documentation des parties de la bibliothèque Java que vous devez utiliser.

3.1. Classe TextMakerFr

La classe TextMakerFr du paquetage principal, publique et immuable, permet de générer tout le texte français nécessaire à l'interface graphique de ChaCuN. Elle implémente l'interface TextMaker et ne fournit aucune autre méthode publique que celles de cette interface.

Notez bien que tous les messages générés par votre classe doivent être conformes à ceux donnés en exemple plus haut, et doivent respecter les règles de l'orthographe et de la grammaire française.

En plus de ces méthodes, TextMakerFr offre un constructeur public qui prend en argument une table associant leur nom aux couleurs des joueurs.

3.1.1. Conseils de programmation

Les méthodes de TextMakerFr doivent générer des chaînes de caractères composées de parties constantes et de parties calculées.

Il existe de nombreuses manières de construire ces chaînes : l'opérateur +, les bâtisseurs de chaînes, la méthode format de String, et ainsi de suite. Java 21 en offre une nouvelle, particulièrement puissante, que nous vous conseillons d'utiliser. Il s'agit des patrons de chaîne (string templates), qui permettent de construire une chaîne combinant des parties constantes et des parties calculées.

Un patron de chaîne ressemble à une chaîne constante, mais est précédé du préfixe STR. et peut contenir du code Java quelconque, entouré d'accolades et précédé d'une barre oblique inverse (\, backslash en anglais). Ce code Java est exécuté normalement, et sa valeur est convertie en chaîne au moyen de toString avant d'être inséré dans la chaîne. Par exemple, au lieu d'écrire :

String name = "Jean";
int points = 12;
String message = name + " a remporté " + points + " points.";

on peut écrire :

String name = "Jean";
int points = 12;
String message = STR."\{name} a remporté \{points} points.";

Il faut noter qu'en Java 21, les patrons de chaîne sont ce que l'on nomme une preview feature, c.-à-d. un concept en cours d'ajout au langage et susceptible de changer dans une version ultérieure. Ces preview features doivent être activées explicitement, ce qui dans IntelliJ peut se faire en changeant le « niveau de langage » en sélectionnant Project Structure… dans le menu File, puis en cliquant sur Project avant de changer le Language level à 21 (Preview) - String templates […].

Les patrons de chaîne sont relativement simples à utiliser et l'exemple ci-dessus devrait donc suffire, mais les personnes désirant en savoir plus à leur sujet pourront lire le document les décrivant, à savoir le JEP 430: String Templates1.

3.2. Installation de JavaFX

Les deux prochaines classes à écrire pour cette étape — ColorMap et Icon — sont les premières du projet qui ont un lien avec l'interface graphique, ce qui a deux conséquences.

La première est que nous placerons ces classes dans un nouveau sous-paquetage du paquetage principal, nommé gui — donc le nom complet de leur paquetage sera ch.epfl.chacun.gui.

La seconde est qu'il faut installer JavaFX avant de commencer à rédiger ces classes. Pour cela, suivez tout d'abord les instructions données dans notre guide, puis ajoutez à votre projet, directement dans le dossier src, un fichier nommé module-info.java ayant le contenu suivant :

module ChaCuN {
    requires javafx.controls;
    requires java.net.http;

    exports ch.epfl.chacun;
    exports ch.epfl.chacun.gui;
}

Le moyen le plus simple de l'ajouter consiste à effectuer un clic droit sur votre dossier src dans IntelliJ, puis de choisir l'entrée module-info.java dans le sous-menu New.

L'existence de ce fichier fait de ChaCuN ce que l'on nomme une application modulaire (modular application), c.-à-d. une application utilisant le système de modules de Java. Ce système de modules a été introduit dans la version 9 du langage, est généralement peu utilisé, et ne sera pas examiné en détail dans le cadre de ce cours. Il permet toutefois de simplifier l'utilisation de JavaFX, raison pour laquelle nous avons choisi d'en faire usage dans le projet2.

3.3. Classe ColorMap

La classe ColorMap du sous-paquetage gui, publique et non instanciable, contient des méthodes permettant de déterminer les couleurs JavaFX à utiliser pour représenter à l'écran les cinq couleurs de joueur qui existent dans ChaCuN. Pour cela, ColorMap offre deux méthodes publiques — et bien entendu statiques.

La première, nommée p. ex. fillColor, prend en argument une couleur de joueur ChaCuN — de type PlayerColor — et retourne la couleur JavaFX — de type javafx.scene.paint.Color — à utiliser pour remplir, entre autres, les occupants du joueur donné. La correspondance entre les couleurs de joueur et les couleurs JavaFX est donnée par la table suivante :

PlayerColor Color
RED RED
BLUE BLUE
GREEN LIME (!)
YELLOW YELLOW
PURPLE PURPLE

La seconde méthode de ColorMap, nommée p. ex. strokeColor, prend en argument une couleur de joueur ChaCuN et retourne la couleur JavaFX à utiliser pour dessiner, entre autre, le contour des occupants du joueur donné.

Cette couleur est le blanc (WHITE) pour tous les joueurs sauf le jaune et le vert, pour lesquels elle est une version 40% moins lumineuse de la couleur de remplissage — qui s'obtient facilement au moyen de la méthode deriveColor appliquée à la couleur de remplissage, en lui passant 0 comme décalage de couleur (hueShift) et 1 pour tous les facteurs sauf celui de la luminosité (brightnessFactor) qui doit valoir 0.6.

3.4. Classe Icon

La classe Icon du sous-paquetage gui, publique et non instanciable, permet d'obtenir des nouveaux éléments JavaFX (nœuds) représentant les occupants des différents joueurs.

La seule méthode publique de la classe Icon, nommée p. ex. newFor, prend en arguments une couleur de joueur et un type d'occupant et retourne une nouvelle instance de SVGPath représentant l'occupant correspondant.

Le type de retour de cette méthode pourrait bien entendu être SVGPath, mais nous vous conseillons d'utiliser plutôt Node, plus général — pour la même raison qu'une méthode retournant une liste retourne généralement une valeur de type List<…> et pas une d'un type plus spécifique comme ArrayList<…>.

3.4.1. Conseils de programmation

Pour comprendre comment construire l'instance de SVGPath à retourner, lisez la documentation de la classe, en particulier celle de la méthode setContent, ainsi que celle des méthodes setFill et setStroke qu'elle hérite de sa classe-mère Shape.

3.5. Tests

À partir de cette étape, aucun fichier de vérification de signatures ne vous est fourni, étant donné que la signature des différentes méthodes n'est plus spécifiée en détail. Pour la même raison, aucun test unitaire ne sera plus fourni à l'avenir, à vous d'écrire les vôtres. Notez que cela est fortement recommandé, en tout cas pour les classes qui sont faciles à tester avec des tests unitaires.

4. Résumé

Pour cette étape, vous devez :

  • écrire les classes TextMakerFr, ColorMap et Icon selon les indications données ci-dessus,
  • tester votre code — surtout la classe TextMakerFr, les deux autres étanet plus difficiles à tester au moyen de tests unitaires,
  • documenter la totalité des entités publiques que vous avez définies.

Aucun rendu n'est à faire pour cette étape avant le rendu final. N'oubliez pas de faire régulièrement des copies de sauvegarde de votre travail en suivant nos indications à ce sujet.

Notes de bas de page

1

Un JEP (acronyme de Java Enhancement Proposal) est un document numéroté proposant une amélioration au langage Java. Le JEP 0 référence tous les JEPs existant.

2

Il faut savoir qu'IntelliJ possède aussi une notion de module qui n'a malheureusement rien à voir avec celle de Java. Par exemple, lorsqu'on examine la structure d'un projet (project structure), les modules qui y figurent sont des modules au sens d'IntelliJ, pas de Java, et ils sont donc présents même en l'absence d'un fichier module-info.java.