diff --git a/Sources/ConsoleApp/Evenements.cs b/Sources/ConsoleApp/Evenements.cs index bacbd3b..8feb58c 100644 --- a/Sources/ConsoleApp/Evenements.cs +++ b/Sources/ConsoleApp/Evenements.cs @@ -1,4 +1,4 @@ -using CoreLibrary.Events; +using CoreLibrary.Evenements; using CoreLibrary.Joueurs; using CoreLibrary.Core; using System.Diagnostics.CodeAnalysis; @@ -17,7 +17,7 @@ namespace ConsoleApp /// L'instance de l'événement DemanderNomEventArgs créée par Partie. /// Le nom du joueur. /// - public static void DemanderNom(Object? sender, DemanderJoueurEventArgs e) + public static void DemanderNom(Object? sender, PartieDemanderJoueurEventArgs e) { Console.WriteLine($"Joueur {e.Indice}"); Console.Write(">>> "); @@ -26,7 +26,7 @@ namespace ConsoleApp Console.WriteLine(); - e.JoueurBuilder.Nom(nom); + e.JoueurDemande.SeConnecter(!string.IsNullOrEmpty(nom) ? Program.Manageur.DemanderJoueur(nom) : new Joueur($"Joueur {e.Indice}")); } @@ -35,7 +35,7 @@ namespace ConsoleApp /// La classe qui appelle l'événement; ici Partie. /// L'instance de l'événement DebutPartieEventArgs créée par Partie. /// - public static void CommencerLaPartie(Object? sender, DebutPartieEventArgs e) + public static void CommencerLaPartie(Object? sender, PartieDebutPartieEventArgs e) { Utils.DessinerSeparateur(); @@ -47,20 +47,21 @@ namespace ConsoleApp /// La classe qui appelle l'événement; ici Partie. /// L'instance de l'événement NouveauTourEventArgs créée par Partie. /// - public static void NouveauTour(Object? sender, NouveauTourEventArgs e) + public static void NouveauTour(Object? sender, PartieNouveauTourEventArgs e) { Utils.DessinerSeparateur(); Console.WriteLine($"Tour {e.Tour} - {e.Joueur.Nom}\n"); - Utils.DessinerPlateau(e.Grille, e.Indicateurs); + (IReadOnlyList> codes, IReadOnlyList> indicateurs) = e.Plateau.Grille; + Utils.DessinerPlateau(e.Plateau); Console.WriteLine(); Code code = e.Code; - while(!code.EstComplet()) + while(!code.Complet) { - Jeton? jeton = Utils.SaisirJeton(code.NbJetons); + Jeton? jeton = Utils.SaisirJeton(code.Taille); if (jeton.HasValue) { Utils.DessinerPion(jeton.Value.Couleur); @@ -73,7 +74,7 @@ namespace ConsoleApp } } - e.Joueur.Code(code); + e.Plateau.AjouterCode(code); } /// @@ -81,7 +82,7 @@ namespace ConsoleApp /// La classe qui appelle l'événement; ici Partie. /// L'instance de l'événement AjouterCodeEventArgs créée par Partie. /// - public static void AjouterCode(Object? sender, AjouterCodeEventArgs e) + public static void AjouterCode(Object? sender, PartiePasserLaMainEventArgs e) { Console.WriteLine(); @@ -93,7 +94,7 @@ namespace ConsoleApp /// La classe qui appelle l'événement; ici Partie. /// L'instance de l'événement PartieTermineeEventArgs créée par Partie. /// - public static void PartieTerminee(Object? sender, PartieTermineeEventArgs e) + public static void PartieTerminee(Object? sender, PartiePartieTermineeEventArgs e) { Joueur[] gagnants = e.Gagnants.ToArray(); diff --git a/Sources/ConsoleApp/Program.cs b/Sources/ConsoleApp/Program.cs index 5bfe329..02d66fe 100644 --- a/Sources/ConsoleApp/Program.cs +++ b/Sources/ConsoleApp/Program.cs @@ -1,5 +1,7 @@ -using CoreLibrary; +using CoreLibrary.Manageurs; +using CoreLibrary.Persistance; using CoreLibrary.Regles; +using CoreLibrary; using System.Diagnostics.CodeAnalysis; namespace ConsoleApp @@ -11,17 +13,19 @@ namespace ConsoleApp [ExcludeFromCodeCoverage] public static class Program { + public static Manageur Manageur { get; private set; } = new Manageur(new PersistanceJSON()); + public static void Main() { Utils.DessinerTitre(); - Partie maPartie = new Partie(new ReglesClassiques()); + Partie maPartie = Manageur.NouvellePartie(new ReglesClassiques()); - maPartie.DemanderNom += Evenements.DemanderNom; - maPartie.DebutPartie += Evenements.CommencerLaPartie; - maPartie.NouveauTour += Evenements.NouveauTour; - maPartie.AjouterCode += Evenements.AjouterCode; - maPartie.PartieTerminee += Evenements.PartieTerminee; + maPartie.PartieDemanderJoueur += Evenements.DemanderNom; + maPartie.PartieDebutPartie += Evenements.CommencerLaPartie; + maPartie.PartieNouveauTour += Evenements.NouveauTour; + maPartie.PartiePasserLaMain += Evenements.AjouterCode; + maPartie.PartiePartieTerminee += Evenements.PartieTerminee; maPartie.Jouer(); } diff --git a/Sources/ConsoleApp/Utils.cs b/Sources/ConsoleApp/Utils.cs index 788b9bd..09e929a 100644 --- a/Sources/ConsoleApp/Utils.cs +++ b/Sources/ConsoleApp/Utils.cs @@ -12,18 +12,18 @@ namespace ConsoleApp // Dictionnaires associant les valeurs des énumérations avec les couleurs de la console private readonly static Dictionary couleursTerminal = new Dictionary() { - {Couleur.NOIR, ConsoleColor.Black }, - {Couleur.BLANC, ConsoleColor.White }, - {Couleur.ROUGE, ConsoleColor.Red }, - {Couleur.VERT, ConsoleColor.Green }, - {Couleur.BLEU, ConsoleColor.Blue }, - {Couleur.JAUNE, ConsoleColor.DarkYellow } + {Couleur.Noir, ConsoleColor.Black }, + {Couleur.Blanc, ConsoleColor.White }, + {Couleur.Rouge, ConsoleColor.Red }, + {Couleur.Vert, ConsoleColor.Green }, + {Couleur.Bleu, ConsoleColor.Blue }, + {Couleur.Jaune, ConsoleColor.DarkYellow } }; private readonly static Dictionary indicateursTerminal = new Dictionary() { - {Indicateur.BONNEPLACE, ConsoleColor.Black }, - {Indicateur.BONNECOULEUR, ConsoleColor.White } + {Indicateur.BonnePlace, ConsoleColor.Black }, + {Indicateur.BonneCouleur, ConsoleColor.White } }; /// @@ -72,7 +72,7 @@ namespace ConsoleApp Console.BackgroundColor = Console.ForegroundColor.Equals(ConsoleColor.Black) ? ConsoleColor.White : ConsoleColor.Black; Console.OutputEncoding = System.Text.Encoding.UTF8; - Console.Write("O"); + Console.Write('O'); Console.ResetColor(); @@ -83,59 +83,54 @@ namespace ConsoleApp /// Dessine une ligne de pions sur la console. /// /// Un tableau d'énumérations représentant les pions à dessiner. - private static void DessinerLigne(Enum[] ligne) + private static void DessinerLigne(int taille, IEnumerable ligne) where T : Enum { - foreach(Enum pion in ligne) + Console.Write(" "); + + foreach (Enum pion in ligne) DessinerPion(pion); - // Ajoute des espaces s'il y a moins de 4 pions à dessiner - Console.Write("".PadLeft((4 - ligne.Length) * 3)); + // Ajoute des espaces s'il y a moins de taille pions à dessiner + Console.Write("".PadLeft((taille - ligne.Count()) * 3 + 1)); } /// /// Dessine un plateau de jeu dans la console, affichant les codes et leurs indicateurs. /// - /// La grille de jeu. - /// Les indicateurs associés à chaque ligne. - public static void DessinerPlateau(IEnumerable> grille, IEnumerable> indicateurs) + /// Le plateau de jeu. + public static void DessinerPlateau(Plateau plateau) { - IEnumerable[] grilleTableau = grille.ToArray(); - IEnumerable[] indicateursTableau = indicateurs.ToArray(); - - Console.WriteLine(" Codes Indicateurs "); - Console.WriteLine("──────────────── ────────────────"); - Console.WriteLine("│ │ │ │"); - - for (int i = 0; i < grille.Count(); ++i) - { - Console.Write("│ "); + (IReadOnlyList> codes, IReadOnlyList> indicateurs) = plateau.Grille; - DessinerLigne( - grilleTableau[i] - .Where(jeton => jeton.HasValue) - .Select(jeton => (Enum)jeton!.Value.Couleur) - .ToArray() - ); + int tailleGrille = 2 + plateau.TailleMaxCode * 3; - Console.Write(" │ │ "); + Console.WriteLine($"─{new string('─', tailleGrille)}─ ─{new string('─', tailleGrille)}─"); + Console.WriteLine($"│{new string(' ', tailleGrille)}│ │{new string(' ', tailleGrille)}│"); - if (indicateursTableau[i] == null) + for (int i = 0; i < plateau.TailleMax; ++i) + { + if(i >= codes.Count) { - indicateursTableau[i] = []; + Console.WriteLine($"│{new string(' ', tailleGrille)}│ │{new string(' ', tailleGrille)}│"); + continue; } - DessinerLigne( - indicateursTableau[i] - .Select(indicateur => (Enum)indicateur) - .ToArray() - ); + IReadOnlyList ligneCodes = codes.ElementAt(i); + IReadOnlyList ligneIndicateurs = indicateurs.ElementAt(i); - Console.WriteLine(" │"); - } + Console.Write("│"); + + DessinerLigne(plateau.TailleMaxCode, ligneCodes.Select(jeton => jeton.Couleur)); + Console.Write("│ │"); - Console.WriteLine("│ │ │ │"); - Console.WriteLine("──────────────── ────────────────"); + DessinerLigne(plateau.TailleMaxCode, ligneIndicateurs); + + Console.WriteLine("│"); + } + + Console.WriteLine($"│{new string(' ', tailleGrille)}│ │{new string(' ', tailleGrille)}│"); + Console.WriteLine($"─{new string('─', tailleGrille)}─ ─{new string('─', tailleGrille)}─"); } /// diff --git a/Sources/CoreLibrary/Core/Code.cs b/Sources/CoreLibrary/Core/Code.cs index 4cf8e91..b5209fd 100644 --- a/Sources/CoreLibrary/Core/Code.cs +++ b/Sources/CoreLibrary/Core/Code.cs @@ -1,166 +1,84 @@ 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 { - private readonly ObservableCollection lesJetons = new ObservableCollection(); - - /// - /// Le nombre maximum de jetons dans le code. - /// [DataMember] - public int NbJetonsMax { get; private set; } + private readonly List jetons = new List(); - /// - /// Le nombre de jetons dans le code. - /// + public IReadOnlyList Jetons => jetons; + public int Taille => jetons.Count; [DataMember] - public int NbJetons { get => lesJetons.Count; } + public int TailleMax { get; private init; } + public bool Complet => Taille == TailleMax; + public bool Vide => Taille == 0; - [DataMember] - public ObservableCollection Jetons => lesJetons; - - /// - /// Initialise une nouvelle instance de la classe avec la longueur de code spécifiée. - /// - /// La longueur du code. - /// Levée lorsque la longueur du code spécifiée est inférieure ou égale à zéro. - public Code(int tailleCode) + public Code(int taille) { - NbJetonsMax = tailleCode; + if (taille < 0) + throw new TailleCodeException(taille); - if (tailleCode <= 0) - { - throw new TailleCodeException(tailleCode); - } + TailleMax = taille; } - /// - /// Initialise une nouvelle instance de la classe avec les jetons spécifiés. - /// - /// Les jetons pour initaliser le code. - /// Levée lorsque la collection de jetons spécifiée est vide. - public Code(IEnumerable jetons) - { - if (!jetons.Any()) - { - throw new TailleCodeException(jetons.Count()); - } - - NbJetonsMax = jetons.Count(); - - - - foreach (Jeton jeton in jetons) - { - AjouterJeton(jeton); - } - } - - /// - /// Ajoute un jeton au code. - /// - /// Le jeton à ajouter. - /// Levée lorsque le code est plein. public void AjouterJeton(Jeton jeton) { - if (lesJetons.Count == NbJetonsMax) - { + if (Complet) throw new CodeCompletException(); - } - lesJetons.Add(jeton); + jetons.Add(jeton); } - /// - /// Supprime le dernier jeton ajouté au code. - /// - /// Levée lorsque le code est vide. - public void SupprimerDernierJeton() + public Jeton RecupererJeton(int indice) { - if (lesJetons.Count == 0) - { - throw new CodeVideException(); - } + if (indice < 0 || indice >= Taille) + throw new IndiceCodeException(indice, Taille - 1); - lesJetons.RemoveAt(lesJetons.Count - 1); + return jetons.ElementAt(indice); } - /// - /// Récupère le jeton à l'indice spécifié dans le code. - /// - /// L'indice du jeton a récupéré. - /// Le jeton situé à l'indice spécifié. - /// Levée lorsque l'indice est supérieur à la taille maximale du code, inférieur à 0 ou qu'il n'y a pas de jeton à l'indice spécifié - public Jeton RecupererJeton(int indice) + public void SupprimerDernierJeton() { - if (indice < 0 || indice >= lesJetons.Count) - throw new IndiceCodeException(indice, lesJetons.Count - 1); - - Jeton? jeton = lesJetons[indice]; - - if (!jeton.HasValue) - throw new IndiceCodeException(indice, lesJetons.Count - 1); + if (Vide) + throw new CodeVideException(); - return jeton.Value; + jetons.RemoveAt(Taille - 1); } - /// - /// Vérifie si le code est complet. - /// - /// True si le code est complet, sinon False. - public bool EstComplet() + public IReadOnlyList Comparer(Code code) { - return lesJetons.Count == NbJetonsMax; - } + // Je suis le bon code - /// - /// Compare le code avec un autre code et génère des indicateurs. - /// - /// Le code à comparer avec le code actuel. - /// Les indicateurs de bonne place et bonne couleur entre les deux codes. - public IEnumerable Comparer(Code autreCode) - { - // Mon code est le code correct, l'autre code est celui qui teste + List indicateurs = new List(); - Indicateur[] indicateurs = []; + if (!code.Complet) + throw new CodeIncompletException(); - if (!autreCode.EstComplet()) - return indicateurs; + if (code.TailleMax != TailleMax) + throw new CodeInvalideException(); - List mesJetons = new List(Jetons); - List sesJetons = new List(autreCode.Jetons); + List mesJetons = Jetons.ToList(); + List sesJetons = code.Jetons.ToList(); for (int i = 0; i < mesJetons.Count; ++i) { - Jeton? monJeton = mesJetons[i]; - Jeton? sonJeton = sesJetons[i]; - - if (monJeton.HasValue && sonJeton.HasValue && monJeton.Value.Couleur.Equals(sonJeton.Value.Couleur)) + if (mesJetons[i] == sesJetons[i]) { - indicateurs = indicateurs.Append(Indicateur.BONNEPLACE).ToArray(); - mesJetons[i] = null; - sesJetons[i] = null; + mesJetons.RemoveAt(i); + sesJetons.RemoveAt(i); + indicateurs.Add(Indicateur.BonnePlace); } } - for (int i = 0; i < sesJetons.Count; ++i) { - Jeton? sonJeton = sesJetons[i]; - - if (sonJeton.HasValue && mesJetons.Contains(sonJeton.Value)) + if (mesJetons.Remove(sesJetons[i])) { - indicateurs = indicateurs.Append(Indicateur.BONNECOULEUR).ToArray(); - mesJetons[mesJetons.IndexOf(sonJeton)] = null; - sesJetons[i] = null; + sesJetons.RemoveAt(i); + indicateurs.Add(Indicateur.BonneCouleur); } } @@ -168,5 +86,3 @@ namespace CoreLibrary.Core } } } - - diff --git a/Sources/CoreLibrary/Core/Couleur.cs b/Sources/CoreLibrary/Core/Couleur.cs index 8c6c271..3631c88 100644 --- a/Sources/CoreLibrary/Core/Couleur.cs +++ b/Sources/CoreLibrary/Core/Couleur.cs @@ -1,15 +1,12 @@ namespace CoreLibrary.Core { - /// - /// Enumération des couleurs disponibles pour les jetons. - /// public enum Couleur { - ROUGE, - VERT, - BLEU, - JAUNE, - BLANC, - NOIR + Rouge, + Vert, + Bleu, + Jaune, + Noir, + Blanc } } diff --git a/Sources/CoreLibrary/Core/Indicateur.cs b/Sources/CoreLibrary/Core/Indicateur.cs index c4284d5..ff4f443 100644 --- a/Sources/CoreLibrary/Core/Indicateur.cs +++ b/Sources/CoreLibrary/Core/Indicateur.cs @@ -1,14 +1,8 @@ -using System.Runtime.Serialization; - -namespace CoreLibrary.Core +namespace CoreLibrary.Core { - /// - /// Enumération des indicateurs disponibles pour les jetons. - /// - [DataContract] public enum Indicateur { - BONNEPLACE, - BONNECOULEUR + BonnePlace, + BonneCouleur } } diff --git a/Sources/CoreLibrary/Core/Jeton.cs b/Sources/CoreLibrary/Core/Jeton.cs index 4451cdc..b6cefe4 100644 --- a/Sources/CoreLibrary/Core/Jeton.cs +++ b/Sources/CoreLibrary/Core/Jeton.cs @@ -2,25 +2,29 @@ namespace CoreLibrary.Core { - /// - /// Structure représentant un jeton de couleur - /// [DataContract] - public struct Jeton + public readonly struct Jeton { - /// - /// La couleur du jeton. - /// [DataMember] - public readonly Couleur Couleur { get; private init; } + public Couleur Couleur { get; private init; } - /// - /// Initialise une nouvelle instance de la structure Jeton avec la couleur spécifiée. - /// - /// La couleur du jeton. public Jeton(Couleur couleur) { Couleur = couleur; } + + public override readonly bool Equals(object? objet) + { + if (objet == null || objet is not Jeton) + return false; + + return Couleur == ((Jeton)objet).Couleur; + } + + public static bool operator ==(Jeton gauche, Jeton droite) => gauche.Equals(droite); + + public static bool operator !=(Jeton gauche, Jeton droite) => gauche.Equals(droite); + + public override readonly int GetHashCode() => Couleur.GetHashCode(); } } diff --git a/Sources/CoreLibrary/Core/Plateau.cs b/Sources/CoreLibrary/Core/Plateau.cs index 6d560b5..02a38a4 100644 --- a/Sources/CoreLibrary/Core/Plateau.cs +++ b/Sources/CoreLibrary/Core/Plateau.cs @@ -1,175 +1,82 @@ using CoreLibrary.Exceptions; +using CoreLibrary.Evenements; using System.Runtime.Serialization; using System.Security.Cryptography; namespace CoreLibrary.Core { - /// - /// Classe représentant un plateau de jeu composé de codes et leurs indicateurs ainsi que les méthodes associées. - /// [DataContract] public class Plateau { + public event EventHandler? PlateauAjouterCode; + + private void QuandPlateauAjouterCode() => PlateauAjouterCode?.Invoke(this, new PlateauAjouterCodeEventArgs(this)); + [DataMember] private readonly Code codeSecret; [DataMember] - private readonly Code?[] grille; + private readonly List codes = new List(); [DataMember] - private readonly IEnumerable[] indicateurs; + private readonly List> indicateurs = new List>(); + public int Taille => codes.Count; [DataMember] - private readonly int tailleCode; - - /// - /// Le numéro de tour actuel. - /// + public int TailleMax { get; private init; } [DataMember] - public int Tour { get; private set; } = 1; - - /// - /// La victoire du joueur, True si le joueur a gagné sinon False - /// + public int TailleMaxCode { get; private init; } + public bool Complet => Taille == TailleMax; [DataMember] public bool Victoire { get; private set; } = false; + public (IReadOnlyList>, IReadOnlyList>) Grille => ( + codes.Select(code => code.Jetons).ToList(), + indicateurs + ); - /// - /// Initialise une nouvelle instance de la classe . - /// - /// Taille des codes du plateau. - /// Taille du plateau de jeu. - /// Levée lorsque la tailleCode est inférieure ou égale à 0. - /// Levée lorsque la tailleGrille est inférieure ou égale à 0. - public Plateau(int tailleCode, int tailleGrille) + public Plateau(int tailleCode, int taillePlateau) { - if (tailleCode <= 0) - { + if (tailleCode < 0) throw new TailleCodeException(tailleCode); - } - if (tailleGrille <= 0) - { - throw new TailleGrilleException(tailleGrille); - } - - codeSecret = new Code(tailleCode); - grille = new Code?[tailleGrille]; - indicateurs = new IEnumerable[tailleGrille]; + if (taillePlateau < 0) + throw new TailleGrilleException(taillePlateau); - this.tailleCode = tailleCode; + TailleMax = taillePlateau; + TailleMaxCode = tailleCode; - GenererCodeAleatoire(); + codeSecret = GenererCodeSecret(); } - /// - /// Génère un code secret aléatoire en utilisant des jetons de couleurs aléatoires. - /// - private void GenererCodeAleatoire() + private Code GenererCodeSecret() { - Couleur[] couleurs = (Couleur[])Enum.GetValues(typeof(Couleur)); + Code code = new Code(TailleMaxCode); + Couleur[] couleurs = Enum.GetValues(); - for (int i = 0; i < tailleCode; ++i) + while (!code.Complet) { - codeSecret.AjouterJeton(new Jeton(couleurs[RandomNumberGenerator.GetInt32(0, couleurs.Length)])); + code.AjouterJeton( + new Jeton(couleurs[RandomNumberGenerator.GetInt32(0, couleurs.Length)]) + ); } - } - /// - /// Vérifie si le plateau de jeu est plein. - /// - /// True si la tableau est plein, sinon False. - public bool EstComplet() - { - return Tour - 1 == grille.Length; + return code; } - /// - /// Ajoute le code fourni au plateau de jeu. - /// - /// Le code à ajouter au plateau de jeu. - /// Levée lorsque le code fourni à une taille invalide. - /// Levée lorsque le code fourni est incomplet. public void AjouterCode(Code code) { - if (code.NbJetonsMax != tailleCode) - { - throw new CodeInvalideException(code.NbJetonsMax, tailleCode); - } - - if (!code.EstComplet()) - { + if (!code.Complet) throw new CodeIncompletException(); - } - indicateurs[Tour - 1] = codeSecret.Comparer(code); - grille[Tour - 1] = code; - ++Tour; + if (Complet) + throw new GrilleCompleteException(); - if (EstBonCode(code)) - { - Victoire = true; - } - } + codes.Add(code); + IReadOnlyList indicateurs = codeSecret.Comparer(code); + this.indicateurs.Add(indicateurs.ToList()); - /// - /// Vérifie si le code fourni correspond au code secret. - /// - /// Le code à vérifier. - /// True si le code fourni correspond au code secret, sinon False - /// Levée lorsque le code fourni à une taille invalide. - /// Levée lorsque le code fourni est incomplet. - public bool EstBonCode(Code code) - { - if (code.NbJetonsMax != tailleCode) - { - throw new CodeInvalideException(code.NbJetonsMax, tailleCode); - } - - if (!code.EstComplet()) - { - throw new CodeIncompletException(); - } - - IEnumerable indicateursCode = codeSecret.Comparer(code); - - if (indicateursCode.Count() != tailleCode) - { - return false; - } - - foreach (Indicateur indicateur in indicateursCode) - { - if (indicateur != Indicateur.BONNEPLACE) - { - return false; - } - } - - return true; - } - - /// - /// Récupère le plateau de jeu. - /// - /// Le plateau de jeu représenté sous forme d'un tableau de tableau de jetons. - public IEnumerable> Grille() - { - IEnumerable[] grilleJetons = new IEnumerable[grille.Length]; - - for (int i = 0; i < grille.Length; ++i) - { - grilleJetons[i] = grille[i]?.Jetons ?? new Code(tailleCode).Jetons; - } - return grilleJetons; - } + if (!Victoire && indicateurs.Count(indicateur => indicateur == Indicateur.BonnePlace) == TailleMaxCode) + Victoire = true; - /// - /// Récupère les indicateurs pour chaque tour. - /// - /// Les indicateurs pour chaque tour représentés sous forme d'un tableau de tableau d'indicateurs. - public IEnumerable> Indicateurs() - { - return indicateurs; + QuandPlateauAjouterCode(); } } } - diff --git a/Sources/CoreLibrary/Evenements/JoueurJoueCodeEventArgs.cs b/Sources/CoreLibrary/Evenements/JoueurJoueCodeEventArgs.cs new file mode 100644 index 0000000..fcd9e98 --- /dev/null +++ b/Sources/CoreLibrary/Evenements/JoueurJoueCodeEventArgs.cs @@ -0,0 +1,6 @@ +namespace CoreLibrary.Evenements +{ + public class JoueurJoueCodeEventArgs : EventArgs + { + } +} diff --git a/Sources/CoreLibrary/Evenements/JoueurSeConnecterEventArgs.cs b/Sources/CoreLibrary/Evenements/JoueurSeConnecterEventArgs.cs new file mode 100644 index 0000000..8983132 --- /dev/null +++ b/Sources/CoreLibrary/Evenements/JoueurSeConnecterEventArgs.cs @@ -0,0 +1,14 @@ +using CoreLibrary.Joueurs; + +namespace CoreLibrary.Evenements +{ + public class JoueurSeConnecterEventArgs : EventArgs + { + public Joueur JoueurConnecte { get; private init; } + + public JoueurSeConnecterEventArgs(Joueur joueurConnecte) + { + JoueurConnecte = joueurConnecte; + } + } +} diff --git a/Sources/CoreLibrary/Evenements/PartieDebutPartieEventArgs.cs b/Sources/CoreLibrary/Evenements/PartieDebutPartieEventArgs.cs new file mode 100644 index 0000000..b05bdce --- /dev/null +++ b/Sources/CoreLibrary/Evenements/PartieDebutPartieEventArgs.cs @@ -0,0 +1,6 @@ +namespace CoreLibrary.Evenements +{ + public class PartieDebutPartieEventArgs : EventArgs + { + } +} diff --git a/Sources/CoreLibrary/Evenements/PartieDemanderJoueurEventArgs.cs b/Sources/CoreLibrary/Evenements/PartieDemanderJoueurEventArgs.cs new file mode 100644 index 0000000..419b023 --- /dev/null +++ b/Sources/CoreLibrary/Evenements/PartieDemanderJoueurEventArgs.cs @@ -0,0 +1,16 @@ +using CoreLibrary.Joueurs; + +namespace CoreLibrary.Evenements +{ + public class PartieDemanderJoueurEventArgs : EventArgs + { + public int Indice { get; private init; } + public Joueur JoueurDemande { get; private init; } + + public PartieDemanderJoueurEventArgs(int indice, Joueur joueurDemande) + { + Indice = indice; + JoueurDemande = joueurDemande; + } + } +} diff --git a/Sources/CoreLibrary/Evenements/PartieNouveauTourEventArgs.cs b/Sources/CoreLibrary/Evenements/PartieNouveauTourEventArgs.cs new file mode 100644 index 0000000..9c4e707 --- /dev/null +++ b/Sources/CoreLibrary/Evenements/PartieNouveauTourEventArgs.cs @@ -0,0 +1,21 @@ +using CoreLibrary.Core; +using CoreLibrary.Joueurs; + +namespace CoreLibrary.Evenements +{ + public class PartieNouveauTourEventArgs : EventArgs + { + public int Tour { get; private init; } + public Joueur Joueur { get; private init; } + public Plateau Plateau { get; private init; } + public Code Code { get; private init; } + + public PartieNouveauTourEventArgs(int tour, Joueur joueur, Plateau plateau, Code code) + { + Tour = tour; + Joueur = joueur; + Plateau = plateau; + Code = code; + } + } +} diff --git a/Sources/CoreLibrary/Evenements/PartiePartieTermineeEventArgs.cs b/Sources/CoreLibrary/Evenements/PartiePartieTermineeEventArgs.cs new file mode 100644 index 0000000..c006567 --- /dev/null +++ b/Sources/CoreLibrary/Evenements/PartiePartieTermineeEventArgs.cs @@ -0,0 +1,16 @@ +using CoreLibrary.Joueurs; + +namespace CoreLibrary.Evenements +{ + public class PartiePartieTermineeEventArgs : EventArgs + { + public IReadOnlyList Gagnants { get; private init; } + public IReadOnlyList Perdants { get; private init; } + + public PartiePartieTermineeEventArgs(IReadOnlyList gagnants, IReadOnlyList perdants) + { + Gagnants = gagnants; + Perdants = perdants; + } + } +} diff --git a/Sources/CoreLibrary/Evenements/PartiePasserLaMainEventArgs.cs b/Sources/CoreLibrary/Evenements/PartiePasserLaMainEventArgs.cs new file mode 100644 index 0000000..59fd14a --- /dev/null +++ b/Sources/CoreLibrary/Evenements/PartiePasserLaMainEventArgs.cs @@ -0,0 +1,15 @@ +using CoreLibrary.Joueurs; + +namespace CoreLibrary.Evenements +{ + public class PartiePasserLaMainEventArgs + { + public Joueur Joueur { get; private init; } + + public PartiePasserLaMainEventArgs(Joueur joueur) + { + Joueur = joueur; + } + + } +} diff --git a/Sources/CoreLibrary/Evenements/PlateauAjouterCodeEventArgs.cs b/Sources/CoreLibrary/Evenements/PlateauAjouterCodeEventArgs.cs new file mode 100644 index 0000000..5255fbd --- /dev/null +++ b/Sources/CoreLibrary/Evenements/PlateauAjouterCodeEventArgs.cs @@ -0,0 +1,14 @@ +using CoreLibrary.Core; + +namespace CoreLibrary.Evenements +{ + public class PlateauAjouterCodeEventArgs : EventArgs + { + public Plateau Plateau { get; private init; } + + public PlateauAjouterCodeEventArgs(Plateau plateau) + { + Plateau = plateau; + } + } +} diff --git a/Sources/CoreLibrary/Events/AjouterCodeEventArgs.cs b/Sources/CoreLibrary/Events/AjouterCodeEventArgs.cs deleted file mode 100644 index 59646cb..0000000 --- a/Sources/CoreLibrary/Events/AjouterCodeEventArgs.cs +++ /dev/null @@ -1,24 +0,0 @@ -using CoreLibrary.Core; - -namespace CoreLibrary.Events -{ - /// - /// Classe contenant les arguments passées en paramètre lors de l'événement AjouterCode. - /// - public class AjouterCodeEventArgs : EventArgs - { - /// - /// Le code ajouté. - /// - public Code Code { get; private set; } - - /// - /// Initialise une nouvelle instance de la classe avec le code spécifié. - /// - /// Le code qui a été ajouté. - public AjouterCodeEventArgs(Code code) - { - Code = code; - } - } -} diff --git a/Sources/CoreLibrary/Events/AjouterJoueurEventArgs.cs b/Sources/CoreLibrary/Events/AjouterJoueurEventArgs.cs deleted file mode 100644 index b0efe7d..0000000 --- a/Sources/CoreLibrary/Events/AjouterJoueurEventArgs.cs +++ /dev/null @@ -1,24 +0,0 @@ -using CoreLibrary.Joueurs; - -namespace CoreLibrary.Events -{ - /// - /// Classe contenant les arguments passées en paramètre lors de l'événement AjouterJoueur. - /// - public class AjouterJoueurEventArgs : EventArgs - { - /// - /// Le joueur ajouté. - /// - public Joueur Joueur { get; private set; } - - /// - /// Initialise une nouvelle instance de la classe avec le joueur spécifié. - /// - /// Le joueur qui a été ajouté. - public AjouterJoueurEventArgs(Joueur joueur) - { - Joueur = joueur; - } - } -} diff --git a/Sources/CoreLibrary/Events/ConstruireJoueurEventArgs.cs b/Sources/CoreLibrary/Events/ConstruireJoueurEventArgs.cs deleted file mode 100644 index fcb8577..0000000 --- a/Sources/CoreLibrary/Events/ConstruireJoueurEventArgs.cs +++ /dev/null @@ -1,24 +0,0 @@ -using CoreLibrary.Joueurs; - -namespace CoreLibrary.Events -{ - /// - /// Classe contenant les arguments passées en paramètre lors de l'événement ConstruireJoueurEventArgs. - /// - public class ConstruireJoueurEventArgs : EventArgs - { - /// - /// Le joueur à ajouter. - /// - public Joueur Joueur { get; private set; } - - /// - /// Initialise une nouvelle instance de la classe avec les informations spécifiées. - /// - /// Le joueur à ajouter. - public ConstruireJoueurEventArgs(Joueur joueur) - { - Joueur = joueur; - } - } -} diff --git a/Sources/CoreLibrary/Events/DebutPartieEventArgs.cs b/Sources/CoreLibrary/Events/DebutPartieEventArgs.cs deleted file mode 100644 index 26cf6e0..0000000 --- a/Sources/CoreLibrary/Events/DebutPartieEventArgs.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace CoreLibrary.Events -{ - // - /// Classe contenant les arguments passées en paramètre lors de l'événement DebutPartie - /// - public class DebutPartieEventArgs : EventArgs - { - } -} diff --git a/Sources/CoreLibrary/Events/DemanderNomEventArgs.cs b/Sources/CoreLibrary/Events/DemanderNomEventArgs.cs deleted file mode 100644 index d014733..0000000 --- a/Sources/CoreLibrary/Events/DemanderNomEventArgs.cs +++ /dev/null @@ -1,31 +0,0 @@ -using CoreLibrary.Joueurs; - -namespace CoreLibrary.Events -{ - /// - /// Classe contenant les arguments passées en paramètre lors de l'événement DemanderNom. - /// - public class DemanderNomEventArgs : EventArgs - { - /// - /// L'indice du joueur - /// - public int Indice { get; private set; } - - /// - /// Le constructeur de joueur dans lequel il faut renseigner le nom du joueur - /// - public JoueurBuilder JoueurBuilder { get; private set; } - - /// - /// Initialise une nouvelle instance de la classe avec les informations spécifiées. - /// - /// L'indice du joueur. - /// La classe dans laquelle on attend la réponse du joueur. - public DemanderNomEventArgs(int indice, JoueurBuilder joueurBuilder) - { - Indice = indice; - JoueurBuilder = joueurBuilder; - } - } -} diff --git a/Sources/CoreLibrary/Events/JouerCodeEventArgs.cs b/Sources/CoreLibrary/Events/JouerCodeEventArgs.cs deleted file mode 100644 index fb6f41b..0000000 --- a/Sources/CoreLibrary/Events/JouerCodeEventArgs.cs +++ /dev/null @@ -1,24 +0,0 @@ -using CoreLibrary.Core; - -namespace CoreLibrary.Events -{ - /// - /// Classe contenant les arguments passées en paramètre lors de l'événement JouerCode. - /// - public class JouerCodeEventArgs : EventArgs - { - /// - /// Le code joué par le joueur - /// - public Code Code { get; private set; } - - /// - /// Initialise une nouvelle instance de la classe avec les informations spécifiées. - /// - /// Le code joué par le joueur dont c'est le tour. - public JouerCodeEventArgs(Code code) - { - Code = code; - } - } -} diff --git a/Sources/CoreLibrary/Events/NouveauJoueurEventArgs.cs b/Sources/CoreLibrary/Events/NouveauJoueurEventArgs.cs deleted file mode 100644 index a646a8a..0000000 --- a/Sources/CoreLibrary/Events/NouveauJoueurEventArgs.cs +++ /dev/null @@ -1,22 +0,0 @@ -namespace CoreLibrary.Events -{ - /// - /// Classe contenant les arguments passées en paramètre lors de l'événement NouveauJoueur. - /// - public class NouveauJoueurEventArgs : EventArgs - { - /// - /// Le nom du joueur - /// - public string Nom { get; private set; } - - /// - /// Initialise une nouvelle instance de la classe avec les informations spécifiées. - /// - /// Le nom du joueur. - public NouveauJoueurEventArgs(string nom) - { - Nom = nom; - } - } -} diff --git a/Sources/CoreLibrary/Events/NouveauTourEventArgs.cs b/Sources/CoreLibrary/Events/NouveauTourEventArgs.cs deleted file mode 100644 index 785c673..0000000 --- a/Sources/CoreLibrary/Events/NouveauTourEventArgs.cs +++ /dev/null @@ -1,53 +0,0 @@ -using CoreLibrary.Core; -using CoreLibrary.Joueurs; - -namespace CoreLibrary.Events -{ - /// - /// Classe contenant les arguments passées en paramètre lors de l'événement NouveauTour. - /// - public class NouveauTourEventArgs : EventArgs - { - /// - /// Le joueur dont c'est le tour. - /// - public Joueur Joueur { get; private set; } - - /// - /// Le numéro du tour. - /// - public int Tour { get; private set; } - - /// - /// Le code où ajouter les jetons - /// - public Code Code { get; private set; } - - /// - /// La grille du joueur actuelle. - /// - public IEnumerable> Grille { get; private set; } - - /// - /// Les indicateurs de la grille de jeu. - /// - public IEnumerable> Indicateurs { get; private set; } - - - /// - /// Initialise une nouvelle instance de la classe avec les informations spécifiées. - /// - /// Le joueur dont c'est le tour. - /// Le numéro du tour. - /// La grille du joueur actuelle. - /// Les indicateurs de la grille de jeu. - public NouveauTourEventArgs(Joueur joueur, int tour, Code code, IEnumerable> grille, IEnumerable> indicateurs) - { - Joueur = joueur; - Tour = tour; - Code = code; - Grille = grille; - Indicateurs = indicateurs; - } - } -} \ No newline at end of file diff --git a/Sources/CoreLibrary/Events/PartieTermineeEventArgs.cs b/Sources/CoreLibrary/Events/PartieTermineeEventArgs.cs deleted file mode 100644 index ebf45b5..0000000 --- a/Sources/CoreLibrary/Events/PartieTermineeEventArgs.cs +++ /dev/null @@ -1,31 +0,0 @@ -using CoreLibrary.Joueurs; - -namespace CoreLibrary.Events -{ - /// - /// Classe contenant les arguments passées en paramètre lors de l'événement PartieTerminee. - /// - public class PartieTermineeEventArgs : EventArgs - { - /// - /// Les joueurs gagnants de la partie. - /// - public Joueur[] Gagnants { get; private set; } - - /// - /// Les joueurs perdants de la partie. - /// - public Joueur[] Perdants { get; private set; } - - /// - /// Initialise une nouvelle instance de la classe avec les gagnants et les perdants spécifiés. - /// - /// Les gagnants. - /// Les perdants. - public PartieTermineeEventArgs(Joueur[] gagnants, Joueur[] perdants) - { - Gagnants = gagnants; - Perdants = perdants; - } - } -} diff --git a/Sources/CoreLibrary/Events/PasserMainEventArgs.cs b/Sources/CoreLibrary/Events/PasserMainEventArgs.cs deleted file mode 100644 index 9e6fb3e..0000000 --- a/Sources/CoreLibrary/Events/PasserMainEventArgs.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace CoreLibrary.Events -{ - /// - /// Classe contenant les arguments passées en paramètre lors de l'événement PasserMain. - /// - public class PasserMainEventArgs : EventArgs - { - } -} diff --git a/Sources/CoreLibrary/Exceptions/JoueurDejaConnecteException.cs b/Sources/CoreLibrary/Exceptions/JoueurDejaConnecteException.cs new file mode 100644 index 0000000..f06f56e --- /dev/null +++ b/Sources/CoreLibrary/Exceptions/JoueurDejaConnecteException.cs @@ -0,0 +1,49 @@ +using CoreLibrary.Joueurs; +using System.Runtime.Serialization; + +namespace CoreLibrary.Exceptions +{ + /// + /// Exception levée lorsqu'un joueur se connecte alors qu'il l'est déjà. + /// + [Serializable] + public class JoueurDejaConnecteException : Exception + { + // Message par défaut + private const string messageDefaut = "Le joueur est déjà connecté."; + + /// + /// Initialise une nouvelle instance de la classe avec le message par défaut. + /// + public JoueurDejaConnecteException() : base(messageDefaut) + {} + + /// + /// Initialise une nouvelle instance de la classe avec le message spécifié. + /// + public JoueurDejaConnecteException(string message) : base(message) + {} + + /// + /// Initialise une nouvelle instance de la classe avec le joueur spécifié. + /// + public JoueurDejaConnecteException(Joueur joueur) : base($"Le joueur {joueur.Nom} est déjà connecté.") + { } + + /// + /// Initialise une nouvelle instance de la classe avec le message et l'exception parent spécifiés. + /// + public JoueurDejaConnecteException(string message, Exception exception) : base(message, exception) + {} + + [Obsolete("This method is obsolete. Use alternative methods for data retrieval.", DiagnosticId = "SYSLIB0051")] + protected JoueurDejaConnecteException(SerializationInfo info, StreamingContext contexte) : base(info, contexte) + {} + + [Obsolete("This method is obsolete. Use alternative methods for data retrieval.", DiagnosticId = "SYSLIB0051")] + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + base.GetObjectData(info, context); + } + } +} diff --git a/Sources/CoreLibrary/Exceptions/PartieNonCommenceeException.cs b/Sources/CoreLibrary/Exceptions/PartieNonCommenceeException.cs deleted file mode 100644 index 23fb29b..0000000 --- a/Sources/CoreLibrary/Exceptions/PartieNonCommenceeException.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System.Runtime.Serialization; - -namespace CoreLibrary.Exceptions -{ - /// - /// Exception levée lorsqu'une opération est tentée alors que la partie n'a pas encore commencé. - /// - [Serializable] - public class PartieNonCommenceeException : Exception - { - // Message par défaut - private const string messageDefaut = "La partie n'a pas encore commencée."; - - /// - /// Initialise une nouvelle instance de la classe avec le message par défaut. - /// - public PartieNonCommenceeException() : base(messageDefaut) - { } - - /// - /// Initialise une nouvelle instance de la classe avec le message spécifié. - /// - public PartieNonCommenceeException(string message) : base(message) - { } - - /// - /// Initialise une nouvelle instance de la classe avec le message et l'exception parent spécifiés. - /// - public PartieNonCommenceeException(string message, Exception exception) : base(message, exception) - { } - - [Obsolete("This method is obsolete. Use alternative methods for data retrieval.", DiagnosticId = "SYSLIB0051")] - protected PartieNonCommenceeException(SerializationInfo info, StreamingContext contexte) : base(info, contexte) { } - - [Obsolete("This method is obsolete. Use alternative methods for data retrieval.", DiagnosticId = "SYSLIB0051")] - public override void GetObjectData(SerializationInfo info, StreamingContext context) - { - base.GetObjectData(info, context); - } - } -} diff --git a/Sources/CoreLibrary/Joueurs/Joueur.cs b/Sources/CoreLibrary/Joueurs/Joueur.cs index 6c318a0..f99e528 100644 --- a/Sources/CoreLibrary/Joueurs/Joueur.cs +++ b/Sources/CoreLibrary/Joueurs/Joueur.cs @@ -1,77 +1,55 @@ -using CoreLibrary.Core; -using CoreLibrary.Events; +using CoreLibrary.Exceptions; using CoreLibrary.Persistance; +using CoreLibrary.Evenements; +using CoreLibrary.Regles; +using CoreLibrary.Statistiques; using System.Runtime.Serialization; namespace CoreLibrary.Joueurs { - /// - /// Classe représentant un joueur. - /// [DataContract] + [KnownType(typeof(ReglesClassiques))] public class Joueur : IEstPersistant { - /// - /// Le nom du joueur. - /// - [DataMember] - public string Nom { get; private init; } - [DataMember] - public int NbCoutTotal { get; set; } + public event EventHandler? JoueurSeConnecter; + + private void QuandJoueurSeConnecter() => JoueurSeConnecter?.Invoke(this, new JoueurSeConnecterEventArgs(this)); + [DataMember] - public int NbPartieGagnee { get; set; } + private Dictionary<(IRegles, Statistique), int> statistiques = new Dictionary<(IRegles, Statistique), int>(); + [DataMember] - public int NbPartieEgalite { get; set; } + public string Nom { get; private set; } = ""; [DataMember] - public int NbPartiePerdue { get; set; } - - /// - /// Crée une nouvelle instance de joueur avec un nom - /// Evénement appelé pour jouer un code. - /// - public event EventHandler? JouerCode; + public bool EstConnecte { get; private set; } = false; - /// - /// Appel de l'événement JouerCode. - /// - private void QuandJouerCode(Code code) => JouerCode?.Invoke(this, new JouerCodeEventArgs(code)); - - /// - /// Crée une nouvelle instance de joueur avec un nom et un plateau spécifié. - /// - /// Le nom du joueur. - public Joueur(string nom) + public Joueur() { - Nom = nom; - NbCoutTotal = 0; - NbPartieGagnee = 0; - NbPartieEgalite = 0; - NbPartiePerdue = 0; } - public Joueur(string nom, int nbCoutTotal, int nbPartieGagnee, int nbPartieEgalite, int nbPartiePerdue) + public Joueur(string nom) { Nom = nom; - NbCoutTotal = nbCoutTotal; - NbPartieGagnee = nbPartieGagnee; - NbPartieEgalite = nbPartieEgalite; - NbPartiePerdue = nbPartiePerdue; } - public void Code(Code code) + public Joueur SeConnecter(Joueur joueur) { - ++NbCoutTotal; - QuandJouerCode(code); - } + if (EstConnecte) + throw new JoueurDejaConnecteException(this); - public void AGagne() => ++NbPartieGagnee; - public void APerdu() => ++NbPartiePerdue; - public void AEgalite() => ++NbPartieEgalite; + Nom = joueur.Nom; + statistiques = joueur.statistiques; + EstConnecte = true; + QuandJoueurSeConnecter(); - public override String ToString() - { - return Nom; + return this; } + + public int Statistique(IRegles regles, Statistique statistique) => + statistiques.GetValueOrDefault((regles, statistique), 0); + + public void IncrementerStatistique(IRegles regles, Statistique statistique) => + statistiques[(regles, statistique)] = Statistique(regles, statistique) + 1; } } diff --git a/Sources/CoreLibrary/Joueurs/JoueurBuilder.cs b/Sources/CoreLibrary/Joueurs/JoueurBuilder.cs deleted file mode 100644 index 6a0f3bf..0000000 --- a/Sources/CoreLibrary/Joueurs/JoueurBuilder.cs +++ /dev/null @@ -1,16 +0,0 @@ -using CoreLibrary.Events; - -namespace CoreLibrary.Joueurs -{ - public class JoueurBuilder - { - public event EventHandler? ConstruireJoueur; - - private void QuandConstruireJoueur(Joueur joueur) => ConstruireJoueur?.Invoke(this, new ConstruireJoueurEventArgs(joueur)); - - public void Joueur(Joueur joueur) - { - QuandConstruireJoueur(joueur); - } - } -} diff --git a/Sources/CoreLibrary/Manageur/Manageur.cs b/Sources/CoreLibrary/Manageur/Manageur.cs deleted file mode 100644 index ef9ff11..0000000 --- a/Sources/CoreLibrary/Manageur/Manageur.cs +++ /dev/null @@ -1,57 +0,0 @@ -using CoreLibrary.Events; -using CoreLibrary.Joueurs; -using CoreLibrary.Persistance; -using System.Collections.Generic; - -namespace CoreLibrary.Manager -{ - public class Manageur - { - private readonly List joueurs; - private readonly List parties; - private readonly IPersistance persistance; - private Partie? partie; - - public IReadOnlyCollection Joueurs => joueurs; - public IReadOnlyCollection Parties => parties; - public Partie? Partie => partie; - - public Manageur(IPersistance persistance) - { - this.persistance = persistance; - joueurs = persistance.Charger().ToList(); - parties = persistance.Charger().ToList(); - } - - public void NouvellePartie(Partie partie) - { - this.partie = partie; - - parties.Add(partie); - - partie.PasserMain += (object? sender, PasserMainEventArgs e) => - { - persistance.Enregistrer(parties.ToArray()); - persistance.Enregistrer(joueurs.ToArray()); - }; - - partie.PartieTerminee += (object? sender, PartieTermineeEventArgs e) => - { - persistance.Enregistrer(parties.ToArray()); - persistance.Enregistrer(joueurs.ToArray()); - }; - } - - public Joueur DemanderJoueur(string nom) - { - foreach (Joueur joueur in joueurs) - { - if (joueur.Nom == nom) - return joueur; - } - Joueur nouveauJoueur = new Joueur(nom); - joueurs.Add(nouveauJoueur); - return nouveauJoueur; - } - } -} diff --git a/Sources/CoreLibrary/Manageurs/Manageur.cs b/Sources/CoreLibrary/Manageurs/Manageur.cs new file mode 100644 index 0000000..236f51c --- /dev/null +++ b/Sources/CoreLibrary/Manageurs/Manageur.cs @@ -0,0 +1,76 @@ +using CoreLibrary.Persistance; +using CoreLibrary.Joueurs; +using CoreLibrary.Regles; +using CoreLibrary.Statistiques; + +namespace CoreLibrary.Manageurs +{ + public class Manageur + { + private readonly IPersistance persistance; + private readonly List joueurs; + private readonly List parties; + + public Manageur(IPersistance persistance) + { + this.persistance = persistance; + + joueurs = persistance.Charger().ToList(); + parties = persistance.Charger().ToList(); + } + + private void Sauvegarder() + { + persistance.Enregistrer(joueurs.ToArray()); + persistance.Enregistrer(parties.ToArray()); + } + + public Partie NouvellePartie(IRegles regles) + { + Partie partie = new Partie(regles); + + parties.Add(partie); + + partie.PartiePasserLaMain += (sender, e) => e.Joueur.IncrementerStatistique(partie.Regles, Statistique.CoupJoue); + + partie.PartieNouveauTour += (sender, e) => Sauvegarder(); + + partie.PartiePartieTerminee += (sender, e) => + { + if (e.Gagnants.Count == 1) + { + e.Gagnants[0].IncrementerStatistique(regles, Statistique.PartieGagnee); + } + else + { + foreach (Joueur gagnant in e.Gagnants) + gagnant.IncrementerStatistique(regles, Statistique.PartieEgalite); + } + + foreach (Joueur perdant in e.Perdants) + { + perdant.IncrementerStatistique(regles, Statistique.PartiePerdue); + } + }; + + return partie; + } + + public Joueur DemanderJoueur(string nom) + { + foreach (Joueur joueur in joueurs) + { + if (joueur.Nom == nom) + { + return joueur; + } + } + + Joueur nouveauJoueur = new Joueur(nom); + + joueurs.Add(nouveauJoueur); + + return nouveauJoueur; + } + } +} diff --git a/Sources/CoreLibrary/Partie.cs b/Sources/CoreLibrary/Partie.cs index 5cc4a2a..2c0ee43 100644 --- a/Sources/CoreLibrary/Partie.cs +++ b/Sources/CoreLibrary/Partie.cs @@ -1,217 +1,118 @@ -using CoreLibrary.Core; -using CoreLibrary.Events; +using CoreLibrary.Persistance; +using CoreLibrary.Core; +using CoreLibrary.Evenements; using CoreLibrary.Joueurs; -using CoreLibrary.Persistance; using CoreLibrary.Regles; using System.Runtime.Serialization; namespace CoreLibrary { - /// - /// Représente une partie de jeu. - /// [DataContract] [KnownType(typeof(ReglesClassiques))] public class Partie : IEstPersistant { - [DataMember] - public IRegles Regles { get; private set; } - + public event EventHandler? PartieDemanderJoueur; + public event EventHandler? PartieDebutPartie; + public event EventHandler? PartieNouveauTour; + public event EventHandler? PartiePasserLaMain; + public event EventHandler? PartiePartieTerminee; + + private void QuandPartieDemanderJoueur(Joueur joueurDemande) => PartieDemanderJoueur?.Invoke(this, new PartieDemanderJoueurEventArgs(joueurs.Count + 1, joueurDemande)); + private void QuandPartieDebutPartie() => PartieDebutPartie?.Invoke(this, new PartieDebutPartieEventArgs()); + private void QuandPartieNouveauTour() => PartieNouveauTour?.Invoke(this, new PartieNouveauTourEventArgs(plateaux.ElementAt(courant).Taille + 1, joueurs.ElementAt(courant), plateaux.ElementAt(courant), new Code(Regles.TailleCode))); + private void QuandPartiePasserLaMain() => PartiePasserLaMain?.Invoke(this, new PartiePasserLaMainEventArgs(joueurs.ElementAt(courant))); + private void QuandPartiePartieTerminee(IReadOnlyList gagnants, IReadOnlyList perdants) => PartiePartieTerminee?.Invoke(this, new PartiePartieTermineeEventArgs(gagnants, perdants)); + [DataMember] private readonly List joueurs = new List(); [DataMember] private readonly List plateaux = new List(); [DataMember] - private int? courant; - - /// - /// Événement déclenché lorsqu'il est nécessaire de d'ajouter un joueur. - /// - public event EventHandler? DemanderNom; - - /// - /// Événement déclenché lorsqu'il est nécessaire d'ajouter un joueur. - /// - public event EventHandler? AjouterJoueur; - - /// - /// Événement déclenché lorsqu'une partie commence. - /// - public event EventHandler? DebutPartie; - - /// - /// Événement déclenché lorsqu'un nouveau tour commence. - /// - public event EventHandler? NouveauTour; - - /// - /// Événement déclenché lorsqu'un code est ajouté. - /// - public event EventHandler? AjouterCode; - - /// - /// Événement déclenché lorsque la main est passée au joueur suivant. - /// - public event EventHandler? PasserMain; - - /// - /// Événement déclenché lorsque la partie est terminée. - /// - public event EventHandler? PartieTerminee; - - /// - /// Méthode pour déclencher l'événement de demande du nom d'un joueur. - /// - /// Le numéro du joueur à ajouter - /// La classe dans laquelle le nom doit être défini - private void QuandDemanderNom(int numero, JoueurBuilder joueurBuilder) => DemanderNom?.Invoke(this, new DemanderNomEventArgs(numero, joueurBuilder)); - - /// - /// Méthode pour déclencher l'événement d'ajout d'un joueur. - /// - /// Le joueur à ajouter. - private void QuandAjouterJoueur(Joueur joueur) => AjouterJoueur?.Invoke(this, new AjouterJoueurEventArgs(joueur)); - - /// - /// Méthode pour déclencher l'événement du début d'un partie. - /// - private void QuandDebutPartie() => DebutPartie?.Invoke(this, new DebutPartieEventArgs()); - - /// - /// Méthode pour déclencher l'événement d'un nouveau tour. - /// - /// Le joueur dont c'est le tour. - /// Le numéro du tour. - /// Le code dans lequel il faut ajouter les jetons. - /// La grille de jeu. - /// Les indicateurs de jeu. - private void QuandNouveauTour(Joueur joueur, int tour, Code code, IEnumerable> grille, IEnumerable> indicateurs) => NouveauTour?.Invoke(this, new NouveauTourEventArgs(joueur, tour, code, grille, indicateurs)); - - /// - /// Méthode pour déclencher l'événement d'ajout d'un nouveau code. - /// - /// Le code ajouté. - private void QuandAjouterCode(Code code) => AjouterCode?.Invoke(this, new AjouterCodeEventArgs(code)); - - /// - /// Méthode pour déclencher l'événement de passage de la main au joueur suivant. - /// - private void QuandPasserMain() => PasserMain?.Invoke(this, new PasserMainEventArgs()); - - /// - /// Méthode pour déclencher l'événement de fin de partie. - /// - /// La liste des joueurs gagnants. - /// La liste des joueurs perdants. - private void QuandPartieTerminee(Joueur[] gagnants, Joueur[] perdants) => PartieTerminee?.Invoke(this, new PartieTermineeEventArgs(gagnants, perdants)); - - /// - /// Crée une nouvelle instance de la classe Partie. - /// - /// Les règles de la partie. - /// Persistance de la partie. + private int courant = 0; + + [DataMember] + public IRegles Regles { get; private init; } + public Partie(IRegles regles) { Regles = regles; } - /// - /// Lance le déroulement de la partie. - /// public void Jouer() { - JoueurBuilder joueurBuilder = new JoueurBuilder(); - joueurBuilder.ConstruireJoueur += Joueur; + DemanderJoueur(); + } + + private void DemanderJoueur() + { + Joueur joueurDemande = new Joueur(); + joueurDemande.JoueurSeConnecter += JoueurConnecte; - QuandDemanderNom(joueurs.Count + 1, joueurBuilder); + QuandPartieDemanderJoueur(joueurDemande); } - /// - /// Un joueur a saisi son nom - /// - private void Joueur(Object? sender, ConstruireJoueurEventArgs e) + private void JoueurConnecte(object? sender, JoueurSeConnecterEventArgs e) { - Joueur joueur = e.Joueur; - Plateau plateau = new Plateau(Regles.TailleCodeMaximum, Regles.TourMaximum); + Plateau plateau = new Plateau(Regles.TailleCode, Regles.NbTour); + plateau.PlateauAjouterCode += PlateauAjouterCode; - joueurs.Add(joueur); + joueurs.Add(e.JoueurConnecte); plateaux.Add(plateau); - QuandAjouterJoueur(joueur); - joueur.JouerCode += Tour; - if (joueurs.Count != Regles.NbJoueursMaximum) + if (joueurs.Count < Regles.NbJoueurs) { - JoueurBuilder joueurBuilder = new JoueurBuilder(); - joueurBuilder.ConstruireJoueur += Joueur; - QuandDemanderNom(joueurs.Count + 1, joueurBuilder); + DemanderJoueur(); } else { - Commencer(); + DebutPartie(); } } - /// - /// La partie démarre - /// - private void Commencer() + private void DebutPartie() { - courant = 0; - Joueur joueurCourant = joueurs[courant.Value]; - Plateau plateauCourant = plateaux[courant.Value]; - QuandDebutPartie(); - - QuandNouveauTour(joueurCourant, plateauCourant.Tour, new Code(Regles.TailleCodeMaximum), plateauCourant.Grille(), plateauCourant.Indicateurs()); + QuandPartieDebutPartie(); + NouveauTour(); } - /// - /// Un joueur a joué son tour - /// - private void Tour(Object? sender, JouerCodeEventArgs e) + private void NouveauTour() { - Plateau plateauCourant = plateaux[courant!.Value]; + QuandPartieNouveauTour(); + } - plateauCourant.AjouterCode(e.Code); - QuandAjouterCode(e.Code); + private void PlateauAjouterCode(object? sender, PlateauAjouterCodeEventArgs e) + { + QuandPartiePasserLaMain(); - if (++courant == joueurs.Count) - courant = 0; - QuandPasserMain(); - - if (courant == 0 && (plateauCourant.Tour > Regles.TourMaximum || plateaux.Where(plateau => plateau.Victoire).Any())) + if (courant + 1 == joueurs.Count && (e.Plateau.Complet || plateaux.Any(plateau => plateau.Victoire))) { - Terminee(); + PartieTerminee(); } else { - Joueur joueurCourant = joueurs[courant!.Value]; - plateauCourant = plateaux[courant!.Value]; - QuandNouveauTour(joueurCourant, plateauCourant.Tour, new Code(Regles.TailleCodeMaximum), plateauCourant.Grille(), plateauCourant.Indicateurs()); + if (courant + 1 == joueurs.Count) + courant = 0; + else + ++courant; + + NouveauTour(); } } - /// - /// La partie est terminée - /// - private void Terminee() + private void PartieTerminee() { - foreach(Joueur joueur in joueurs) - { - joueur.JouerCode -= Tour; - } - List gagnants = new List(); List perdants = new List(); - for (int i = 0; i < joueurs.Count; i++) + for (int i = 0; i < joueurs.Count; ++i) { - if (plateaux[i].Victoire) + if (plateaux.ElementAt(i).Victoire) gagnants.Add(joueurs[i]); else perdants.Add(joueurs[i]); } - QuandPartieTerminee(gagnants.ToArray(), perdants.ToArray()); + QuandPartiePartieTerminee(gagnants, perdants); } } } diff --git a/Sources/CoreLibrary/Persistance/IPersistance.cs b/Sources/CoreLibrary/Persistance/IPersistance.cs index 3f90645..d3ebed8 100644 --- a/Sources/CoreLibrary/Persistance/IPersistance.cs +++ b/Sources/CoreLibrary/Persistance/IPersistance.cs @@ -1,6 +1,4 @@ - using CoreLibrary.Joueurs; - -namespace CoreLibrary.Persistance +namespace CoreLibrary.Persistance { public interface IPersistance { diff --git a/Sources/CoreLibrary/Persistance/PersistanceJSON.cs b/Sources/CoreLibrary/Persistance/PersistanceJSON.cs index f41a8c3..51bbed5 100644 --- a/Sources/CoreLibrary/Persistance/PersistanceJSON.cs +++ b/Sources/CoreLibrary/Persistance/PersistanceJSON.cs @@ -6,17 +6,19 @@ namespace CoreLibrary.Persistance { public class PersistanceJSON : IPersistance { + private readonly string dossier = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "../../../.."); + private readonly string nomDossier = "Fichiers"; public T[] Charger() where T : IEstPersistant { string fichier = $"{typeof(T).Name.ToLower()}s.json"; - Directory.SetCurrentDirectory(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "../../../../../../..")); + Directory.SetCurrentDirectory(dossier); - if (!Directory.Exists("Fichiers")) + if (!Directory.Exists(nomDossier)) return []; - Directory.SetCurrentDirectory(Path.Combine(Directory.GetCurrentDirectory(), "Fichiers")); + Directory.SetCurrentDirectory(Path.Combine(Directory.GetCurrentDirectory(), nomDossier)); if (!File.Exists(fichier)) return []; @@ -36,18 +38,18 @@ namespace CoreLibrary.Persistance { string fichier = $"{typeof(T).Name.ToLower()}s.json"; - Directory.SetCurrentDirectory(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "../../../../../../..")); + Directory.SetCurrentDirectory(dossier); - if (!Directory.Exists("Fichiers")) - Directory.CreateDirectory("Fichiers"); + if (!Directory.Exists(nomDossier)) + Directory.CreateDirectory(nomDossier); - Directory.SetCurrentDirectory(Path.Combine(Directory.GetCurrentDirectory(), "Fichiers")); + Directory.SetCurrentDirectory(Path.Combine(Directory.GetCurrentDirectory(), nomDossier)); DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(T[])); - using(FileStream s = File.Create(fichier)) + using (FileStream s = File.Create(fichier)) { - using(XmlDictionaryWriter writer = JsonReaderWriterFactory.CreateJsonWriter( + using (XmlDictionaryWriter writer = JsonReaderWriterFactory.CreateJsonWriter( s, Encoding.UTF8, false, @@ -58,4 +60,4 @@ namespace CoreLibrary.Persistance } } } -} \ No newline at end of file +} diff --git a/Sources/CoreLibrary/Regles/IRegles.cs b/Sources/CoreLibrary/Regles/IRegles.cs index aea134c..27ab32e 100644 --- a/Sources/CoreLibrary/Regles/IRegles.cs +++ b/Sources/CoreLibrary/Regles/IRegles.cs @@ -1,31 +1,10 @@ - -using System.Runtime.Serialization; - -namespace CoreLibrary.Regles +namespace CoreLibrary.Regles { - /// - /// Interface définissant les règles du jeu. - /// public interface IRegles { - /// - /// Le nom des règles du jeu. - /// string Nom { get; } - - /// - /// Le nombre de maximum de tours. - /// - int TourMaximum { get; } - - /// - /// La taille maximal du code. - /// - int TailleCodeMaximum { get; } - - /// - /// Le nombre maximum de joueurs. - /// - int NbJoueursMaximum { get; } + int NbJoueurs { get; } + int NbTour { get; } + int TailleCode { get; } } } diff --git a/Sources/CoreLibrary/Regles/ReglesClassiques.cs b/Sources/CoreLibrary/Regles/ReglesClassiques.cs index ca65851..6a8723c 100644 --- a/Sources/CoreLibrary/Regles/ReglesClassiques.cs +++ b/Sources/CoreLibrary/Regles/ReglesClassiques.cs @@ -2,34 +2,12 @@ namespace CoreLibrary.Regles { - /// - /// Classe définissant les règles classiques du jeu. - /// [DataContract] public class ReglesClassiques : IRegles { - /// - /// Le nom des règles. - /// - [DataMember] - public string Nom { get => "Règles classiques"; } - - /// - /// Le nombre maximum de tour. - /// - [DataMember] - public int TourMaximum { get => 12; } - - /// - /// La taille maximale d'un code. - /// - [DataMember] - public int TailleCodeMaximum { get => 4; } - - /// - /// Me nombre maximum de joueurs possibles pour le jeu. - /// - [DataMember] - public int NbJoueursMaximum { get => 2; } + public string Nom => "Règles classiques"; + public int NbJoueurs => 2; + public int NbTour => 12; + public int TailleCode => 4; } } diff --git a/Sources/CoreLibrary/Statistiques/Statistique.cs b/Sources/CoreLibrary/Statistiques/Statistique.cs new file mode 100644 index 0000000..e32c738 --- /dev/null +++ b/Sources/CoreLibrary/Statistiques/Statistique.cs @@ -0,0 +1,10 @@ +namespace CoreLibrary.Statistiques +{ + public enum Statistique + { + PartieGagnee, + PartiePerdue, + PartieEgalite, + CoupJoue + } +} diff --git a/Sources/mastermind.sln b/Sources/mastermind.sln index 4816ed0..af9bf58 100644 --- a/Sources/mastermind.sln +++ b/Sources/mastermind.sln @@ -14,8 +14,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTesting", "UnitTesting\ {341FB405-085D-4C34-B395-64EF0F9B93E0} = {341FB405-085D-4C34-B395-64EF0F9B93E0} EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleApp1", "ConsoleApp1\ConsoleApp1.csproj", "{69A6F940-1A25-4FC0-83E3-ABEFA4003DD6}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -40,10 +38,6 @@ Global {A2182054-C0D1-46D6-BD39-F3F7926CE2DD}.Debug|Any CPU.Build.0 = Debug|Any CPU {A2182054-C0D1-46D6-BD39-F3F7926CE2DD}.Release|Any CPU.ActiveCfg = Release|Any CPU {A2182054-C0D1-46D6-BD39-F3F7926CE2DD}.Release|Any CPU.Build.0 = Release|Any CPU - {69A6F940-1A25-4FC0-83E3-ABEFA4003DD6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {69A6F940-1A25-4FC0-83E3-ABEFA4003DD6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {69A6F940-1A25-4FC0-83E3-ABEFA4003DD6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {69A6F940-1A25-4FC0-83E3-ABEFA4003DD6}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE