Merge branch 'NouveauCore' into UT

master
Camille TURPIN-ETIENNE 11 months ago
commit 68841cdc92

@ -27,7 +27,6 @@ namespace ConsoleApp
Console.WriteLine();
Joueur joueur = !string.IsNullOrEmpty(nom) ? Program.Manageur.DemanderJoueur(nom) : new Robot();
joueur.JoueurJouer += JoueurJouer;
e.JoueurDemande.SeConnecter(joueur);
}
@ -45,7 +44,7 @@ namespace ConsoleApp
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();
@ -76,7 +75,7 @@ namespace ConsoleApp
if (!e.EstJoueur)
{
Task t = Task.Delay(1000);
Task t = Task.Delay(3000);
t.GetAwaiter().GetResult();
}

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

@ -2,7 +2,7 @@
namespace CoreLibrary.Evenements
{
public class JoueurJouerEventArgs
public class PartieNouveauTourEventArgs : EventArgs
{
public int Tour { get; private init; }
public string Nom { get; private init; }
@ -10,7 +10,7 @@ namespace CoreLibrary.Evenements
public Code Code { 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;
Nom = nom;

@ -10,14 +10,13 @@ namespace CoreLibrary.Joueurs
{
[DataContract]
[KnownType(typeof(ReglesClassiques))]
[KnownType(typeof(ReglesDifficiles))]
public class Joueur : IEstPersistant
{
public event EventHandler<JoueurSeConnecterEventArgs>? JoueurSeConnecter;
public event EventHandler<JoueurJouerEventArgs>? JoueurJouer;
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]
private Dictionary<(IRegles, Statistique), int> statistiques = new Dictionary<(IRegles, Statistique), int>();
@ -51,8 +50,6 @@ namespace CoreLibrary.Joueurs
{
if (e.Nom != Nom)
return;
QuandJoueurJouer(e.Tour, e.Nom, e.Plateau, e.Code, e.EstJoueur);
}
public override string ToString() => Nom;

@ -7,20 +7,100 @@ namespace CoreLibrary.Joueurs
{
private static int nbRobots = 0;
private List<Code>? codesPossibles;
public Robot() :
base($"Naps {++nbRobots}")
{
}
public Robot(string nom) :
base(nom)
{
}
public override void QuandDemanderJoueurJouer(object? sender, PartieDemanderJoueurJouerEventArgs e)
{
if (e.Nom != Nom)
return;
while (!e.Code.Complet)
e.Code.AjouterJeton(new Jeton());
if (codesPossibles == null)
{
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);
}
}
}

@ -1,111 +1,111 @@
using CoreLibrary.Persistance;
using CoreLibrary.Joueurs;
using CoreLibrary.Regles;
using CoreLibrary.Statistiques;
namespace CoreLibrary.Manageurs
{
public class Manageur
{
private readonly IPersistance persistance;
private readonly List<Joueur> joueurs;
private readonly List<Partie> parties;
public IReadOnlyList<Joueur> Joueurs => joueurs;
public IReadOnlyList<Partie> Parties => parties;
public IReadOnlyList<Partie> PartiesNonTerminees => parties.Where(partie => !partie.Termine).Reverse().ToList();
public Manageur(IPersistance persistance)
{
this.persistance = persistance;
joueurs = persistance.Charger<Joueur>().ToList();
parties = persistance.Charger<Partie>().ToList();
}
private void Sauvegarder()
{
persistance.Enregistrer(joueurs.ToArray());
persistance.Enregistrer(parties.ToArray());
}
public Partie ChargerPartie(Partie partie)
{
parties.Remove(partie);
Partie nouvellePartie = new Partie(partie);
parties.Add(nouvellePartie);
EcouterPartie(nouvellePartie);
return nouvellePartie;
}
public Partie NouvellePartie(IRegles regles)
{
Partie partie = new Partie(regles);
parties.Add(partie);
EcouterPartie(partie);
return partie;
}
private void EcouterPartie(Partie partie)
{
partie.PartieDemanderJoueur += (sender, e) => Sauvegarder();
partie.PartieDebutPartie += (sender, e) => Sauvegarder();
partie.PartieDemanderJoueurJouer += (sender, e) => Sauvegarder();
partie.PartiePasserLaMain += (sender, e) =>
{
DemanderJoueurExistant(e.Joueur)?.IncrementerStatistique(partie.Regles, Statistique.CoupJoue);
Sauvegarder();
};
partie.PartiePartieTerminee += (sender, e) =>
{
if (e.Gagnants.Count == 1)
{
DemanderJoueurExistant(e.Gagnants[0])?.IncrementerStatistique(partie.Regles, Statistique.PartieGagnee);
}
else
{
foreach (string gagnant in e.Gagnants)
DemanderJoueurExistant(gagnant)?.IncrementerStatistique(partie.Regles, Statistique.PartieEgalite);
}
foreach (string perdant in e.Perdants)
{
DemanderJoueurExistant(perdant)?.IncrementerStatistique(partie.Regles, Statistique.PartiePerdue);
}
Sauvegarder();
};
}
private Joueur? DemanderJoueurExistant(string nom)
{
foreach (Joueur joueur in joueurs)
{
if (joueur.Nom == nom)
{
return joueur;
}
}
return null;
}
public Joueur DemanderJoueur(string nom)
{
Joueur? joueur = DemanderJoueurExistant(nom);
using CoreLibrary.Persistance;
using CoreLibrary.Joueurs;
using CoreLibrary.Regles;
using CoreLibrary.Statistiques;
namespace CoreLibrary.Manageurs
{
public class Manageur
{
private readonly IPersistance persistance;
private readonly List<Joueur> joueurs;
private readonly List<Partie> parties;
public IReadOnlyList<Joueur> Joueurs => joueurs;
public IReadOnlyList<Partie> Parties => parties;
public IReadOnlyList<Partie> PartiesNonTerminees => parties.Where(partie => !partie.Termine).Reverse().ToList();
public Manageur(IPersistance persistance)
{
this.persistance = persistance;
joueurs = persistance.Charger<Joueur>().ToList();
parties = persistance.Charger<Partie>().ToList();
}
private void Sauvegarder()
{
persistance.Enregistrer(joueurs.ToArray());
persistance.Enregistrer(parties.ToArray());
}
public Partie ChargerPartie(Partie partie)
{
parties.Remove(partie);
Partie nouvellePartie = new Partie(partie);
parties.Add(nouvellePartie);
EcouterPartie(nouvellePartie);
return nouvellePartie;
}
public Partie NouvellePartie(IRegles regles)
{
Partie partie = new Partie(regles);
parties.Add(partie);
EcouterPartie(partie);
return partie;
}
private void EcouterPartie(Partie partie)
{
partie.PartieDemanderJoueur += (sender, e) => Sauvegarder();
partie.PartieDebutPartie += (sender, e) => Sauvegarder();
partie.PartieDemanderJoueurJouer += (sender, e) => Sauvegarder();
partie.PartiePasserLaMain += (sender, e) =>
{
DemanderJoueurExistant(e.Joueur)?.IncrementerStatistique(partie.Regles, Statistique.CoupJoue);
Sauvegarder();
};
partie.PartiePartieTerminee += (sender, e) =>
{
if (e.Gagnants.Count == 1)
{
DemanderJoueurExistant(e.Gagnants[0])?.IncrementerStatistique(partie.Regles, Statistique.PartieGagnee);
}
else
{
foreach (string gagnant in e.Gagnants)
DemanderJoueurExistant(gagnant)?.IncrementerStatistique(partie.Regles, Statistique.PartieEgalite);
}
foreach (string perdant in e.Perdants)
{
DemanderJoueurExistant(perdant)?.IncrementerStatistique(partie.Regles, Statistique.PartiePerdue);
}
Sauvegarder();
};
}
private Joueur? DemanderJoueurExistant(string nom)
{
foreach (Joueur joueur in joueurs)
{
if (joueur.Nom == nom)
{
return joueur;
}
}
return null;
}
public Joueur DemanderJoueur(string nom)
{
Joueur? joueur = DemanderJoueurExistant(nom);
if (joueur == null)
{
joueur = new Joueur(nom);
joueurs.Add(joueur);
}
return joueur;
}
}
}
}
return joueur;
}
}
}

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

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

@ -5,20 +5,13 @@ namespace CoreLibrary.Regles
[DataContract]
public class ReglesClassiques : IRegles
{
public int Indice => 1;
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 NbTour => 12;
public int TailleCode => 4;
public override bool Equals(object? obj)
{
if (obj == null || obj is not ReglesClassiques) return false;
return true;
}
public override int GetHashCode()
{
return HashCode.Combine(Nom, NbJoueurs, NbTour, TailleCode);
}
public override bool Equals(object? obj) => obj == null ? false : obj is ReglesClassiques;
public override int GetHashCode() => Nom.GetHashCode();
}
}

@ -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,59 +1,125 @@
[
{
"Nom": "a",
"statistiques": [
{
"Key": {
"Item1": {
"__type": "ReglesClassiques:#CoreLibrary.Regles"
},
"Item2": 3
},
"Value": 2
}
]
},
{
"Nom": "Céleste",
"statistiques": [
{
"Key": {
"Item1": {
"__type": "ReglesClassiques:#CoreLibrary.Regles"
},
"Item2": 3
},
"Value": 30
},
{
"Key": {
"Item1": {
"__type": "ReglesClassiques:#CoreLibrary.Regles"
},
"Item2": 1
},
"Value": 2
}
]
},
{
"Nom": "C",
"statistiques": [ ]
},
{
"Nom": "Pauline",
"statistiques": [ ]
},
{
"Nom": "b",
"statistiques": [ ]
},
{
"Nom": "A",
"statistiques": [ ]
},
{
"Nom": "B",
"statistiques": [ ]
}
[
{
"Nom": "Céleste",
"statistiques": [
{
"Key": {
"Item1": {
"__type": "ReglesClassiques:#CoreLibrary.Regles"
},
"Item2": 0
},
"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": "Pauline",
"statistiques": [
{
"Key": {
"Item1": {
"__type": "ReglesClassiques:#CoreLibrary.Regles"
},
"Item2": 0
},
"Value": 1
},
{
"Key": {
"Item1": {
"__type": "ReglesClassiques:#CoreLibrary.Regles"
},
"Item2": 1
},
"Value": 5
},
{
"Key": {
"Item1": {
"__type": "ReglesClassiques:#CoreLibrary.Regles"
},
"Item2": 2
},
"Value": 2
},
{
"Key": {
"Item1": {
"__type": "ReglesClassiques:#CoreLibrary.Regles"
},
"Item2": 3
},
"Value": 10
}
]
},
{
"Nom": "Camille",
"statistiques": [
{
"Key": {
"Item1": {
"__type": "ReglesClassiques:#CoreLibrary.Regles"
},
"Item2": 0
},
"Value": 3
},
{
"Key": {
"Item1": {
"__type": "ReglesClassiques:#CoreLibrary.Regles"
},
"Item2": 1
},
"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
{
/// <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
{
/// <summary>
/// Obtient la couleur rouge.
/// </summary>
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");
/// <summary>
/// Obtient la couleur bleue.
/// </summary>
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");
/// <summary>
/// Obtient la couleur noire.
/// </summary>
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");
/// <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)
{
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)
{
if (value is not Color) return Couleur.Noir;

@ -3,23 +3,53 @@ using System.Globalization;
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
{
/// <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)
{
if (value is not Indicateur) return "black";
if (value is not Indicateur) return Noir;
switch (value)
{
case Indicateur.BonnePlace:
return "black";
return Noir;
case Indicateur.BonneCouleur:
return "white";
return Blanc;
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)
{
throw new NotImplementedException();

@ -2,8 +2,21 @@
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
{
/// <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)
{
if (value is not string)
@ -12,6 +25,14 @@ namespace MauiSpark.Convertisseurs
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)
{
throw new NotImplementedException();

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

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

@ -1,133 +1,137 @@
using CoreLibrary.Joueurs;
using CoreLibrary.Statistiques;
using CoreLibrary.Regles;
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace MauiSpark.Pages
{
partial class Enfant
{
private readonly Classement classement;
private int PartieJouee => PartieGagnee + PartieEgalite + PartiePerdue;
public Joueur Joueur { get; set; }
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 int PartieGagnee => Joueur.Statistique(classement.Regles, Statistique.PartieGagnee);
public int PartiePerdue => Joueur.Statistique(classement.Regles, Statistique.PartiePerdue);
public int PartieEgalite => Joueur.Statistique(classement.Regles, Statistique.PartieEgalite);
public Enfant(Joueur joueur, Classement classement)
{
this.classement = classement;
Joueur = joueur;
}
public override bool Equals(object? obj)
{
if (obj == null || obj is not Enfant)
return false;
return ((Enfant)obj).Joueur.Equals(Joueur);
}
using CoreLibrary.Joueurs;
using CoreLibrary.Statistiques;
using CoreLibrary.Regles;
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace MauiSpark.Pages
{
partial class Enfant
{
private readonly Classement classement;
public Joueur Joueur { get; set; }
public int Place => classement.Enfants.ToList().IndexOf(this) + 1;
public IEnumerable<int> Statistiques => Enum.GetValues<Statistique>()
.Select(statistique => Joueur.Statistique(classement.Regles, statistique));
public IEnumerable<string> Objets => new List<string>([$"{Place}", Joueur.Nom])
.Concat(Statistiques.Select(statistique => $"{statistique}"));
public Enfant(Joueur joueur, Classement classement)
{
this.classement = classement;
Joueur = joueur;
}
public override bool Equals(object? obj)
{
if (obj == null || obj is not Enfant)
return false;
return Joueur == ((Enfant)obj).Joueur;
}
public override int GetHashCode() => Joueur.GetHashCode();
}
partial class Classement : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
public void QuandProprieteChangee([CallerMemberName] string? nomPropriete = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nomPropriete));
}
private static Dictionary<string, IComparer<Enfant>> Tris => new Dictionary<string, IComparer<Enfant>> {
{ "Nom", Comparer<Enfant>.Create((enfant1, enfant2) => string.Compare(enfant1.Joueur.Nom, enfant2.Joueur.Nom)) },
{ "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;
public bool Inverser
{
get
{
return inverser;
}
set
{
inverser = value;
QuandProprieteChangee(nameof(Enfants));
}
}
private IRegles regles = new ReglesClassiques();
public IRegles Regles
{
get
{
return regles;
}
set
{
regles = value;
QuandProprieteChangee(nameof(Enfants));
}
}
public IComparer<Enfant> Tri => Tris.GetValueOrDefault(TypeTri) ?? Tris["CoupMoyen"];
public IEnumerable<Enfant> Enfants => Inverser ?
MauiProgram.Manageur.Joueurs.Select(joueur => new Enfant(joueur, this)).Order(Tri).Reverse() :
MauiProgram.Manageur.Joueurs.Select(joueur => new Enfant(joueur, this)).Order(Tri);
}
public partial class ClassementPage : ContentPage
{
public ClassementPage()
{
InitializeComponent();
NavigationPage.SetHasNavigationBar(this, false);
BindingContext = new Classement();
}
private void QuandBoutonPresse(object sender, EventArgs e)
{
Classement classement = (Classement)BindingContext;
if (sender == ReglesClassiques)
{
classement.Regles = new ReglesClassiques();
return;
}
if (classement.TypeTri == nameof(sender)) {
classement.Inverser = !classement.Inverser;
return;
}
classement.Inverser = false;
classement.TypeTri = nameof(sender);
}
}
}
partial class Classement : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
public void QuandProprieteChangee([CallerMemberName] string? propriete = null) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propriete));
private int indiceRegles = 0;
public IRegles Regles => ClassementPage.ToutesRegles.ElementAt(indiceRegles);
private Statistique statistique = Enum.GetValues<Statistique>().First();
public Statistique Statistique
{
get => statistique;
set
{
statistique = value;
QuandProprieteChangee(nameof(Enfants));
}
}
private bool inverser = true;
public bool Inverser {
get => inverser;
set
{
inverser = value;
QuandProprieteChangee(nameof(Enfants));
}
}
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 ?
MauiProgram.Manageur.Joueurs
.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 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()
{
InitializeComponent();
NavigationPage.SetHasNavigationBar(this, false);
BindingContext = new Classement();
}
public void ChangerReglesPresse(object sender, EventArgs e)
{
((Classement)BindingContext).IncrementerRegles(sender == DiminuerRegles ? -1 : 1);
}
public void StatistiquePressee(object sender, EventArgs e)
{
if (sender is not Label || !Enum.IsDefined(typeof(Statistique), ((Label)sender).Text.Replace(" ", "")))
return;
Statistique statistique = Enum.Parse<Statistique>(((Label)sender).Text.Replace(" ", ""));
Classement classement = (Classement)BindingContext;
if (classement.Statistique == statistique)
{
classement.Inverser = !classement.Inverser;
return;
}
classement.Inverser = true;
classement.Statistique = statistique;
}
}
}

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

@ -32,13 +32,26 @@ public partial class ConnexionPage : ContentPage
if (joueurDemande == null || indice == null)
return;
Joueur joueur;
if (string.IsNullOrEmpty(Nom.Text))
{
joueurDemande.SeConnecter(new Joueur($"Joueur {indice.Value}"));
joueur = new Joueur($"Joueur {indice.Value}");
}
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);
}
}

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

@ -1,4 +1,3 @@
using CoreLibrary;
using CoreLibrary.Regles;
namespace MauiSpark.Pages;
@ -9,22 +8,11 @@ public partial class ModePage : ContentPage
{
NavigationPage.SetHasNavigationBar(this, false);
InitializeComponent();
}
private void QuandReglesPresse(Object sender, EventArgs e)
{
Partie partie;
BindingContext = typeof(IRegles).Assembly.GetTypes()
.Where(type => typeof(IRegles).IsAssignableFrom(type) && type.IsClass)
.Select(type => (Activator.CreateInstance(type) as IRegles)!)
.OrderBy(regles => regles.Indice);
if (sender.Equals(ReglesClassiques))
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();
InitializeComponent();
}
}

@ -36,10 +36,13 @@
<BindableLayout.ItemTemplate>
<DataTemplate>
<Label Text="O"/>
<vues:IndicateurVue Couleur="{Binding ., Converter={StaticResource IndicateurVersCouleurMAUI}}"
VerticalOptions="FillAndExpand"
HorizontalOptions="FillAndExpand"/>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
<StackLayout
Orientation="Horizontal"
@ -112,13 +115,13 @@
<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.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.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.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}" 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}" 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.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.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.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}" 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}" 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>
</Border>

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

@ -9,11 +9,16 @@
<ScrollView>
<StackLayout>
<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 .}">
<BindableLayout.ItemTemplate>
<DataTemplate>
<vues:ReglesVue Titre="{Binding Titre}" Description="{Binding Description}" Margin="20"/>
<vues:ReglesVue Titre="{Binding Nom}" Description="{Binding Description}" Margin="20"/>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>

@ -1,27 +1,18 @@
namespace MauiSpark.Pages;
using CoreLibrary.Regles;
internal class Regles
{
public string Titre { get; init; } = "";
public string Description { get; init; } = "";
}
namespace MauiSpark.Pages;
public partial class ReglesPage : ContentPage
{
private static readonly Regles reglesClassiques = new Regles()
{
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()
{
public ReglesPage()
{
NavigationPage.SetHasNavigationBar(this, false);
BindingContext = (Regles[])[
reglesClassiques
];
InitializeComponent();
BindingContext = typeof(IRegles).Assembly.GetTypes()
.Where(type => typeof(IRegles).IsAssignableFrom(type) && type.IsClass)
.Select(type => (Activator.CreateInstance(type) as IRegles)!)
.OrderBy(regles => regles.Indice);
InitializeComponent();
}
}

@ -6,17 +6,17 @@
x:Name="reprendrePage"
Title="ReprendrePage">
<ScrollView>
<StackLayout>
<vues:TitreVue Texte="Reprendre une partie"/>
<StackLayout BindableLayout.ItemsSource="{Binding .}">
<BindableLayout.ItemTemplate>
<DataTemplate>
<vues:PartieCommenceeVue Partie="{Binding .}" Margin="20"/>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
</StackLayout>
<ScrollView>
<StackLayout>
<vues:TitreVue Texte="Reprendre une partie"/>
<StackLayout BindableLayout.ItemsSource="{Binding .}">
<BindableLayout.ItemTemplate>
<DataTemplate>
<vues:PartieCommenceeVue Partie="{Binding .}" Margin="20"/>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
</StackLayout>
</ScrollView>
</ContentPage>

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

@ -20,18 +20,12 @@
<Setter Property="WidthRequest" Value="300"/>
</Style>
<Style x:Key="ButtonClassement" TargetType="Button">
<Setter Property="BorderColor" Value="{AppThemeBinding Light={StaticResource FondSecondaireClair}, Dark={StaticResource FondSecondaireSombre}}"/>
<Setter Property="WidthRequest" Value="150"/>
<Setter Property="FontSize" Value="20"/>
</Style>
<Style x:Key="ButtonClassementRegle" TargetType="Button">
<Setter Property="FontSize" Value="24"/>
<Setter Property="Padding" Value="10, 5"/>
</Style>
<Style TargetType="Frame">
<Setter Property="BorderColor" Value="Black"/>
</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 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
{
@ -22,6 +23,12 @@ public partial class JetonVue : ContentView
set => SetValue(CodeProperty, value);
}
public bool EstJoueur
{
get => (bool)GetValue(EstJoueurProperty);
set => SetValue(EstJoueurProperty, value);
}
public JetonVue()
{
InitializeComponent();
@ -36,7 +43,7 @@ public partial class JetonVue : ContentView
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;
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.PartieDemanderJoueur += new ConnexionPage().QuandDemanderNom;
partie.PartieNouveauTour += new PlateauPage().QuandNouveauTour;
partie.PartiePartieTerminee += new VictoirePage().QuandPartieTerminee;
partie.PartieNouveauTour += new PlateauPage().QuandNouveauTour;
partie.Jouer();
}

Loading…
Cancel
Save