diff --git a/Diagrammes-UML.md b/Diagrammes-UML.md index 458400b..87b59ea 100644 --- a/Diagrammes-UML.md +++ b/Diagrammes-UML.md @@ -10,32 +10,38 @@ # Architecture Description -Notre application s'articule autour d'une classe principale, la classe Game. Celle-ci est entourée par la quasi-totalité des autres classes. +# Description de l'Architecture de l'Application -Elle utilise donc la classe Player, laquelle est utilisée dans deux lieux 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 lieu d'utilisation est notre ScoreBoard, un dictionnaire liant un player et 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. +Notre application s'articule autour d'une classe principale, la classe `Game`. Celle-ci est entourée par la quasi-totalité des autres classes. -Évidemment, une game ne serait rien sans un "board" ! C'est donc une classe, composée d'une liste encapsulée de cellules (class cells). Cette classe nous permet de stocker et d'exécuter certaines méthodes, comme l'ajout des tuiles. +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. -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 de couleur, l'autre de forme. Cette classe est correctement sécurisée aussi, en possédant des getters. +É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. -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. +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. -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. +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. -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 majeure : -- Un qui permet de **vérifier si une tuile peut être placée là où l'utilisateur le souhaite** -*→ L'algorithme verifie toutes les exceptions possibles, passant de celle ou il n'y a pas de tuile sur le plateau, jusqu'a regarder si la ligne fait deja 6 tuiles par exemples.* +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. -- Un **concernant l'attribution des points** -*→ Cet algorithme, qui permet de compter les points d'un joueur a la fin de son tour, inspecte plusieurs possibilités, ce qui rend sa complexitié eleve.* +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 **dernier qui gère la fin de partie.** -*→ Cet methode permet de savoir si la fin de partie est atteinte, celle-ci regarde l'ensemble du tableau si la pioche est vide, pour savoir si cela reste possible de placer les tuiles deja posseder par les joueurs.** +- 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.* -Pour terminer le tour de l'architecture, il faut aussi parler de l'application console, celle-ci est abonnée à quatre événements de Game, permettant une optimisation et une clarté du code. Les événements sont très utilisés pour indiquer ce qu'il se passe à l'utilisateur ; ils lui permettent de savoir pourquoi une tuile n'est pas placée, pourquoi un nom de joueur n'est pas accepté, qui est le prochain joueur et qui est le dernier joueur de la partie. +- 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).