using CoreLibrary.Persistance; using CoreLibrary.Core; using CoreLibrary.Evenements; using CoreLibrary.Joueurs; using CoreLibrary.Regles; using System.Runtime.Serialization; namespace CoreLibrary { [DataContract] [KnownType(typeof(ReglesClassiques))] [KnownType(typeof(ReglesDifficiles))] public class Partie : IEstPersistant { public event EventHandler? PartieDemanderJoueur; public event EventHandler? PartieDebutPartie; public event EventHandler? PartieDemanderJoueurJouer; 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 QuandPartieDemanderJoueurJouer(Code code) => PartieDemanderJoueurJouer?.Invoke(this, new PartieDemanderJoueurJouerEventArgs(Tour, Joueurs.ElementAt(courant), plateaux.ElementAt(courant), code, joueurs[Joueurs.ElementAt(courant)])); private void QuandPartieNouveauTour(Code code) => PartieNouveauTour?.Invoke(this, new PartieNouveauTourEventArgs(Tour, Joueurs.ElementAt(courant), plateaux.ElementAt(courant), code, joueurs[Joueurs.ElementAt(courant)])); 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 Dictionary joueurs = new Dictionary(); [DataMember] private readonly List plateaux = new List(); [DataMember] private int courant = 0; public IReadOnlyList Joueurs => joueurs.Keys.ToList(); public IReadOnlyList Robots => joueurs.Where(joueur => joueur.Value).Select(joueur => joueur.Key).ToList(); [DataMember] public bool Termine { get; private set; } = false; [DataMember] public int Tour { get; private set; } = 0; [DataMember] public IRegles Regles { get; private init; } public Partie(IRegles regles) { Regles = regles; } public Partie(Partie partie) { joueurs = partie.joueurs; plateaux = partie.plateaux; courant = partie.courant; Tour = partie.Tour; Regles = partie.Regles; partie.PartieDemanderJoueur = null; partie.PartieDebutPartie = null; partie.PartieDemanderJoueurJouer = null; partie.PartieNouveauTour = null; partie.PartiePasserLaMain = null; partie.PartiePartieTerminee = null; foreach (string joueur in Joueurs) (joueurs[joueur] ? new Joueur(joueur) : new Robot(joueur)).JouerPartie(this); } public void Jouer() { if (joueurs.Count != Regles.NbJoueurs) DemanderJoueur(); else DebutPartie(); } private void DemanderJoueur() { Joueur joueurDemande = new Joueur(); joueurDemande.JoueurSeConnecter += JoueurConnecte; QuandPartieDemanderJoueur(joueurDemande); } private void JoueurConnecte(object? sender, JoueurSeConnecterEventArgs e) { joueurs.Add(e.Joueur.Nom, e.Joueur.GetType().Equals(typeof(Joueur))); plateaux.Add(new Plateau(Regles.TailleCode, Regles.NbTour)); e.Joueur.JouerPartie(this); if (joueurs.Count < Regles.NbJoueurs) { DemanderJoueur(); } else { DebutPartie(); } } private void DebutPartie() { if (Tour == 0) ++Tour; foreach (Plateau plateau in plateaux) { plateau.PlateauAjouterCode += PlateauAjouterCode; } QuandPartieDebutPartie(); NouveauTour(); } private void NouveauTour() { Code code = new Code(Regles.TailleCode); QuandPartieDemanderJoueurJouer(code); QuandPartieNouveauTour(code); } private void PlateauAjouterCode(object? sender, PlateauAjouterCodeEventArgs e) { QuandPartiePasserLaMain(); if (courant + 1 == joueurs.Count && (e.Plateau.Complet || plateaux.Any(plateau => plateau.Victoire))) { PartieTerminee(); } else { if (courant + 1 == joueurs.Count) { ++Tour; courant = 0; } else ++courant; NouveauTour(); } } private void PartieTerminee() { Termine = true; List gagnants = new List(); List perdants = new List(); for (int i = 0; i < joueurs.Count; ++i) { if (plateaux.ElementAt(i).Victoire) gagnants.Add(Joueurs[i]); else perdants.Add(Joueurs[i]); } QuandPartiePartieTerminee(gagnants, perdants); } } }