# POO - Labo 8 Rapport
* Auteurs: Aurélien Bloch, Dorian Niclass, Leandro Saraiva Maia
* 7 Janvier 2022
## Utilisation du programme
## Diagramme de classe

## Choix d'implémentation
### Plateau de jeu
Le plateau de jeu est représenté, dans la classe `Board`, par un tableau à 2 dimensions de `Piece` qui répresente les lignes et colonnes du jeu d'échec. L'arrangement des lignes dans ce tableau respecte celui d'un plateau d'échec standard, c'est à dire que la ligne 1 est tout en bas (côté blanc) alors que la ligne 8 est tout en haut (côté noir). Autrement dit, c'est comme si l'ordre des lignes dans le tableau `chessboard` était à l'envers, étant donné que la ligne à l'index 0 représente la ligne tout en bas du plateau d'échec (côté blanc) au lieu d'être la première ligne.
### Pièces et mouvements
Toutes les pièces héritent de la classe abstraite `Piece`. Cela nous permet de gérer le plateau d'échec et d'effectuer des actions sur des pièces sans appriori sur le type de la pièce.
Deux méthodes importantes dans la classe `Piece` permettent de gérer leurs mouvements `canMoveTo()` et `moveTo()`. La première permet de savoir si la pièce peut se déplacer aux coordonnées fournies sans la déplacer, la seconde vérifie si la pièce peut se déplacer aux coordonnées fournies et déplace la pièce si cela est possible. Ces deux méthodes retournent `true` si la pièce peut se déplacer ou si elle a été déplacée et `false` lorsque cela n'est pas possible.
Pour gérer les mouvements qu'une pièce peut executer, une pièce possède une liste de `Move`. `Move` est une classe abstraite qui définit un mouvement. Cette classe contient aussi les méthodes `canMoveTo()` et `moveTo()`. La pièce, lors de l'appel a `canMoveTo()` ou `moveTo()` itère parmis sa liste de `Move` et appelle les fonctions `canMoveTo()` ou `moveTo()`, s'arrétant sur le premier mouvement valide et l'execute.
La plupart des mouvements partent d'un mouvement "générique" `LinearMove` qui défini un mouvement en ligne droite. Certaines pièces ne possèdes pas de tel mouvement comme le cavalier qui possède son propre `KnightMove` qui hérite directement de `Move`. D'autres mouvement linéaires sont plus spécialisés, comme le `PawnDoubleMove` qui gère le déplacement de deux cases du pion ou encore le `Castling` qui est un mouvement très spécifique.
### Détection de mise en échec
Pour déterminer si un roi est un échec, on vérifie après chaque tour si une pièce ennemie peut se déplacer sur le roi. Si tel est le cas, alors le roi est mit en échec par au moins une pièce.
Une pièce ne peut pas se déplacer vers une case qui met son roi en échec, pour implémenter ça, on fait une copie du plateau avant le mouvement, et si le roi est en échec après ce mouvement, il faut revenir en arrière et annuler le mouvement en remettant le plateau à l'état sauvegardé précedemment.
### Détection de l'échec et mat et du pat
Afin de déterminer si un joueur est en échec et mat, on contrôle s'il est mis en échec et on utilise la méthode `canPlayerLegallyMove()` en lui disant de ne contrôler que le roi.
Pour déterminer si un joueur est en pat, on contrôle qu'il n'est pas en échec et on utilise la méthode `canPlayerLegallyMove()` en lui disant de contrôler toutes les pièces.
Cette méthode contrôle pour toutes les pièces demandées si elles ont au moins une possibilité de se déplacer sans se faire manger en utilisant la méthode `canPieceLegallyMove()` pour chacune d'entre elles.
Cette méthode fonctionne ainsi : pour tous les déplacements possibles de la pièce, on contrôle si elle peut le faire sans se faire manger au tour suivant par n'importe quelle pièce adverse.
## Vérification du fonctionnement
Nous avons effectué beaucoup de parties et rencontré aucun bug d'affichage ou de comportements suspects.
Pour vérifier le stalemate/pat, nous avons regardé des exemples connus et les avons reproduits dans le programme pour voir si les cas étaient bien reconnus.
Pour être 100% transparents, nous n'avons pas réussi à implémenter parfaitement le stalemate. Il y a (au moins) un cas où le pat n'est pas détecté, c'est le premier exemple sur [la page wikipedia du stalemate](https://en.wikipedia.org/wiki/Stalemate).
Notre algorithme ne permet pas de savoir si la pièce se fera manger par une autre si elle en mange une pour faire son déplacement.
L'échec est toujours correctement détecté.
L'échec et mat est toujours correctement détecté.
Le sauvetage du roi est toujours correctement détecté.
Les coups interdits sont toujours correctement détectés.