Class Diagram
Package Diagram
Sequence Diagram
Architecture Description
Description de l'Architecture de l'Application
Notre application s'articule autour d'une classe principale, la classe Game
. Celle-ci est entourée par la quasi-totalité des autres classes.
Elle utilise la classe Player
, laquelle est utilisée dans deux contextes très importants. Les méthodes liées à la gestion des joueurs sont majoritairement basées sur une interface nommée IPlayer
, nous permettant d'imaginer, au besoin, d'autres règles pour ces méthodes-là. Le premier contexte d'utilisation est notre ScoreBoard
, un dictionnaire liant un joueur à un score. La classe Player
est aussi utilisée par une liste qui nous permet de faire fonctionner correctement la partie. Le choix a été fait de ne pas se servir du ScoreBoard
pour cela, afin d'éviter tout problème.
Évidemment, une partie ne serait rien sans un "board" ! C'est donc une classe, composée d'une liste encapsulée de cellules (classe Cell
). Cette classe nous permet de stocker et d'exécuter certaines méthodes, comme l'ajout des tuiles.
Le QWIRKLE est composé de tuiles. Chez nous, les tuiles représentent deux classes, deux enums. La première est une classe simple contenant une couleur et une forme, piochées dans les deux enums, une pour les couleurs, l'autre pour les formes. Cette classe est correctement sécurisée, en possédant des getters.
La seconde classe des tuiles est très importante, c'est celle des TilesBag
. Elle est utilisée à deux endroits. Cette classe, qui nous permet de créer des listes de tuiles, est donc appelée à deux reprises : dans Game
, où elle sert de pioche pour les joueurs, et dans Player
, pour stocker les tuiles de chaque joueur.
Pour compléter sur la gestion des tuiles, dans Game
, plusieurs méthodes s'en occupent. Tout d'abord, une fonction swap
et une autre de distribution des tuiles, essentielles pour le bon fonctionnement du jeu.
Plusieurs autres fonctions implémentent les tuiles et globalement les règles de jeu. Elles sont liées à l'interface IRules
et sont écrites dans la classe Game
. On y retrouve, par exemple, trois algorithmes majeurs :
-
Un qui permet de vérifier si une tuile peut être placée là où l'utilisateur le souhaite.
- L'algorithme vérifie toutes les exceptions possibles, passant de celle où il n'y a pas de tuile sur le plateau, jusqu'à vérifier si la ligne fait déjà 6 tuiles, par exemple.
-
Un concernant l'attribution des points.
- Cet algorithme, qui permet de compter les points d'un joueur à la fin de son tour, inspecte plusieurs possibilités, ce qui rend sa complexité élevée.
-
Un dernier qui gère la fin de partie.
- Cette méthode permet de savoir si la fin de partie est atteinte ; elle examine l'ensemble du plateau et vérifie si la pioche est vide, pour déterminer s'il est encore possible de placer les tuiles déjà possédées par les joueurs.
Nous avons préféré utiliser des événements à la place des exceptions pour permettre une meilleure implémentation. L'exemple même est celui du premier événement, qui permet de renvoyer un message clair indiquant à l'utilisateur si oui ou non le nom entré est valide, en lui spécifiant la raison du refus (nom vide, avec des espaces, déjà existant, etc.).
Nous avons utilisé d'autres événements : un qui renvoie à qui c'est le tour, lié directement à la fonction qui définit le prochain joueur ; un autre qui simule une exception pour le placement de tuile, en indiquant si celle-ci est posée ou non et, le cas échéant, la raison du refus (trop de tuiles sur la même ligne, pas les bonnes couleurs, etc.).
Un dernier événement permet d'annoncer la fin de la partie et d'indiquer quel joueur a joué en dernier.
Pour terminer la description de l'architecture, il faut également parler de l'application console, qui est abonnée aux quatre événements précédemment cités de Game
. Notre application console fait le moins de choses possible, afin d'éviter trop de modifications lors de la transition vers l'affichage. La logique du jeu est entièrement gérée par la partie métier, et la console assure simplement le lien avec l'utilisateur en analysant ses entrées et en affichant les messages. Nous avons choisi de séparer notre code pour la partie console en deux : une partie principale (program.cs) et une partie dédiée à l'affichage des notifications (NotificationClass.cs).
Nous avons également dans le projet deux autres classes indépendantes. Pour une bonne gestion et un affichage efficace du classement, ainsi qu'une gestion future optimale de la persistance, nous avons créé une classe "Leaderboard" qui implémente une liste de "Score". Cette dernière est aussi une classe contenant plusieurs informations, telles que la date, les dernières victoires, les derniers points, etc.