using CoreLibrary.Core; using CoreLibrary.Events; using CoreLibrary.Joueurs; using CoreLibrary.Regles; namespace CoreLibrary { /// /// Représente une partie de jeu. /// public class Partie { public IRegles Regles { get; private set; } /// /// É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(IEnumerable gagnants, IEnumerable perdants) => PartieTerminee?.Invoke(this, new PartieTermineeEventArgs(gagnants, perdants)); /// /// Crée une nouvelle instance de la classe Partie. /// /// Les règles de la partie. public Partie(IRegles regles) { this.regles = regles; } /// /// Lance le déroulement de la partie. /// public void Jouer() { JoueurBuilder joueurBuilder = new JoueurBuilder(); joueurBuilder.ConstruireJoueur += Joueur; QuandDemanderNom(regles.NbJoueurs + 1, joueurBuilder); } /// /// Un joueur a saisi son nom /// private void Joueur(Object? sender, ConstruireJoueurEventArgs e) { Joueur joueur = regles.AjouterJoueur(e.Nom ?? $"Joueur {regles.NbJoueurs + 1}"); QuandAjouterJoueur(joueur); joueur.JouerCode += Tour; if (regles.NbJoueurs != regles.NbJoueursMaximum) { JoueurBuilder joueurBuilder = new JoueurBuilder(); joueurBuilder.ConstruireJoueur += Joueur; QuandDemanderNom(regles.NbJoueurs + 1, joueurBuilder); } else { Commencer(); } } /// /// La partie démarre /// private void Commencer() { regles.CommencerLaPartie(); QuandDebutPartie(); (Joueur joueurCourant, Plateau plateauCourant) = regles.JoueurCourant(); QuandNouveauTour(joueurCourant, plateauCourant.Tour, regles.GenererCode(), plateauCourant.Grille(), plateauCourant.Indicateurs()); } /// /// Un joueur a joué son tour /// private void Tour(Object? sender, JouerCodeEventArgs e) { (Joueur joueurCourant, Plateau plateauCourant) = regles.JoueurCourant(); plateauCourant.AjouterCode(e.Code); QuandAjouterCode(e.Code); if(regles.EstTerminee()) { Terminee(); } else { regles.PasserLaMain(); QuandPasserMain(); (joueurCourant, plateauCourant) = regles.JoueurCourant(); QuandNouveauTour(joueurCourant, plateauCourant.Tour, regles.GenererCode(), plateauCourant.Grille(), plateauCourant.Indicateurs()); } } /// /// La partie est terminée /// private void Terminee() { QuandPartieTerminee(regles.Gagnants(), regles.Perdants()); } } }