|
|
|
@ -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
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Représente une partie de jeu.
|
|
|
|
|
/// </summary>
|
|
|
|
|
[DataContract]
|
|
|
|
|
[KnownType(typeof(ReglesClassiques))]
|
|
|
|
|
public class Partie : IEstPersistant
|
|
|
|
|
{
|
|
|
|
|
[DataMember]
|
|
|
|
|
public IRegles Regles { get; private set; }
|
|
|
|
|
public event EventHandler<PartieDemanderJoueurEventArgs>? PartieDemanderJoueur;
|
|
|
|
|
public event EventHandler<PartieDebutPartieEventArgs>? PartieDebutPartie;
|
|
|
|
|
public event EventHandler<PartieNouveauTourEventArgs>? PartieNouveauTour;
|
|
|
|
|
public event EventHandler<PartiePasserLaMainEventArgs>? PartiePasserLaMain;
|
|
|
|
|
public event EventHandler<PartiePartieTermineeEventArgs>? 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<Joueur> gagnants, IReadOnlyList<Joueur> perdants) => PartiePartieTerminee?.Invoke(this, new PartiePartieTermineeEventArgs(gagnants, perdants));
|
|
|
|
|
|
|
|
|
|
[DataMember]
|
|
|
|
|
private readonly List<Joueur> joueurs = new List<Joueur>();
|
|
|
|
|
[DataMember]
|
|
|
|
|
private readonly List<Plateau> plateaux = new List<Plateau>();
|
|
|
|
|
[DataMember]
|
|
|
|
|
private int? courant;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Événement déclenché lorsqu'il est nécessaire de d'ajouter un joueur.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public event EventHandler<DemanderNomEventArgs>? DemanderNom;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Événement déclenché lorsqu'il est nécessaire d'ajouter un joueur.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public event EventHandler<AjouterJoueurEventArgs>? AjouterJoueur;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Événement déclenché lorsqu'une partie commence.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public event EventHandler<DebutPartieEventArgs>? DebutPartie;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Événement déclenché lorsqu'un nouveau tour commence.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public event EventHandler<NouveauTourEventArgs>? NouveauTour;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Événement déclenché lorsqu'un code est ajouté.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public event EventHandler<AjouterCodeEventArgs>? AjouterCode;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Événement déclenché lorsque la main est passée au joueur suivant.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public event EventHandler<PasserMainEventArgs>? PasserMain;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Événement déclenché lorsque la partie est terminée.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public event EventHandler<PartieTermineeEventArgs>? PartieTerminee;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Méthode pour déclencher l'événement de demande du nom d'un joueur.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="numero">Le numéro du joueur à ajouter</param>
|
|
|
|
|
/// <param name="joueurBuilder">La classe dans laquelle le nom doit être défini</param>
|
|
|
|
|
private void QuandDemanderNom(int numero, JoueurBuilder joueurBuilder) => DemanderNom?.Invoke(this, new DemanderNomEventArgs(numero, joueurBuilder));
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Méthode pour déclencher l'événement d'ajout d'un joueur.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="joueur">Le joueur à ajouter.</param>
|
|
|
|
|
private void QuandAjouterJoueur(Joueur joueur) => AjouterJoueur?.Invoke(this, new AjouterJoueurEventArgs(joueur));
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Méthode pour déclencher l'événement du début d'un partie.
|
|
|
|
|
/// </summary>
|
|
|
|
|
private void QuandDebutPartie() => DebutPartie?.Invoke(this, new DebutPartieEventArgs());
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Méthode pour déclencher l'événement d'un nouveau tour.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="joueur">Le joueur dont c'est le tour.</param>
|
|
|
|
|
/// <param name="tour">Le numéro du tour.</param>
|
|
|
|
|
/// <param name="code">Le code dans lequel il faut ajouter les jetons.</param>
|
|
|
|
|
/// <param name="grille">La grille de jeu.</param>
|
|
|
|
|
/// <param name="indicateurs">Les indicateurs de jeu.</param>
|
|
|
|
|
private void QuandNouveauTour(Joueur joueur, int tour, Code code, IEnumerable<IEnumerable<Jeton?>> grille, IEnumerable<IEnumerable<Indicateur>> indicateurs) => NouveauTour?.Invoke(this, new NouveauTourEventArgs(joueur, tour, code, grille, indicateurs));
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Méthode pour déclencher l'événement d'ajout d'un nouveau code.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="code">Le code ajouté.</param>
|
|
|
|
|
private void QuandAjouterCode(Code code) => AjouterCode?.Invoke(this, new AjouterCodeEventArgs(code));
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Méthode pour déclencher l'événement de passage de la main au joueur suivant.
|
|
|
|
|
/// </summary>
|
|
|
|
|
private void QuandPasserMain() => PasserMain?.Invoke(this, new PasserMainEventArgs());
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Méthode pour déclencher l'événement de fin de partie.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="gagnants">La liste des joueurs gagnants.</param>
|
|
|
|
|
/// <param name="perdants">La liste des joueurs perdants.</param>
|
|
|
|
|
private void QuandPartieTerminee(Joueur[] gagnants, Joueur[] perdants) => PartieTerminee?.Invoke(this, new PartieTermineeEventArgs(gagnants, perdants));
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Crée une nouvelle instance de la classe Partie.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="regles">Les règles de la partie.</param>
|
|
|
|
|
/// <param name="persistance">Persistance de la partie.</param>
|
|
|
|
|
private int courant = 0;
|
|
|
|
|
|
|
|
|
|
[DataMember]
|
|
|
|
|
public IRegles Regles { get; private init; }
|
|
|
|
|
|
|
|
|
|
public Partie(IRegles regles)
|
|
|
|
|
{
|
|
|
|
|
Regles = regles;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Lance le déroulement de la partie.
|
|
|
|
|
/// </summary>
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Un joueur a saisi son nom
|
|
|
|
|
/// </summary>
|
|
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// La partie démarre
|
|
|
|
|
/// </summary>
|
|
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Un joueur a joué son tour
|
|
|
|
|
/// </summary>
|
|
|
|
|
private void Tour(Object? sender, JouerCodeEventArgs e)
|
|
|
|
|
private void NouveauTour()
|
|
|
|
|
{
|
|
|
|
|
Plateau plateauCourant = plateaux[courant!.Value];
|
|
|
|
|
|
|
|
|
|
plateauCourant.AjouterCode(e.Code);
|
|
|
|
|
QuandAjouterCode(e.Code);
|
|
|
|
|
QuandPartieNouveauTour();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (++courant == joueurs.Count)
|
|
|
|
|
courant = 0;
|
|
|
|
|
QuandPasserMain();
|
|
|
|
|
private void PlateauAjouterCode(object? sender, PlateauAjouterCodeEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
QuandPartiePasserLaMain();
|
|
|
|
|
|
|
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// La partie est terminée
|
|
|
|
|
/// </summary>
|
|
|
|
|
private void Terminee()
|
|
|
|
|
private void PartieTerminee()
|
|
|
|
|
{
|
|
|
|
|
foreach(Joueur joueur in joueurs)
|
|
|
|
|
{
|
|
|
|
|
joueur.JouerCode -= Tour;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
List<Joueur> gagnants = new List<Joueur>();
|
|
|
|
|
List<Joueur> perdants = new List<Joueur>();
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|