You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
283 lines
10 KiB
283 lines
10 KiB
using CoreLibrary.Persistance;
|
|
using CoreLibrary.Core;
|
|
using CoreLibrary.Evenements;
|
|
using CoreLibrary.Joueurs;
|
|
using CoreLibrary.Regles;
|
|
using System.Runtime.Serialization;
|
|
|
|
namespace CoreLibrary
|
|
{
|
|
/// <summary>
|
|
/// Classe représentant une partie.
|
|
/// </summary>
|
|
[DataContract]
|
|
[KnownType(typeof(ReglesClassiques))]
|
|
[KnownType(typeof(ReglesDifficiles))]
|
|
public class Partie : IEstPersistant
|
|
{
|
|
/// <summary>
|
|
/// Evénement déclenché lorsqu'il faut ajouter un joueur à la partie.
|
|
/// </summary>
|
|
public event EventHandler<PartieDemanderJoueurEventArgs>? PartieDemanderJoueur;
|
|
|
|
/// <summary>
|
|
/// Evénement déclenché lors du commencement de la partie.
|
|
/// </summary>
|
|
public event EventHandler<PartieDebutPartieEventArgs>? PartieDebutPartie;
|
|
|
|
/// <summary>
|
|
/// Evénement déclenché lorsqu'il faut demander à un joueur de jouer.
|
|
/// </summary>
|
|
public event EventHandler<PartieDemanderJoueurJouerEventArgs>? PartieDemanderJoueurJouer;
|
|
|
|
/// <summary>
|
|
/// Evénement déclenché lorsqu'un nouveau tour commence.
|
|
/// </summary>
|
|
public event EventHandler<PartieNouveauTourEventArgs>? PartieNouveauTour;
|
|
|
|
/// <summary>
|
|
/// Evénement déclenché lorsqu'on passe la main au joueur suivant.
|
|
/// </summary>
|
|
public event EventHandler<PartiePasserLaMainEventArgs>? PartiePasserLaMain;
|
|
|
|
/// <summary>
|
|
/// Evénement déclenché lorsque la partie est terminée.
|
|
/// </summary>
|
|
public event EventHandler<PartiePartieTermineeEventArgs>? PartiePartieTerminee;
|
|
|
|
/// <summary>
|
|
/// Méthode pour déclencher l'événement qui demande le joueur.
|
|
/// </summary>
|
|
/// <param name="joueurDemande">.</param>
|
|
private void QuandPartieDemanderJoueur(Joueur joueurDemande) => PartieDemanderJoueur?.Invoke(this, new PartieDemanderJoueurEventArgs(joueurs.Count + 1, joueurDemande));
|
|
|
|
/// <summary>
|
|
/// Méthode pour déclencher l'événement de début de partie.
|
|
/// </summary>
|
|
private void QuandPartieDebutPartie() => PartieDebutPartie?.Invoke(this, new PartieDebutPartieEventArgs());
|
|
|
|
/// <summary>
|
|
/// Méthode pour déclencher l'événement demandant à un joueur de jouer.
|
|
/// </summary>
|
|
/// <param name="code">Le code à utiliser pour jouer.</param>
|
|
private void QuandPartieDemanderJoueurJouer(Code code) => PartieDemanderJoueurJouer?.Invoke(this, new PartieDemanderJoueurJouerEventArgs(Tour, Joueurs.ElementAt(courant), plateaux.ElementAt(courant), code, joueurs[Joueurs.ElementAt(courant)]));
|
|
|
|
/// <summary>
|
|
/// Méthode pour déclencher l'événement d'un nouveau tour.
|
|
/// </summary>
|
|
/// <param name="code">Le code utilisé pour le nouveau tour.</param>
|
|
private void QuandPartieNouveauTour(Code code) => PartieNouveauTour?.Invoke(this, new PartieNouveauTourEventArgs(Tour, Joueurs.ElementAt(courant), plateaux.ElementAt(courant), code, joueurs[Joueurs.ElementAt(courant)]));
|
|
|
|
/// <summary>
|
|
/// Méthode pour déclencher l'événement de passer la main au joueur suivant.
|
|
/// </summary>
|
|
private void QuandPartiePasserLaMain() => PartiePasserLaMain?.Invoke(this, new PartiePasserLaMainEventArgs(Joueurs.ElementAt(courant)));
|
|
|
|
/// <summary>
|
|
/// Méthode pour déclencher l'événement de fin de partie.
|
|
/// </summary>
|
|
/// <param name="gagnants">Liste des noms des joueurs gagnants.</param>
|
|
/// <param name="perdants">Liste des noms des joueurs perdants.</param>
|
|
private void QuandPartiePartieTerminee(IReadOnlyList<string> gagnants, IReadOnlyList<string> perdants) => PartiePartieTerminee?.Invoke(this, new PartiePartieTermineeEventArgs(gagnants, perdants));
|
|
|
|
/// <summary>
|
|
/// Dictionnaire des joueurs, avec leur nom et le statut de leur joueur (humain ou robot).
|
|
/// </summary>
|
|
[DataMember]
|
|
private readonly Dictionary<string, bool> joueurs = new Dictionary<string, bool>();
|
|
|
|
/// <summary>
|
|
/// Liste des plateaux de jeu.
|
|
/// </summary
|
|
[DataMember]
|
|
private readonly List<Plateau> plateaux = new List<Plateau>();
|
|
|
|
/// <summary>
|
|
/// Indice correspondant au joueur courant.
|
|
/// </summary>
|
|
[DataMember]
|
|
private int courant = 0;
|
|
|
|
/// <summary>
|
|
/// Liste des noms des joueurs.
|
|
/// </summary>
|
|
public IEnumerable<string> Joueurs => joueurs.Keys;
|
|
|
|
/// <summary>
|
|
/// Liste des noms des robots.
|
|
/// </summary>
|
|
public IEnumerable<string> Robots => joueurs.Where(joueur => joueur.Value).Select(joueur => joueur.Key);
|
|
|
|
/// <summary>
|
|
/// Indique si la partie est terminée.
|
|
/// </summary>
|
|
[DataMember]
|
|
public bool Termine { get; private set; } = false;
|
|
|
|
/// <summary>
|
|
/// Numéro du tour actuel.
|
|
/// </summary>
|
|
[DataMember]
|
|
public int Tour { get; private set; } = 0;
|
|
|
|
/// <summary>
|
|
/// Règles utilisées dans la partie.
|
|
/// </summary>
|
|
[DataMember]
|
|
public IRegles Regles { get; private init; }
|
|
|
|
/// <summary>
|
|
/// Premier constructeur de la partie.
|
|
/// </summary>
|
|
/// <param name="regles">Les règles de la partie.</param>
|
|
public Partie(IRegles regles)
|
|
{
|
|
Regles = regles;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Deuxième constructeur de la partie.
|
|
/// </summary>
|
|
/// <param name="partie">La partie à reprendre en cours.</param>
|
|
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);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Lance le déroulement de la partie.
|
|
/// </summary>
|
|
public void Jouer()
|
|
{
|
|
if (joueurs.Count != Regles.NbJoueurs)
|
|
DemanderJoueur();
|
|
else
|
|
DebutPartie();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Demande un joueur.
|
|
/// </summary>
|
|
private void DemanderJoueur()
|
|
{
|
|
Joueur joueurDemande = new Joueur();
|
|
joueurDemande.JoueurSeConnecter += JoueurConnecte;
|
|
|
|
QuandPartieDemanderJoueur(joueurDemande);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Connecte les joueurs à la partie.
|
|
/// </summary>
|
|
/// <param name="sender">La classe qui appelle l'événement, ici Joueur.</param>
|
|
/// <param name="e">L'instance de l'événement JoueurSeConnecterEventArgs créée par Joueur.</param>
|
|
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();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Lance le début de la partie.
|
|
/// </summary>
|
|
private void DebutPartie()
|
|
{
|
|
if (Tour == 0)
|
|
++Tour;
|
|
|
|
foreach (Plateau plateau in plateaux)
|
|
{
|
|
plateau.PlateauAjouterCode += PlateauAjouterCode;
|
|
}
|
|
|
|
QuandPartieDebutPartie();
|
|
|
|
NouveauTour();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Passe au tour suivant.
|
|
/// </summary>
|
|
private void NouveauTour()
|
|
{
|
|
Code code = new Code(Regles.TailleCode);
|
|
|
|
QuandPartieDemanderJoueurJouer(code);
|
|
QuandPartieNouveauTour(code);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Ajoute un code au plateau.
|
|
/// </summary>
|
|
/// <param name="sender">La classe qui appelle l'événement, ici Plateau.</param>
|
|
/// <param name="e">L'instance de l'événement PlateauAjouterCodeEventArgs créée par Plateau.</param>
|
|
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();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// La partie est terminée.
|
|
/// </summary>
|
|
private void PartieTerminee()
|
|
{
|
|
Termine = true;
|
|
|
|
List<string> gagnants = new List<string>();
|
|
List<string> perdants = new List<string>();
|
|
|
|
for (int i = 0; i < joueurs.Count; ++i)
|
|
{
|
|
if (plateaux.ElementAt(i).Victoire)
|
|
gagnants.Add(Joueurs.ElementAt(i));
|
|
else
|
|
perdants.Add(Joueurs.ElementAt(i));
|
|
}
|
|
|
|
QuandPartiePartieTerminee(gagnants, perdants);
|
|
}
|
|
}
|
|
}
|