Merge branch 'NouveauCore' into UT

master
Camille TURPIN-ETIENNE 11 months ago
commit 68841cdc92

@ -27,7 +27,6 @@ namespace ConsoleApp
Console.WriteLine(); Console.WriteLine();
Joueur joueur = !string.IsNullOrEmpty(nom) ? Program.Manageur.DemanderJoueur(nom) : new Robot(); Joueur joueur = !string.IsNullOrEmpty(nom) ? Program.Manageur.DemanderJoueur(nom) : new Robot();
joueur.JoueurJouer += JoueurJouer;
e.JoueurDemande.SeConnecter(joueur); e.JoueurDemande.SeConnecter(joueur);
} }
@ -45,7 +44,7 @@ namespace ConsoleApp
Console.WriteLine("La partie commence, bonne chance à tous !\n"); Console.WriteLine("La partie commence, bonne chance à tous !\n");
} }
public static void JoueurJouer(object? sender, JoueurJouerEventArgs e) public static void NouveauTour(object? sender, PartieNouveauTourEventArgs e)
{ {
Utils.DessinerSeparateur(); Utils.DessinerSeparateur();
@ -76,7 +75,7 @@ namespace ConsoleApp
if (!e.EstJoueur) if (!e.EstJoueur)
{ {
Task t = Task.Delay(1000); Task t = Task.Delay(3000);
t.GetAwaiter().GetResult(); t.GetAwaiter().GetResult();
} }

@ -24,6 +24,7 @@ namespace ConsoleApp
maPartie.PartieDemanderJoueur += Evenements.DemanderNom; maPartie.PartieDemanderJoueur += Evenements.DemanderNom;
maPartie.PartieDebutPartie += Evenements.CommencerLaPartie; maPartie.PartieDebutPartie += Evenements.CommencerLaPartie;
maPartie.PartieNouveauTour += Evenements.NouveauTour;
maPartie.PartiePasserLaMain += Evenements.AjouterCode; maPartie.PartiePasserLaMain += Evenements.AjouterCode;
maPartie.PartiePartieTerminee += Evenements.PartieTerminee; maPartie.PartiePartieTerminee += Evenements.PartieTerminee;

@ -2,7 +2,7 @@
namespace CoreLibrary.Evenements namespace CoreLibrary.Evenements
{ {
public class JoueurJouerEventArgs public class PartieNouveauTourEventArgs : EventArgs
{ {
public int Tour { get; private init; } public int Tour { get; private init; }
public string Nom { get; private init; } public string Nom { get; private init; }
@ -10,7 +10,7 @@ namespace CoreLibrary.Evenements
public Code Code { get; private init; } public Code Code { get; private init; }
public bool EstJoueur { get; private init; } public bool EstJoueur { get; private init; }
public JoueurJouerEventArgs(int tour, string nom, Plateau plateau, Code code, bool estJoueur) public PartieNouveauTourEventArgs(int tour, string nom, Plateau plateau, Code code, bool estJoueur)
{ {
Tour = tour; Tour = tour;
Nom = nom; Nom = nom;

@ -10,13 +10,12 @@ namespace CoreLibrary.Joueurs
{ {
[DataContract] [DataContract]
[KnownType(typeof(ReglesClassiques))] [KnownType(typeof(ReglesClassiques))]
[KnownType(typeof(ReglesDifficiles))]
public class Joueur : IEstPersistant public class Joueur : IEstPersistant
{ {
public event EventHandler<JoueurSeConnecterEventArgs>? JoueurSeConnecter; public event EventHandler<JoueurSeConnecterEventArgs>? JoueurSeConnecter;
public event EventHandler<JoueurJouerEventArgs>? JoueurJouer;
private void QuandJoueurSeConnecter(Joueur joueur) => JoueurSeConnecter?.Invoke(this, new JoueurSeConnecterEventArgs(joueur)); private void QuandJoueurSeConnecter(Joueur joueur) => JoueurSeConnecter?.Invoke(this, new JoueurSeConnecterEventArgs(joueur));
private void QuandJoueurJouer(int tour, string nom, Plateau plateau, Code code, bool estJoueur) => JoueurJouer?.Invoke(this, new JoueurJouerEventArgs(tour, nom, plateau, code, estJoueur));
[DataMember] [DataMember]
private Dictionary<(IRegles, Statistique), int> statistiques = new Dictionary<(IRegles, Statistique), int>(); private Dictionary<(IRegles, Statistique), int> statistiques = new Dictionary<(IRegles, Statistique), int>();
@ -51,8 +50,6 @@ namespace CoreLibrary.Joueurs
{ {
if (e.Nom != Nom) if (e.Nom != Nom)
return; return;
QuandJoueurJouer(e.Tour, e.Nom, e.Plateau, e.Code, e.EstJoueur);
} }
public override string ToString() => Nom; public override string ToString() => Nom;

@ -7,20 +7,100 @@ namespace CoreLibrary.Joueurs
{ {
private static int nbRobots = 0; private static int nbRobots = 0;
private List<Code>? codesPossibles;
public Robot() : public Robot() :
base($"Naps {++nbRobots}") base($"Naps {++nbRobots}")
{ {
} }
public Robot(string nom) :
base(nom)
{
}
public override void QuandDemanderJoueurJouer(object? sender, PartieDemanderJoueurJouerEventArgs e) public override void QuandDemanderJoueurJouer(object? sender, PartieDemanderJoueurJouerEventArgs e)
{ {
if (e.Nom != Nom) if (e.Nom != Nom)
return; return;
while (!e.Code.Complet) if (codesPossibles == null)
e.Code.AjouterJeton(new Jeton()); {
codesPossibles = new List<Code>();
GenererTousCodesPossibles(e.Code.TailleMax);
}
SupprimerCodesImpossibles(e.Plateau);
for(int i = 0; i < e.Code.TailleMax; ++i)
e.Code.AjouterJeton(codesPossibles.ElementAt(0).Jetons[i]);
}
private void GenererTousCodesPossibles(int tailleCode)
{
Couleur[] couleurs = Enum.GetValues<Couleur>();
int nbLignes = (int)Math.Pow(couleurs.Length, tailleCode);
Jeton?[,] jetons = new Jeton?[nbLignes, tailleCode];
for(int indiceColonne = 0; indiceColonne < jetons.GetLength(1); ++indiceColonne)
{
int repetition = nbLignes / (int)Math.Pow(couleurs.Length, (indiceColonne + 1));
for (int indiceLigne = 0; indiceLigne < jetons.GetLength(0); ++indiceLigne)
{
jetons[indiceLigne, indiceColonne] = new Jeton(couleurs[(indiceLigne / repetition) % couleurs.Length]);
}
}
for (int i = 0; i < jetons.GetLength(0); ++i)
{
Code code = new Code(tailleCode);
for (int j = 0; j < jetons.GetLength(1); ++j)
{
code.AjouterJeton(jetons[i, j]!.Value);
}
codesPossibles!.Add(code);
}
}
private bool EstCodePossible(Plateau plateau, Code code)
{
for(int i = 0; i < plateau.Taille; ++i)
{
Code sonCode = new Code(code.TailleMax);
for(int j = 0; j < code.TailleMax; ++j)
{
sonCode.AjouterJeton(plateau.Grille.Item1.ElementAt(i).ElementAt(j));
}
IReadOnlyList<Indicateur> indicateurs = sonCode.Comparer(code);
if (
indicateurs.Count(indicateur => indicateur == Indicateur.BonnePlace) != plateau.Grille.Item2.ElementAt(i).Count(indicateur => indicateur == Indicateur.BonnePlace) ||
indicateurs.Count(indicateur => indicateur == Indicateur.BonneCouleur) != plateau.Grille.Item2.ElementAt(i).Count(indicateur => indicateur == Indicateur.BonneCouleur)
)
return false;
}
return true;
}
private void SupprimerCodesImpossibles(Plateau plateau)
{
if (codesPossibles == null)
return;
List<int> indicesASupprimer = new List<int>();
for(int i = codesPossibles.Count - 1; i >= 0; --i)
{
if(!EstCodePossible(plateau, codesPossibles.ElementAt(i)))
indicesASupprimer.Add(i);
}
base.QuandDemanderJoueurJouer(sender, e); foreach (int indice in indicesASupprimer)
codesPossibles.RemoveAt(indice);
} }
} }
} }

@ -9,17 +9,20 @@ namespace CoreLibrary
{ {
[DataContract] [DataContract]
[KnownType(typeof(ReglesClassiques))] [KnownType(typeof(ReglesClassiques))]
[KnownType(typeof(ReglesDifficiles))]
public class Partie : IEstPersistant public class Partie : IEstPersistant
{ {
public event EventHandler<PartieDemanderJoueurEventArgs>? PartieDemanderJoueur; public event EventHandler<PartieDemanderJoueurEventArgs>? PartieDemanderJoueur;
public event EventHandler<PartieDebutPartieEventArgs>? PartieDebutPartie; public event EventHandler<PartieDebutPartieEventArgs>? PartieDebutPartie;
public event EventHandler<PartieDemanderJoueurJouerEventArgs>? PartieDemanderJoueurJouer; public event EventHandler<PartieDemanderJoueurJouerEventArgs>? PartieDemanderJoueurJouer;
public event EventHandler<PartieNouveauTourEventArgs>? PartieNouveauTour;
public event EventHandler<PartiePasserLaMainEventArgs>? PartiePasserLaMain; public event EventHandler<PartiePasserLaMainEventArgs>? PartiePasserLaMain;
public event EventHandler<PartiePartieTermineeEventArgs>? PartiePartieTerminee; public event EventHandler<PartiePartieTermineeEventArgs>? PartiePartieTerminee;
private void QuandPartieDemanderJoueur(Joueur joueurDemande) => PartieDemanderJoueur?.Invoke(this, new PartieDemanderJoueurEventArgs(joueurs.Count + 1, joueurDemande)); private void QuandPartieDemanderJoueur(Joueur joueurDemande) => PartieDemanderJoueur?.Invoke(this, new PartieDemanderJoueurEventArgs(joueurs.Count + 1, joueurDemande));
private void QuandPartieDebutPartie() => PartieDebutPartie?.Invoke(this, new PartieDebutPartieEventArgs()); private void QuandPartieDebutPartie() => PartieDebutPartie?.Invoke(this, new PartieDebutPartieEventArgs());
private void QuandPartieDemanderJoueurJouer() => PartieDemanderJoueurJouer?.Invoke(this, new PartieDemanderJoueurJouerEventArgs(Tour, Joueurs.ElementAt(courant), plateaux.ElementAt(courant), new Code(Regles.TailleCode), joueurs[Joueurs.ElementAt(courant)])); 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 QuandPartiePasserLaMain() => PartiePasserLaMain?.Invoke(this, new PartiePasserLaMainEventArgs(Joueurs.ElementAt(courant)));
private void QuandPartiePartieTerminee(IReadOnlyList<string> gagnants, IReadOnlyList<string> perdants) => PartiePartieTerminee?.Invoke(this, new PartiePartieTermineeEventArgs(gagnants, perdants)); private void QuandPartiePartieTerminee(IReadOnlyList<string> gagnants, IReadOnlyList<string> perdants) => PartiePartieTerminee?.Invoke(this, new PartiePartieTermineeEventArgs(gagnants, perdants));
@ -31,6 +34,7 @@ namespace CoreLibrary
private int courant = 0; private int courant = 0;
public IReadOnlyList<string> Joueurs => joueurs.Keys.ToList(); public IReadOnlyList<string> Joueurs => joueurs.Keys.ToList();
public IReadOnlyList<string> Robots => joueurs.Where(joueur => joueur.Value).Select(joueur => joueur.Key).ToList();
[DataMember] [DataMember]
public bool Termine { get; private set; } = false; public bool Termine { get; private set; } = false;
[DataMember] [DataMember]
@ -55,8 +59,12 @@ namespace CoreLibrary
partie.PartieDemanderJoueur = null; partie.PartieDemanderJoueur = null;
partie.PartieDebutPartie = null; partie.PartieDebutPartie = null;
partie.PartieDemanderJoueurJouer = null; partie.PartieDemanderJoueurJouer = null;
partie.PartieNouveauTour = null;
partie.PartiePasserLaMain = null; partie.PartiePasserLaMain = null;
partie.PartiePartieTerminee = null; partie.PartiePartieTerminee = null;
foreach (string joueur in Joueurs)
(joueurs[joueur] ? new Joueur(joueur) : new Robot(joueur)).JouerPartie(this);
} }
public void Jouer() public void Jouer()
@ -109,7 +117,10 @@ namespace CoreLibrary
private void NouveauTour() private void NouveauTour()
{ {
QuandPartieDemanderJoueurJouer(); Code code = new Code(Regles.TailleCode);
QuandPartieDemanderJoueurJouer(code);
QuandPartieNouveauTour(code);
} }
private void PlateauAjouterCode(object? sender, PlateauAjouterCodeEventArgs e) private void PlateauAjouterCode(object? sender, PlateauAjouterCodeEventArgs e)

@ -2,9 +2,13 @@
{ {
public interface IRegles public interface IRegles
{ {
int Indice { get; }
string Nom { get; } string Nom { get; }
string Description { get; }
int NbJoueurs { get; } int NbJoueurs { get; }
int NbTour { get; } int NbTour { get; }
int TailleCode { get; } int TailleCode { get; }
bool Equals(object? obj);
int GetHashCode();
} }
} }

@ -5,20 +5,13 @@ namespace CoreLibrary.Regles
[DataContract] [DataContract]
public class ReglesClassiques : IRegles public class ReglesClassiques : IRegles
{ {
public int Indice => 1;
public string Nom => "Règles classiques"; public string Nom => "Règles classiques";
public string Description => "Le but du jeu est de découvrir la combinaison. On génère aléatoirement deux combinaisons de 4 couleurs (six couleurs au total : jaune, bleu, rouge, vert, blanc et noir), une combinaison pour chaque joueur. Deux joueurs se battent pour trouver la combinaison en premier, il y a douze tours. Le premier joueur à trouver la combinaison à gagner, chaque joueur a le même nombre de coups à réaliser. Donc si le joueur un à trouvé la solution au bout de huit coups, le joueur deux doit finir son huitième coup. Si le joueur deux trouve la combinaison, les deux joueurs sont à égalité. Sinon, le joueur un gagne. Pour trouver la combinaison, les joueurs disposent de quatre indicateurs. Ces indicateurs sont quatre ronds qui représentent les quatre couleurs sélectionnées par le joueur. Un rond noir signifie quune couleur est à la bonne place, un rond blanc correspond à une mauvaise place et s'il ny a pas dindicateur aucune des couleurs nest présentent dans la combinaison.";
public int NbJoueurs => 2; public int NbJoueurs => 2;
public int NbTour => 12; public int NbTour => 12;
public int TailleCode => 4; public int TailleCode => 4;
public override bool Equals(object? obj) => obj == null ? false : obj is ReglesClassiques;
public override bool Equals(object? obj) public override int GetHashCode() => Nom.GetHashCode();
{
if (obj == null || obj is not ReglesClassiques) return false;
return true;
}
public override int GetHashCode()
{
return HashCode.Combine(Nom, NbJoueurs, NbTour, TailleCode);
}
} }
} }

@ -0,0 +1,17 @@
using System.Runtime.Serialization;
namespace CoreLibrary.Regles
{
[DataContract]
public class ReglesDifficiles : IRegles
{
public int Indice => 2;
public string Nom => "Règles difficiles";
public string Description => "Le but du jeu est de découvrir la combinaison. On génère aléatoirement deux combinaisons de 6 couleurs (six couleurs au total : jaune, bleu, rouge, vert, blanc et noir), une combinaison pour chaque joueur. Deux joueurs se battent pour trouver la combinaison en premier, il y a douze tours. Le premier joueur à trouver la combinaison à gagner, chaque joueur a le même nombre de coups à réaliser. Donc si le joueur un à trouvé la solution au bout de huit coups, le joueur deux doit finir son huitième coup. Si le joueur deux trouve la combinaison, les deux joueurs sont à égalité. Sinon, le joueur un gagne. Pour trouver la combinaison, les joueurs disposent de quatre indicateurs. Ces indicateurs sont quatre ronds qui représentent les 6 couleurs sélectionnées par le joueur. Un rond noir signifie quune couleur est à la bonne place, un rond blanc correspond à une mauvaise place et s'il ny a pas dindicateur aucune des couleurs nest présentent dans la combinaison.";
public int NbJoueurs => 2;
public int NbTour => 12;
public int TailleCode => 6;
public override bool Equals(object? obj) => obj == null ? false : obj is ReglesDifficiles;
public override int GetHashCode() => Nom.GetHashCode();
}
}

@ -1,29 +1,56 @@
[ [
{ {
"Nom": "a", "Nom": "Céleste",
"statistiques": [ "statistiques": [
{ {
"Key": { "Key": {
"Item1": { "Item1": {
"__type": "ReglesClassiques:#CoreLibrary.Regles" "__type": "ReglesClassiques:#CoreLibrary.Regles"
}, },
"Item2": 3 "Item2": 0
}, },
"Value": 2 "Value": 2
},
{
"Key": {
"Item1": {
"__type": "ReglesClassiques:#CoreLibrary.Regles"
},
"Item2": 1
},
"Value": 1
},
{
"Key": {
"Item1": {
"__type": "ReglesClassiques:#CoreLibrary.Regles"
},
"Item2": 2
},
"Value": 0
},
{
"Key": {
"Item1": {
"__type": "ReglesClassiques:#CoreLibrary.Regles"
},
"Item2": 3
},
"Value": 5
} }
] ]
}, },
{ {
"Nom": "Céleste", "Nom": "Pauline",
"statistiques": [ "statistiques": [
{ {
"Key": { "Key": {
"Item1": { "Item1": {
"__type": "ReglesClassiques:#CoreLibrary.Regles" "__type": "ReglesClassiques:#CoreLibrary.Regles"
}, },
"Item2": 3 "Item2": 0
}, },
"Value": 30 "Value": 1
}, },
{ {
"Key": { "Key": {
@ -32,28 +59,67 @@
}, },
"Item2": 1 "Item2": 1
}, },
"Value": 5
},
{
"Key": {
"Item1": {
"__type": "ReglesClassiques:#CoreLibrary.Regles"
},
"Item2": 2
},
"Value": 2 "Value": 2
},
{
"Key": {
"Item1": {
"__type": "ReglesClassiques:#CoreLibrary.Regles"
},
"Item2": 3
},
"Value": 10
} }
] ]
}, },
{ {
"Nom": "C", "Nom": "Camille",
"statistiques": [ ] "statistiques": [
}, {
{ "Key": {
"Nom": "Pauline", "Item1": {
"statistiques": [ ] "__type": "ReglesClassiques:#CoreLibrary.Regles"
}, },
{ "Item2": 0
"Nom": "b", },
"statistiques": [ ] "Value": 3
}, },
{ {
"Nom": "A", "Key": {
"statistiques": [ ] "Item1": {
}, "__type": "ReglesClassiques:#CoreLibrary.Regles"
{ },
"Nom": "B", "Item2": 1
"statistiques": [ ] },
"Value": 5
},
{
"Key": {
"Item1": {
"__type": "ReglesClassiques:#CoreLibrary.Regles"
},
"Item2": 2
},
"Value": 6
},
{
"Key": {
"Item1": {
"__type": "ReglesClassiques:#CoreLibrary.Regles"
},
"Item2": 3
},
"Value": 50
}
]
} }
] ]

File diff suppressed because it is too large Load Diff

@ -3,15 +3,50 @@ using System.Globalization;
namespace MauiSpark.Convertisseurs namespace MauiSpark.Convertisseurs
{ {
/// <summary>
/// Convertisseur de couleur qui implémente l'interface IValueConverter.
/// Cette classe permet de convertir des valeurs de type Couleur en valeurs de type Color (et vice versa).
/// </summary>
public class CouleurVersCouleurMAUI : IValueConverter public class CouleurVersCouleurMAUI : IValueConverter
{ {
/// <summary>
/// Obtient la couleur rouge.
/// </summary>
public static Color Rouge { get; private set; } = Color.FromArgb("#F75353"); public static Color Rouge { get; private set; } = Color.FromArgb("#F75353");
/// <summary>
/// Obtient la couleur verte.
/// </summary>
public static Color Vert { get; private set; } = Color.FromArgb("#53F769"); public static Color Vert { get; private set; } = Color.FromArgb("#53F769");
/// <summary>
/// Obtient la couleur bleue.
/// </summary>
public static Color Bleu { get; private set; } = Color.FromArgb("#535AF3"); public static Color Bleu { get; private set; } = Color.FromArgb("#535AF3");
/// <summary>
/// Obtient la couleur jaune.
/// </summary>
public static Color Jaune { get; private set; } = Color.FromArgb("#E9FE67"); public static Color Jaune { get; private set; } = Color.FromArgb("#E9FE67");
/// <summary>
/// Obtient la couleur noire.
/// </summary>
public static Color Noir { get; private set; } = Color.FromArgb("#241E1E"); public static Color Noir { get; private set; } = Color.FromArgb("#241E1E");
/// <summary>
/// Obtient la couleur blanche.
/// </summary>
public static Color Blanc { get; private set; } = Color.FromArgb("#FFFFFF"); public static Color Blanc { get; private set; } = Color.FromArgb("#FFFFFF");
/// <summary>
/// Convertit une valeur de type Couleur en une valeur de type Color.
/// </summary>
/// <param name="value">La valeur à convertir.</param>
/// <param name="targetType">Le type cible de la conversion.</param>
/// <param name="parameter">Un paramètre facultatif utilisé pour la conversion.</param>
/// <param name="culture">La culture à utiliser pour la conversion.</param>
/// <returns>Une valeur de type Color correspondant à la valeur de type Couleur.</returns>
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture) public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{ {
if (value is not Couleur) if (value is not Couleur)
@ -36,6 +71,14 @@ namespace MauiSpark.Convertisseurs
} }
} }
/// <summary>
/// Convertit une valeur de type Color en une valeur de type Couleur.
/// </summary>
/// <param name="value">La valeur à convertir.</param>
/// <param name="targetType">Le type cible de la conversion.</param>
/// <param name="parameter">Un paramètre facultatif utilisé pour la conversion.</param>
/// <param name="culture">La culture à utiliser pour la conversion.</param>
/// <returns>Une valeur de type Couleur correspondant à la valeur de type Color.</returns>
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{ {
if (value is not Color) return Couleur.Noir; if (value is not Color) return Couleur.Noir;

@ -3,23 +3,53 @@ using System.Globalization;
namespace MauiSpark.Convertisseurs namespace MauiSpark.Convertisseurs
{ {
/// <summary>
/// Convertisseur d'indicateur en couleur qui implémente l'interface IValueConverter.
/// Cette classe permet de convertir des valeurs de type Indicateur en valeurs de type Color.
/// </summary>
public class IndicateurVersCouleurMAUI : IValueConverter public class IndicateurVersCouleurMAUI : IValueConverter
{ {
/// <summary>
/// Obtient la couleur noire.
/// </summary>
public static Color Noir { get; private set; } = Color.FromArgb("#000000");
/// <summary>
/// Obtient la couleur blanche.
/// </summary>
public static Color Blanc { get; private set; } = Color.FromArgb("#FFFFFF");
/// <summary>
/// Convertit une valeur de type Indicateur en une valeur de type Color.
/// </summary>
/// <param name="value">La valeur à convertir.</param>
/// <param name="targetType">Le type cible de la conversion.</param>
/// <param name="parameter">Un paramètre facultatif utilisé pour la conversion.</param>
/// <param name="culture">La culture à utiliser pour la conversion.</param>
/// <returns>Une valeur de type Color correspondant à la valeur de type Indicateur.</returns>
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture) public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{ {
if (value is not Indicateur) return "black"; if (value is not Indicateur) return Noir;
switch (value) switch (value)
{ {
case Indicateur.BonnePlace: case Indicateur.BonnePlace:
return "black"; return Noir;
case Indicateur.BonneCouleur: case Indicateur.BonneCouleur:
return "white"; return Blanc;
default: default:
return "black"; return Noir;
} }
} }
/// <summary>
/// Convertit une valeur de type Color en une valeur de type Indicateur.
/// </summary>
/// <param name="value">La valeur à convertir.</param>
/// <param name="targetType">Le type cible de la conversion.</param>
/// <param name="parameter">Un paramètre facultatif utilisé pour la conversion.</param>
/// <param name="culture">La culture à utiliser pour la conversion.</param>
/// <returns>Non implémenté. Lance une NotImplementedException.</returns>
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{ {
throw new NotImplementedException(); throw new NotImplementedException();

@ -2,8 +2,21 @@
namespace MauiSpark.Convertisseurs namespace MauiSpark.Convertisseurs
{ {
/// <summary>
/// Convertisseur de texte en texte en majuscules qui implémente l'interface IValueConverter.
/// Cette classe permet de convertir une chaîne de caractères en majuscules.
/// </summary>
public class TexteVersTexteMajuscule : IValueConverter public class TexteVersTexteMajuscule : IValueConverter
{ {
/// <summary>
/// Convertit une chaîne de caractères en majuscules.
/// </summary>
/// <param name="value">La valeur à convertir.</param>
/// <param name="targetType">Le type cible de la conversion.</param>
/// <param name="parameter">Un paramètre facultatif utilisé pour la conversion.</param>
/// <param name="culture">La culture à utiliser pour la conversion.</param>
/// <returns>Une chaîne de caractères en majuscules.</returns>
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture) public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{ {
if (value is not string) if (value is not string)
@ -12,6 +25,14 @@ namespace MauiSpark.Convertisseurs
return ((string)value).ToUpper(); return ((string)value).ToUpper();
} }
/// <summary>
/// Non implémenté. Lance une NotImplementedException.
/// </summary>
/// <param name="value">La valeur à convertir.</param>
/// <param name="targetType">Le type cible de la conversion.</param>
/// <param name="parameter">Un paramètre facultatif utilisé pour la conversion.</param>
/// <param name="culture">La culture à utiliser pour la conversion.</param>
/// <returns>Non implémenté. Lance une NotImplementedException.</returns>
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{ {
throw new NotImplementedException(); throw new NotImplementedException();

@ -124,9 +124,15 @@
<MauiXaml Update="Vues\ImageResultatVue.xaml"> <MauiXaml Update="Vues\ImageResultatVue.xaml">
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</MauiXaml> </MauiXaml>
<MauiXaml Update="Vues\IndicateurVue.xaml">
<Generator>MSBuild:Compile</Generator>
</MauiXaml>
<MauiXaml Update="Vues\JetonVue.xaml"> <MauiXaml Update="Vues\JetonVue.xaml">
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</MauiXaml> </MauiXaml>
<MauiXaml Update="Vues\ModeVue.xaml">
<Generator>MSBuild:Compile</Generator>
</MauiXaml>
<MauiXaml Update="Vues\PartieCommenceeVue.xaml"> <MauiXaml Update="Vues\PartieCommenceeVue.xaml">
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</MauiXaml> </MauiXaml>

@ -14,38 +14,51 @@
<Image Grid.Row="1" Source="star.png" WidthRequest="100" HorizontalOptions="Start" VerticalOptions="Center" Margin="0"/> <Image Grid.Row="1" Source="star.png" WidthRequest="100" HorizontalOptions="Start" VerticalOptions="Center" Margin="0"/>
</FlexLayout> </FlexLayout>
<Grid RowDefinitions="*" ColumnDefinitions="*"> <Grid RowDefinitions="*" ColumnDefinitions="*, 2*, *" Padding="50">
<Button x:Name="ReglesClassiques" Text="ReglesClassiques" Style="{StaticResource ButtonClassementRegle}" Clicked="QuandBoutonPresse"/> <Button x:Name="DiminuerRegles" Text="&lt;" Clicked="ChangerReglesPresse" VerticalOptions="Center" HorizontalOptions="Center"/>
<Label Grid.Column="1" x:Name="ReglesDifficiles" Text="{Binding Regles.Nom}" FontSize="Large" VerticalOptions="Center" HorizontalOptions="Center"/>
<Button x:Name="AugmenterRegles" Grid.Column="2" Text="&gt;" Clicked="ChangerReglesPresse" VerticalOptions="Center" HorizontalOptions="Center"/>
</Grid> </Grid>
<Border Margin="20" StrokeThickness="2" StrokeShape="RoundRectangle 10"> <ScrollView Orientation="Horizontal">
<Grid ColumnDefinitions="*, *, *, *, *, *, *" ColumnSpacing="10" > <VerticalStackLayout>
<Button Margin="5" Grid.Column="0" Text="Place" Style="{StaticResource ButtonClassement}" VerticalOptions="Center" HorizontalOptions="Center" Clicked="QuandBoutonPresse"/> <Border Margin="20" StrokeThickness="2" StrokeShape="RoundRectangle 10">
<Button x:Name="Nom" Margin="5" Grid.Column="1" Text="Nom" Style="{StaticResource ButtonClassement}" VerticalOptions="Center" HorizontalOptions="Center" Clicked="QuandBoutonPresse"/> <StackLayout
<Button x:Name="CoupMoyen" Margin="5" Grid.Column="3" Text="Coup moyen" Style="{StaticResource ButtonClassement}" VerticalOptions="Center" HorizontalOptions="Center" Clicked="QuandBoutonPresse"/> Orientation="Horizontal"
<Button x:Name="Gagnee" Margin="5" Grid.Column="4" Text="Partie gagnée" Style="{StaticResource ButtonClassement}" VerticalOptions="Center" HorizontalOptions="Center" Clicked="QuandBoutonPresse"/> BindableLayout.ItemsSource="{Binding Titres}">
<Button x:Name="Perdue" Margin="5" Grid.Column="5" Text="Partie perdue" Style="{StaticResource ButtonClassement}" VerticalOptions="Center" HorizontalOptions="Center" Clicked="QuandBoutonPresse"/>
<Button x:Name="Egalite" Margin="5" Grid.Column="6" Text="Partie égalité" Style="{StaticResource ButtonClassement}" VerticalOptions="Center" HorizontalOptions="Center" Clicked="QuandBoutonPresse"/>
</Grid>
</Border>
<StackLayout BindableLayout.ItemsSource="{Binding Enfants}"> <BindableLayout.ItemTemplate>
<BindableLayout.ItemTemplate> <DataTemplate>
<DataTemplate> <Label Text="{Binding .}" FontSize="Medium" Margin="0, 20" WidthRequest="250" HorizontalTextAlignment="Center">
<Border Margin="20, 0" StrokeThickness="2" StrokeShape="RoundRectangle 10" Padding="0,20"> <Label.GestureRecognizers>
<Grid ColumnDefinitions="*, *, *, *, *, *, *"> <TapGestureRecognizer Tapped="StatistiquePressee"/>
<Label Grid.Column="0" Text="{Binding Place}" VerticalOptions="Center" HorizontalOptions="Center" Style="{StaticResource TexteFrame}" /> </Label.GestureRecognizers>
<Label Grid.Column="1" Text="{Binding Joueur}" VerticalOptions="Center" HorizontalOptions="Center" Style="{StaticResource TexteFrame}" /> </Label>
<Label Grid.Column="3" Text="{Binding NbCoupMoyen}" VerticalOptions="Center" HorizontalOptions="Center" Style="{StaticResource TexteFrame}" /> </DataTemplate>
<Label Grid.Column="4" Text="{Binding PartieGagnee}" VerticalOptions="Center" HorizontalOptions="Center" Style="{StaticResource TexteFrame}" /> </BindableLayout.ItemTemplate>
<Label Grid.Column="5" Text="{Binding PartiePerdue}" VerticalOptions="Center" HorizontalOptions="Center" Style="{StaticResource TexteFrame}" /> </StackLayout>
<Label Grid.Column="6" Text="{Binding PartieEgalite}" VerticalOptions="Center" HorizontalOptions="Center" Style="{StaticResource TexteFrame}" /> </Border>
</Grid>
</Border> <StackLayout BindableLayout.ItemsSource="{Binding Enfants}">
</DataTemplate> <BindableLayout.ItemTemplate>
</BindableLayout.ItemTemplate> <DataTemplate>
</StackLayout> <Border Margin="20, 0" StrokeThickness="2" StrokeShape="RoundRectangle 10" Padding="0,20">
<StackLayout
Orientation="Horizontal"
BindableLayout.ItemsSource="{Binding Objets}">
<BindableLayout.ItemTemplate>
<DataTemplate>
<Label Text="{Binding .}" FontSize="Micro" WidthRequest="250" HorizontalTextAlignment="Center"/>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
</Border>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
</VerticalStackLayout>
</ScrollView>
</VerticalStackLayout> </VerticalStackLayout>
</ScrollView> </ScrollView>
</ContentPage> </ContentPage>

@ -10,14 +10,13 @@ namespace MauiSpark.Pages
{ {
private readonly Classement classement; private readonly Classement classement;
private int PartieJouee => PartieGagnee + PartieEgalite + PartiePerdue;
public Joueur Joueur { get; set; } public Joueur Joueur { get; set; }
public int Place => classement.Enfants.ToList().IndexOf(this) + 1; public int Place => classement.Enfants.ToList().IndexOf(this) + 1;
public int NbCoupMoyen => PartieJouee > 0 ? Joueur.Statistique(classement.Regles, Statistique.CoupJoue) / PartieJouee : Joueur.Statistique(classement.Regles, Statistique.CoupJoue); public IEnumerable<int> Statistiques => Enum.GetValues<Statistique>()
public int PartieGagnee => Joueur.Statistique(classement.Regles, Statistique.PartieGagnee); .Select(statistique => Joueur.Statistique(classement.Regles, statistique));
public int PartiePerdue => Joueur.Statistique(classement.Regles, Statistique.PartiePerdue);
public int PartieEgalite => Joueur.Statistique(classement.Regles, Statistique.PartieEgalite); public IEnumerable<string> Objets => new List<string>([$"{Place}", Joueur.Nom])
.Concat(Statistiques.Select(statistique => $"{statistique}"));
public Enfant(Joueur joueur, Classement classement) public Enfant(Joueur joueur, Classement classement)
{ {
@ -30,7 +29,7 @@ namespace MauiSpark.Pages
if (obj == null || obj is not Enfant) if (obj == null || obj is not Enfant)
return false; return false;
return ((Enfant)obj).Joueur.Equals(Joueur); return Joueur == ((Enfant)obj).Joueur;
} }
public override int GetHashCode() => Joueur.GetHashCode(); public override int GetHashCode() => Joueur.GetHashCode();
@ -38,70 +37,71 @@ namespace MauiSpark.Pages
partial class Classement : INotifyPropertyChanged partial class Classement : INotifyPropertyChanged
{ {
public event PropertyChangedEventHandler? PropertyChanged; public event PropertyChangedEventHandler? PropertyChanged;
public void QuandProprieteChangee([CallerMemberName] string? nomPropriete = null) public void QuandProprieteChangee([CallerMemberName] string? propriete = null) =>
{ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propriete));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nomPropriete));
}
private static Dictionary<string, IComparer<Enfant>> Tris => new Dictionary<string, IComparer<Enfant>> { private int indiceRegles = 0;
{ "Nom", Comparer<Enfant>.Create((enfant1, enfant2) => string.Compare(enfant1.Joueur.Nom, enfant2.Joueur.Nom)) }, public IRegles Regles => ClassementPage.ToutesRegles.ElementAt(indiceRegles);
{ "CoupMoyen", Comparer<Enfant>.Create((enfant1, enfant2) => enfant2.NbCoupMoyen - enfant1.NbCoupMoyen) },
{ "Gagnee", Comparer<Enfant>.Create((enfant1, enfant2) => enfant2.PartieGagnee - enfant1.PartieGagnee) },
{ "Perdue", Comparer<Enfant>.Create((enfant1, enfant2) => enfant2.PartiePerdue - enfant1.PartiePerdue) },
{ "Egalite", Comparer<Enfant>.Create((enfant1, enfant2) => enfant2.PartieEgalite - enfant1.PartieEgalite) },
};
private string typeTri = "CoupMoyen";
public string TypeTri {
get
{
return typeTri;
}
set
{
typeTri = value;
QuandProprieteChangee(nameof(Enfants));
}
}
private bool inverser = false; private Statistique statistique = Enum.GetValues<Statistique>().First();
public bool Inverser public Statistique Statistique
{ {
get get => statistique;
{
return inverser;
}
set set
{ {
inverser = value; statistique = value;
QuandProprieteChangee(nameof(Enfants)); QuandProprieteChangee(nameof(Enfants));
} }
} }
private IRegles regles = new ReglesClassiques(); private bool inverser = true;
public IRegles Regles public bool Inverser {
{ get => inverser;
get
{
return regles;
}
set set
{ {
regles = value; inverser = value;
QuandProprieteChangee(nameof(Enfants)); QuandProprieteChangee(nameof(Enfants));
} }
} }
public IComparer<Enfant> Tri => Tris.GetValueOrDefault(TypeTri) ?? Tris["CoupMoyen"]; public IEnumerable<string> Titres => new List<string>(["Place", "Nom"]).Concat(
Enum.GetValues<Statistique>().Select(
statistique => string.Concat((Enum.GetName(typeof(Statistique), statistique) ?? "").Select(
(lettre, indice) => indice > 0 && char.IsUpper(lettre) ? $" {lettre}" : $"{lettre}")
)
)
);
public IEnumerable<Enfant> Enfants => Inverser ? public IEnumerable<Enfant> Enfants => Inverser ?
MauiProgram.Manageur.Joueurs.Select(joueur => new Enfant(joueur, this)).Order(Tri).Reverse() : MauiProgram.Manageur.Joueurs
MauiProgram.Manageur.Joueurs.Select(joueur => new Enfant(joueur, this)).Order(Tri); .OrderBy(joueur => joueur.Statistique(Regles, Statistique))
.Select(joueur => new Enfant(joueur, this)).Reverse() :
MauiProgram.Manageur.Joueurs
.OrderBy(joueur => joueur.Statistique(Regles, Statistique))
.Select(joueur => new Enfant(joueur, this));
public void IncrementerRegles(int valeur)
{
if ((indiceRegles += valeur) < 0)
indiceRegles = ClassementPage.ToutesRegles.Count() - 1;
else if (indiceRegles >= ClassementPage.ToutesRegles.Count())
indiceRegles = 0;
QuandProprieteChangee(nameof(Regles));
QuandProprieteChangee(nameof(Enfants));
}
} }
public partial class ClassementPage : ContentPage public partial class ClassementPage : ContentPage
{ {
public static IEnumerable<IRegles> ToutesRegles => typeof(IRegles).Assembly.GetTypes()
.Where(type => typeof(IRegles).IsAssignableFrom(type) && type.IsClass)
.Select(type => (Activator.CreateInstance(type) as IRegles)!)
.OrderBy(regles => regles.Indice);
public ClassementPage() public ClassementPage()
{ {
InitializeComponent(); InitializeComponent();
@ -111,23 +111,27 @@ namespace MauiSpark.Pages
BindingContext = new Classement(); BindingContext = new Classement();
} }
private void QuandBoutonPresse(object sender, EventArgs e) public void ChangerReglesPresse(object sender, EventArgs e)
{ {
Classement classement = (Classement)BindingContext; ((Classement)BindingContext).IncrementerRegles(sender == DiminuerRegles ? -1 : 1);
}
if (sender == ReglesClassiques) public void StatistiquePressee(object sender, EventArgs e)
{ {
classement.Regles = new ReglesClassiques(); if (sender is not Label || !Enum.IsDefined(typeof(Statistique), ((Label)sender).Text.Replace(" ", "")))
return; return;
}
if (classement.TypeTri == nameof(sender)) { Statistique statistique = Enum.Parse<Statistique>(((Label)sender).Text.Replace(" ", ""));
Classement classement = (Classement)BindingContext;
if (classement.Statistique == statistique)
{
classement.Inverser = !classement.Inverser; classement.Inverser = !classement.Inverser;
return; return;
} }
classement.Inverser = false; classement.Inverser = true;
classement.TypeTri = nameof(sender); classement.Statistique = statistique;
} }
} }
} }

@ -36,10 +36,17 @@
</Grid> </Grid>
</VerticalStackLayout> </VerticalStackLayout>
<Button <Grid Grid.Row="2" VerticalOptions="Center" RowDefinitions="*" ColumnDefinitions="*, *">
VerticalOptions="Center" <Button
Grid.Row="2" VerticalOptions="Center"
Text="Se connecter" Text="Se connecter"
Clicked="QuandSeConnecterPresse"/> Clicked="QuandSeConnecterPresse"/>
<Button
Grid.Column="1"
VerticalOptions="Center"
Text="Robot"
Clicked="QuandRobotPresse"/>
</Grid>
</Grid> </Grid>
</ContentPage> </ContentPage>

@ -32,13 +32,26 @@ public partial class ConnexionPage : ContentPage
if (joueurDemande == null || indice == null) if (joueurDemande == null || indice == null)
return; return;
Joueur joueur;
if (string.IsNullOrEmpty(Nom.Text)) if (string.IsNullOrEmpty(Nom.Text))
{ {
joueurDemande.SeConnecter(new Joueur($"Joueur {indice.Value}")); joueur = new Joueur($"Joueur {indice.Value}");
} }
else else
{ {
joueurDemande.SeConnecter(MauiProgram.Manageur.DemanderJoueur(Nom.Text)); joueur = MauiProgram.Manageur.DemanderJoueur(Nom.Text);
} }
joueurDemande.SeConnecter(joueur);
}
private void QuandRobotPresse(object sender, EventArgs e)
{
if (joueurDemande == null || indice == null)
return;
Robot robot = new Robot();
joueurDemande.SeConnecter(robot);
} }
} }

@ -5,16 +5,17 @@
xmlns:vues="clr-namespace:MauiSpark.Vues" xmlns:vues="clr-namespace:MauiSpark.Vues"
Title="ModePage"> Title="ModePage">
<Grid <ScrollView>
ColumnDefinitions="*" <StackLayout>
RowDefinitions="*, *"> <vues:TitreVue Texte="mode de jeu"/>
<vues:TitreVue Texte="mode de jeu"/> <StackLayout BindableLayout.ItemsSource="{Binding .}">
<BindableLayout.ItemTemplate>
<Button <DataTemplate>
x:Name="ReglesClassiques" <vues:ModeVue Regles="{Binding .}"/>
Grid.Row="1" </DataTemplate>
Text="Règles classiques" </BindableLayout.ItemTemplate>
Clicked="QuandReglesPresse"/> </StackLayout>
</Grid> </StackLayout>
</ScrollView>
</ContentPage> </ContentPage>

@ -1,4 +1,3 @@
using CoreLibrary;
using CoreLibrary.Regles; using CoreLibrary.Regles;
namespace MauiSpark.Pages; namespace MauiSpark.Pages;
@ -9,22 +8,11 @@ public partial class ModePage : ContentPage
{ {
NavigationPage.SetHasNavigationBar(this, false); NavigationPage.SetHasNavigationBar(this, false);
InitializeComponent(); BindingContext = typeof(IRegles).Assembly.GetTypes()
} .Where(type => typeof(IRegles).IsAssignableFrom(type) && type.IsClass)
.Select(type => (Activator.CreateInstance(type) as IRegles)!)
private void QuandReglesPresse(Object sender, EventArgs e) .OrderBy(regles => regles.Indice);
{
Partie partie;
if (sender.Equals(ReglesClassiques)) InitializeComponent();
partie = MauiProgram.Manageur.NouvellePartie(new ReglesClassiques());
else
return;
partie.PartieDemanderJoueur += new ConnexionPage().QuandDemanderNom;
partie.PartieNouveauTour += new PlateauPage().QuandNouveauTour;
partie.PartiePartieTerminee += new VictoirePage().QuandPartieTerminee;
partie.Jouer();
} }
} }

@ -36,11 +36,14 @@
<BindableLayout.ItemTemplate> <BindableLayout.ItemTemplate>
<DataTemplate> <DataTemplate>
<Label Text="O"/> <vues:IndicateurVue Couleur="{Binding ., Converter={StaticResource IndicateurVersCouleurMAUI}}"
VerticalOptions="FillAndExpand"
HorizontalOptions="FillAndExpand"/>
</DataTemplate> </DataTemplate>
</BindableLayout.ItemTemplate> </BindableLayout.ItemTemplate>
</StackLayout> </StackLayout>
<StackLayout <StackLayout
Orientation="Horizontal" Orientation="Horizontal"
Grid.Column="1" Grid.Column="1"
@ -112,13 +115,13 @@
<BoxView Grid.Row="1" Grid.ColumnSpan="6" HeightRequest="1" VerticalOptions="Center"/> <BoxView Grid.Row="1" Grid.ColumnSpan="6" HeightRequest="1" VerticalOptions="Center"/>
<vues:JetonVue Couleur="{x:Static conv:CouleurVersCouleurMAUI.Rouge}" Code="{Binding Source={x:Reference plateauPage}, Path=BindingContext.Code}" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" Grid.Column="0" Grid.Row="2" Grid.ColumnSpan="2"/> <vues:JetonVue Couleur="{x:Static conv:CouleurVersCouleurMAUI.Rouge}" EstJoueur="{Binding Source={x:Reference plateauPage}, Path=BindingContext.EstJoueur}" Code="{Binding Source={x:Reference plateauPage}, Path=BindingContext.Code}" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" Grid.Column="0" Grid.Row="2" Grid.ColumnSpan="2"/>
<vues:JetonVue Couleur="{x:Static conv:CouleurVersCouleurMAUI.Vert}" Code="{Binding Source={x:Reference plateauPage}, Path=BindingContext.Code}" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" Grid.Column="2" Grid.Row="2" Grid.ColumnSpan="2"/> <vues:JetonVue Couleur="{x:Static conv:CouleurVersCouleurMAUI.Vert}" EstJoueur="{Binding Source={x:Reference plateauPage}, Path=BindingContext.EstJoueur}" Code="{Binding Source={x:Reference plateauPage}, Path=BindingContext.Code}" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" Grid.Column="2" Grid.Row="2" Grid.ColumnSpan="2"/>
<vues:JetonVue Couleur="{x:Static conv:CouleurVersCouleurMAUI.Bleu}" Code="{Binding Source={x:Reference plateauPage}, Path=BindingContext.Code}" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" Grid.Column="4" Grid.Row="2" Grid.ColumnSpan="2"/> <vues:JetonVue Couleur="{x:Static conv:CouleurVersCouleurMAUI.Bleu}" EstJoueur="{Binding Source={x:Reference plateauPage}, Path=BindingContext.EstJoueur}" Code="{Binding Source={x:Reference plateauPage}, Path=BindingContext.Code}" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" Grid.Column="4" Grid.Row="2" Grid.ColumnSpan="2"/>
<vues:JetonVue Couleur="{x:Static conv:CouleurVersCouleurMAUI.Jaune}" Code="{Binding Source={x:Reference plateauPage}, Path=BindingContext.Code}" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" Grid.Column="0" Grid.Row="3" Grid.ColumnSpan="2"/> <vues:JetonVue Couleur="{x:Static conv:CouleurVersCouleurMAUI.Jaune}" EstJoueur="{Binding Source={x:Reference plateauPage}, Path=BindingContext.EstJoueur}" Code="{Binding Source={x:Reference plateauPage}, Path=BindingContext.Code}" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" Grid.Column="0" Grid.Row="3" Grid.ColumnSpan="2"/>
<vues:JetonVue Couleur="{x:Static conv:CouleurVersCouleurMAUI.Noir}" Code="{Binding Source={x:Reference plateauPage}, Path=BindingContext.Code}" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" Grid.Column="2" Grid.Row="3" Grid.ColumnSpan="2"/> <vues:JetonVue Couleur="{x:Static conv:CouleurVersCouleurMAUI.Noir}" EstJoueur="{Binding Source={x:Reference plateauPage}, Path=BindingContext.EstJoueur}" Code="{Binding Source={x:Reference plateauPage}, Path=BindingContext.Code}" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" Grid.Column="2" Grid.Row="3" Grid.ColumnSpan="2"/>
<vues:JetonVue Couleur="{x:Static conv:CouleurVersCouleurMAUI.Blanc}" Code="{Binding Source={x:Reference plateauPage}, Path=BindingContext.Code}" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" Grid.Column="4" Grid.Row="3" Grid.ColumnSpan="2"/> <vues:JetonVue Couleur="{x:Static conv:CouleurVersCouleurMAUI.Blanc}" EstJoueur="{Binding Source={x:Reference plateauPage}, Path=BindingContext.EstJoueur}" Code="{Binding Source={x:Reference plateauPage}, Path=BindingContext.Code}" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" Grid.Column="4" Grid.Row="3" Grid.ColumnSpan="2"/>
</Grid> </Grid>
</Border> </Border>

@ -1,7 +1,6 @@
using CoreLibrary.Core; using CoreLibrary.Core;
using CoreLibrary.Evenements; using CoreLibrary.Evenements;
using CoreLibrary.Exceptions; using CoreLibrary.Exceptions;
using CoreLibrary.Joueurs;
namespace MauiSpark.Pages; namespace MauiSpark.Pages;
@ -11,12 +10,14 @@ internal class Tour
public string Joueur { get; private init; } public string Joueur { get; private init; }
public string Numero { get; private init; } public string Numero { get; private init; }
public Code Code { get; private init; } public Code Code { get; private init; }
public bool EstJoueur { get; private init; }
public Tour(PartieNouveauTourEventArgs e) public Tour(PartieNouveauTourEventArgs e)
{ {
Numero = $"Tour {e.Tour}"; Numero = $"Tour {e.Tour}";
Joueur = e.Joueur; Joueur = e.Nom;
Code = e.Code; Code = e.Code;
EstJoueur = e.EstJoueur;
(IReadOnlyList<IReadOnlyList<Jeton>> jetons, IReadOnlyList < IReadOnlyList < Indicateur >> indicateurs) = e.Plateau.Grille; (IReadOnlyList<IReadOnlyList<Jeton>> jetons, IReadOnlyList < IReadOnlyList < Indicateur >> indicateurs) = e.Plateau.Grille;
@ -41,6 +42,7 @@ public partial class PlateauPage : ContentPage
{ {
private Code? code; private Code? code;
private Plateau? plateau; private Plateau? plateau;
private bool? estJoueur;
public PlateauPage() public PlateauPage()
{ {
@ -69,6 +71,7 @@ public partial class PlateauPage : ContentPage
code = e.Code; code = e.Code;
plateau = e.Plateau; plateau = e.Plateau;
estJoueur = e.EstJoueur;
BindingContext = new Tour(e); BindingContext = new Tour(e);
} }
@ -77,7 +80,7 @@ public partial class PlateauPage : ContentPage
{ {
try try
{ {
if(code != null) if(code != null && estJoueur.HasValue && estJoueur.Value)
code.SupprimerDernierJeton(); code.SupprimerDernierJeton();
} }
catch(CodeVideException) catch(CodeVideException)

@ -9,11 +9,16 @@
<ScrollView> <ScrollView>
<StackLayout> <StackLayout>
<vues:TitreVue Texte="Règles"/> <vues:TitreVue Texte="Règles"/>
<Grid RowDefinitions="*,*" ColumnDefinitions="*,*">
<vues:IndicateurVue Couleur="White" WidthRequest="100" HeightRequest="100" />
<Label Grid.Row="1" FontSize="Medium" Text="Cette indicateur indique une bonne couleur" HorizontalOptions="Center"/>
<vues:IndicateurVue Grid.Column="1" Couleur="Black" WidthRequest="100" HeightRequest="100"/>
<Label Grid.Row="1" Grid.Column="1" FontSize="Medium" Text="Cette indicateur indique une bonne place" HorizontalOptions="Center"/>
</Grid>
<StackLayout BindableLayout.ItemsSource="{Binding .}"> <StackLayout BindableLayout.ItemsSource="{Binding .}">
<BindableLayout.ItemTemplate> <BindableLayout.ItemTemplate>
<DataTemplate> <DataTemplate>
<vues:ReglesVue Titre="{Binding Titre}" Description="{Binding Description}" Margin="20"/> <vues:ReglesVue Titre="{Binding Nom}" Description="{Binding Description}" Margin="20"/>
</DataTemplate> </DataTemplate>
</BindableLayout.ItemTemplate> </BindableLayout.ItemTemplate>
</StackLayout> </StackLayout>

@ -1,27 +1,18 @@
namespace MauiSpark.Pages; using CoreLibrary.Regles;
internal class Regles namespace MauiSpark.Pages;
{
public string Titre { get; init; } = "";
public string Description { get; init; } = "";
}
public partial class ReglesPage : ContentPage public partial class ReglesPage : ContentPage
{ {
private static readonly Regles reglesClassiques = new Regles() public ReglesPage()
{
Titre = "Règles classiques",
Description = "Le but du jeu est de découvrir la combinaison. On génère aléatoirement deux combinaisons de 4 couleurs (six couleurs au total : jaune, bleu, rouge, vert, blanc et noir), une combinaison pour chaque joueur. Deux joueurs se battent pour trouver la combinaison en premier, il y a douze tours. Le premier joueur à trouver la combinaison à gagner, chaque joueur a le même nombre de coups à réaliser. Donc si le joueur un à trouvé la solution au bout de huit coups, le joueur deux doit finir son huitième coup. Si le joueur deux trouve la combinaison, les deux joueurs sont à égalité. Sinon, le joueur un gagne. Pour trouver la combinaison, les joueurs disposent de quatre indicateurs. Ces indicateurs sont quatre ronds qui représentent les quatre couleurs sélectionnées par le joueur. Un rond noir signifie quune couleur est à la bonne place, un rond blanc correspond à une mauvaise place et s'il ny a pas dindicateur aucune des couleurs nest présentent dans la combinaison."
};
public ReglesPage()
{ {
NavigationPage.SetHasNavigationBar(this, false); NavigationPage.SetHasNavigationBar(this, false);
BindingContext = (Regles[])[ BindingContext = typeof(IRegles).Assembly.GetTypes()
reglesClassiques .Where(type => typeof(IRegles).IsAssignableFrom(type) && type.IsClass)
]; .Select(type => (Activator.CreateInstance(type) as IRegles)!)
.OrderBy(regles => regles.Indice);
InitializeComponent(); InitializeComponent();
} }
} }

@ -29,7 +29,7 @@
Margin="20" Margin="20"
Padding="20"> Padding="20">
<Label HorizontalOptions="Center" Text="{Binding Texte}"/> <Label FontSize="Large" HorizontalOptions="Center" Text="{Binding Texte}"/>
</Border> </Border>
<Button <Button

@ -20,18 +20,12 @@
<Setter Property="WidthRequest" Value="300"/> <Setter Property="WidthRequest" Value="300"/>
</Style> </Style>
<Style x:Key="ButtonClassement" TargetType="Button"> <Style x:Key="ButtonClassement" TargetType="Button">
<Setter Property="BorderColor" Value="{AppThemeBinding Light={StaticResource FondSecondaireClair}, Dark={StaticResource FondSecondaireSombre}}"/> <Setter Property="BorderColor" Value="{AppThemeBinding Light={StaticResource FondSecondaireClair}, Dark={StaticResource FondSecondaireSombre}}"/>
<Setter Property="WidthRequest" Value="150"/> <Setter Property="WidthRequest" Value="150"/>
<Setter Property="FontSize" Value="20"/> <Setter Property="FontSize" Value="20"/>
</Style> </Style>
<Style x:Key="ButtonClassementRegle" TargetType="Button">
<Setter Property="FontSize" Value="24"/>
<Setter Property="Padding" Value="10, 5"/>
</Style>
<Style TargetType="Frame"> <Style TargetType="Frame">
<Setter Property="BorderColor" Value="Black"/> <Setter Property="BorderColor" Value="Black"/>
</Style> </Style>

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiSpark.Vues.IndicateurVue"
x:Name="indicateurVue">
<Grid
x:Name="Grid"
SizeChanged="QuandTailleChangee"
VerticalOptions="FillAndExpand"
HorizontalOptions="FillAndExpand">
<Rectangle
x:Name="Carre"
Fill="{Binding Couleur, Source={x:Reference indicateurVue}}">
</Rectangle>
</Grid>
</ContentView>

@ -0,0 +1,28 @@
using CoreLibrary.Core;
using MauiSpark.Convertisseurs;
using System.Globalization;
namespace MauiSpark.Vues;
public partial class IndicateurVue : ContentView
{
public static readonly BindableProperty CouleurProperty = BindableProperty.Create(nameof(Couleur), typeof(Color), typeof(IndicateurVue), default(Color));
public Color Couleur
{
get => (Color)GetValue(CouleurProperty);
set => SetValue(CouleurProperty, value);
}
public IndicateurVue()
{
InitializeComponent();
BindingContext = this;
}
private void QuandTailleChangee(object sender, EventArgs e)
{
double taille = Math.Min(Grid.Width, Grid.Height) / 2;
Carre.WidthRequest = Carre.HeightRequest = taille;
}
}

@ -9,6 +9,7 @@ public partial class JetonVue : ContentView
{ {
public static readonly BindableProperty CouleurProperty = BindableProperty.Create(nameof(Couleur), typeof(Color), typeof(JetonVue), default(Color)); public static readonly BindableProperty CouleurProperty = BindableProperty.Create(nameof(Couleur), typeof(Color), typeof(JetonVue), default(Color));
public static readonly BindableProperty CodeProperty = BindableProperty.Create(nameof(Code), typeof(Code), typeof(JetonVue), null); public static readonly BindableProperty CodeProperty = BindableProperty.Create(nameof(Code), typeof(Code), typeof(JetonVue), null);
public static readonly BindableProperty EstJoueurProperty = BindableProperty.Create(nameof(EstJoueur), typeof(bool), typeof(JetonVue), true);
public Color Couleur public Color Couleur
{ {
@ -22,6 +23,12 @@ public partial class JetonVue : ContentView
set => SetValue(CodeProperty, value); set => SetValue(CodeProperty, value);
} }
public bool EstJoueur
{
get => (bool)GetValue(EstJoueurProperty);
set => SetValue(EstJoueurProperty, value);
}
public JetonVue() public JetonVue()
{ {
InitializeComponent(); InitializeComponent();
@ -36,7 +43,7 @@ public partial class JetonVue : ContentView
private void JetonPresse(object sender, EventArgs e) private void JetonPresse(object sender, EventArgs e)
{ {
if (Cercle == null || !sender.Equals(Cercle) || Code == null || Application.Current == null || Application.Current.MainPage == null) if (Cercle == null || !sender.Equals(Cercle) || Code == null || Application.Current == null || Application.Current.MainPage == null || !EstJoueur)
return; return;
Couleur couleur = (Couleur)new CouleurVersCouleurMAUI().ConvertBack(((SolidColorBrush)Cercle.Fill).Color, typeof(Couleur), null, CultureInfo.InvariantCulture); Couleur couleur = (Couleur)new CouleurVersCouleurMAUI().ConvertBack(((SolidColorBrush)Cercle.Fill).Color, typeof(Couleur), null, CultureInfo.InvariantCulture);

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiSpark.Vues.ModeVue"
x:Name="modeVue">
<Button
Text="{Binding Regles.Nom, Source={x:Reference modeVue}}"
Clicked="QuandReglesPresse"
Margin="0, 50"/>
</ContentView>

@ -0,0 +1,32 @@
using CoreLibrary;
using CoreLibrary.Regles;
using MauiSpark.Pages;
namespace MauiSpark.Vues;
public partial class ModeVue : ContentView
{
public static readonly BindableProperty ReglesProperty = BindableProperty.Create(nameof(Regles), typeof(IRegles), typeof(ModeVue), null);
public IRegles Regles
{
get => (IRegles)GetValue(ReglesProperty);
set => SetValue(ReglesProperty, value);
}
public ModeVue()
{
InitializeComponent();
}
private void QuandReglesPresse(Object sender, EventArgs e)
{
Partie partie = MauiProgram.Manageur.NouvellePartie(Regles);
partie.PartieDemanderJoueur += new ConnexionPage().QuandDemanderNom;
partie.PartiePartieTerminee += new VictoirePage().QuandPartieTerminee;
partie.PartieNouveauTour += new PlateauPage().QuandNouveauTour;
partie.Jouer();
}
}

@ -47,8 +47,8 @@ public partial class PartieCommenceeVue : ContentView, INotifyPropertyChanged
Partie partie = MauiProgram.Manageur.ChargerPartie(Partie); Partie partie = MauiProgram.Manageur.ChargerPartie(Partie);
partie.PartieDemanderJoueur += new ConnexionPage().QuandDemanderNom; partie.PartieDemanderJoueur += new ConnexionPage().QuandDemanderNom;
partie.PartieNouveauTour += new PlateauPage().QuandNouveauTour;
partie.PartiePartieTerminee += new VictoirePage().QuandPartieTerminee; partie.PartiePartieTerminee += new VictoirePage().QuandPartieTerminee;
partie.PartieNouveauTour += new PlateauPage().QuandNouveauTour;
partie.Jouer(); partie.Jouer();
} }

Loading…
Cancel
Save