using CoreLibrary.Exceptions; using System.Collections.ObjectModel; using System.Runtime.Serialization; namespace CoreLibrary.Core { /// /// Classe représentant un code composé de jetons et ses différentes méthodes. /// [DataContract] public class Code { /// /// Collection observable de jetons. /// [DataMember] public ObservableCollection Jetons { get; private init; } = new ObservableCollection(); /// /// Obtient le nombre actuel de jetons dans le code. /// public int Taille => Jetons.Count; /// /// Taille maximale de jetons autorisée pour le code. /// [DataMember] public int TailleMax { get; private init; } /// /// Indique si le code est complet. /// public bool Complet => Taille == TailleMax; /// /// Indique si le code est vide. /// public bool Vide => Taille == 0; /// /// Constructeur de code avec une taille maximale spécifiée. /// /// La taille maximale de jetons autorisée pour le code. /// Exception lancée si la taille spécifiée est négative ou nulle. public Code(int taille) { if (taille < 0) throw new TailleCodeException(taille); TailleMax = taille; } /// /// Ajoute un jeton au code. /// /// Le jeton à ajouter. /// Lancée si le code est déjà complet. public void AjouterJeton(Jeton jeton) { if (Complet) throw new CodeCompletException(); Jetons.Add(jeton); } /// /// Récupère le jeton à l'indice spécifié. /// /// L'indice du jeton à récupérer. /// Renvoie le jeton à l'indice spécifié. /// Lancée si l'indice est en dehors des limites de la collection de jetons. public Jeton RecupererJeton(int indice) { if (indice < 0 || indice >= Taille) throw new IndiceCodeException(indice, Taille - 1); return Jetons.ElementAt(indice); } /// /// Supprime le dernier jeton du code. /// /// Lancée si le code est vide. public void SupprimerDernierJeton() { if (Vide) throw new CodeVideException(); Jetons.RemoveAt(Taille - 1); } /// /// Compare le code avec le code secret et retourne une liste d'indicateurs. /// /// Le code à comparer. /// Renvoie une liste d'indicateurs représentant les résultats de la comparaison. /// Lancée si le code n'est pas complet. /// Lancée si le code est invalide. public IReadOnlyList Comparer(Code code) { // Je suis le bon code List indicateurs = new List(); if (!code.Complet) throw new CodeIncompletException(); if (code.TailleMax != TailleMax) throw new CodeInvalideException(); List mesJetons = Jetons.Select(jeton => (Jeton?)jeton).ToList(); List sesJetons = code.Jetons.Select(jeton => (Jeton?)jeton).ToList(); for (int i = 0; i < mesJetons.Count; ++i) { if (mesJetons[i] == sesJetons[i]) { mesJetons[i] = null; sesJetons[i] = null; indicateurs.Add(Indicateur.BonnePlace); } } for (int i = 0; i < sesJetons.Count; ++i) { if (sesJetons[i].HasValue && mesJetons.Contains(sesJetons[i])) { mesJetons[mesJetons.IndexOf(sesJetons[i])] = null; sesJetons[i] = null; indicateurs.Add(Indicateur.BonneCouleur); } } return indicateurs; } /// /// Retourne la taille du code sous forme de chaîne de caractères. /// /// Renvoie une chaîne de caractères représentant la taille du code. public override string ToString() => $"Code({Taille})"; } }