using CoreLibrary.Exceptions; using CoreLibrary.Evenements; using System.Runtime.Serialization; using System.Security.Cryptography; namespace CoreLibrary.Core { /// /// Classe représentant le plateau de jeu contenant les codes et les indicateurs. /// [DataContract] public class Plateau { /// /// Événement déclenché lorsqu'un code est ajouté au plateau. /// public event EventHandler? PlateauAjouterCode; private void QuandPlateauAjouterCode() => PlateauAjouterCode?.Invoke(this, new PlateauAjouterCodeEventArgs(this)); /// /// Le code secret à deviner. /// [DataMember] private readonly Code codeSecret; /// /// Liste des codes ajoutés au plateau. /// [DataMember] private readonly List codes = new List(); /// /// Liste des listes d'indicateurs pour chaque code ajouté. /// [DataMember] private readonly List> indicateurs = new List>(); /// /// Obtient le nombre de codes sur le plateau. /// public int Taille => codes.Count; /// /// Obtient la taille maximale de codes autorisée sur le plateau. /// [DataMember] public int TailleMax { get; private init; } /// /// Obtient la taille maximale d'un code. /// [DataMember] public int TailleMaxCode { get; private init; } /// /// Indique si le plateau à atteint sa taille maximale. /// public bool Complet => Taille == TailleMax; /// /// Indique si la victoire est atteinte. /// [DataMember] public bool Victoire { get; private set; } = false; /// /// Obtient la grille des codes et des indicateurs. /// public (IEnumerable>, IEnumerable>) Grille => ( codes.Select(code => code.Jetons), indicateurs ); /// /// Constructeur de plateau avec une taille de code et une taille de plateau spécifiées. /// /// La taille maximale d'un code. /// La taille maximale du plateau. /// Lancée si la taille du code est négative ou nulle. /// Lancée si la taille du plateau spécifiée est négative ou nulle. public Plateau(int tailleCode, int taillePlateau) { if (tailleCode < 0) throw new TailleCodeException(tailleCode); if (taillePlateau < 0) throw new TailleGrilleException(taillePlateau); TailleMax = taillePlateau; TailleMaxCode = tailleCode; codeSecret = GenererCodeSecret(); } /// /// Génère un code secret aléatoire. /// /// Renvoie le code secret généré. private Code GenererCodeSecret() { Code code = new Code(TailleMaxCode); Couleur[] couleurs = Enum.GetValues(); while (!code.Complet) { code.AjouterJeton( new Jeton(couleurs[RandomNumberGenerator.GetInt32(0, couleurs.Length)]) ); } return code; } /// /// Ajoute un code au plateau et compare avec le code secret. /// /// Le code à ajouter. /// Lancée si le code à ajouter n'est pas complet. /// Lancée si le plateau est déjà complet. public void AjouterCode(Code code) { if (!code.Complet) throw new CodeIncompletException(); if (Complet) throw new GrilleCompleteException(); codes.Add(code); IReadOnlyList indicateursCode = codeSecret.Comparer(code); indicateurs.Add(indicateursCode.ToList()); if (!Victoire && indicateursCode.Count(indicateur => indicateur == Indicateur.BonnePlace) == TailleMaxCode) Victoire = true; QuandPlateauAjouterCode(); } } }