You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
155 lines
5.9 KiB
155 lines
5.9 KiB
using CoreLibrary.Core;
|
|
using CoreLibrary.Evenements;
|
|
|
|
namespace CoreLibrary.Joueurs
|
|
{
|
|
/// <summary>
|
|
/// Représente un joueur automatique (robot).
|
|
/// </summary>
|
|
public class Robot : Joueur
|
|
{
|
|
private static int nbRobots = 0;
|
|
|
|
private List<Code>? codesPossibles;
|
|
|
|
/// <summary>
|
|
/// Initialise une nouvelle instance de la classe <see cref="Robot"/>.
|
|
/// </summary>
|
|
public Robot() :
|
|
base($"Naps {++nbRobots}")
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initialise une nouvelle instance de la classe <see cref="Robot"/> avec le nom spécifié.
|
|
/// </summary>
|
|
/// <param name="nom">Le nom du robot.</param>
|
|
public Robot(string nom) :
|
|
base(nom)
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Méthode appelée lorsqu'un joueur doit jouer dans une partie.
|
|
/// </summary>
|
|
/// <param name="sender">La source de l'événement.</param>
|
|
/// <param name="e">Les arguments de l'événement.</param>
|
|
public override void QuandDemanderJoueurJouer(object? sender, PartieDemanderJoueurJouerEventArgs e)
|
|
{
|
|
if (e.Nom != Nom)
|
|
return;
|
|
|
|
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]);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Génère tous les codes possibles pour une taille de code donnée.
|
|
/// </summary>
|
|
/// <param name="tailleCode">La taille du code.</param>
|
|
private void GenererTousCodesPossibles(int tailleCode)
|
|
{
|
|
// Obtient toutes les valeurs de l'énumération Couleur
|
|
Couleur[] couleurs = Enum.GetValues<Couleur>();
|
|
|
|
// Calcule le nombre total de combinaisons possibles
|
|
int nbLignes = (int)Math.Pow(couleurs.Length, tailleCode);
|
|
|
|
// Crée une matrice pour stocker les jetons de chaque combinaison
|
|
Jeton?[,] jetons = new Jeton?[nbLignes, tailleCode];
|
|
|
|
// Pour chaque colonne de la matrice
|
|
for (int indiceColonne = 0; indiceColonne < jetons.GetLength(1); ++indiceColonne)
|
|
{
|
|
// Calcule le nombre de répétitions pour chaque couleur
|
|
int repetition = nbLignes / (int)Math.Pow(couleurs.Length, (indiceColonne + 1));
|
|
|
|
// Pour chaque ligne de la matrice
|
|
for (int indiceLigne = 0; indiceLigne < jetons.GetLength(0); ++indiceLigne)
|
|
{
|
|
// Calcule l'indice de la couleur à utiliser dans cette colonne
|
|
int couleurIndex = (indiceLigne / repetition) % couleurs.Length;
|
|
|
|
// Crée un jeton avec la couleur correspondante et l'ajoute à la matrice
|
|
jetons[indiceLigne, indiceColonne] = new Jeton(couleurs[couleurIndex]);
|
|
}
|
|
}
|
|
|
|
// Pour chaque combinaison de jetons générée
|
|
for (int i = 0; i < jetons.GetLength(0); ++i)
|
|
{
|
|
// Crée un nouveau code avec les jetons de la combinaison
|
|
Code code = new Code(tailleCode);
|
|
for (int j = 0; j < jetons.GetLength(1); ++j)
|
|
{
|
|
code.AjouterJeton(jetons[i, j]!.Value);
|
|
}
|
|
|
|
// Ajoute le code à la liste des codes possibles
|
|
codesPossibles!.Add(code);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Vérifie si un code est possible sur le plateau.
|
|
/// </summary>
|
|
/// <param name="plateau">Le plateau de jeu.</param>
|
|
/// <param name="code">Le code à vérifier.</param>
|
|
/// <returns>True si le code est possible, sinon False.</returns>
|
|
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);
|
|
|
|
// Vérifie si les indicateurs du code correspondent aux indicateurs du plateau
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Supprime les codes impossibles du plateau.
|
|
/// </summary>
|
|
/// <param name="plateau">Le plateau de jeu.</param>
|
|
private void SupprimerCodesImpossibles(Plateau plateau)
|
|
{
|
|
if (codesPossibles == null)
|
|
return;
|
|
|
|
List<int> indicesASupprimer = new List<int>();
|
|
|
|
// Pour chaque code possible
|
|
for (int i = codesPossibles.Count - 1; i >= 0; --i)
|
|
{
|
|
// Vérifie s'il est possible sur le plateau
|
|
if (!EstCodePossible(plateau, codesPossibles.ElementAt(i)))
|
|
indicesASupprimer.Add(i);
|
|
}
|
|
|
|
// Supprime les codes impossibles de la liste
|
|
foreach (int indice in indicesASupprimer)
|
|
codesPossibles.RemoveAt(indice);
|
|
}
|
|
}
|
|
}
|