using CoreLibrary.Core; using CoreLibrary.Evenements; namespace CoreLibrary.Joueurs { /// /// Représente un joueur automatique (robot). /// public class Robot : Joueur { private static int nbRobots; private List? codesPossibles; /// /// Le constructeur statique de /// static Robot() { nbRobots = 0; } /// /// Initialise une nouvelle instance de la classe . /// public Robot() : base($"Naps {nbRobots + 1}") { ++nbRobots; } /// /// Initialise une nouvelle instance de la classe avec le nom spécifié. /// /// Le nom du robot. public Robot(string nom) : base(nom) { } /// /// Méthode appelée lorsqu'un joueur doit jouer dans une partie. /// /// La source de l'événement. /// Les arguments de l'événement. public override void QuandDemanderJoueurJouer(object? sender, PartieDemanderJoueurJouerEventArgs e) { if (e.Nom != Nom) return; if (codesPossibles == null) codesPossibles = GenererTousCodesPossibles(e.Code.TailleMax); SupprimerCodesImpossibles(codesPossibles, e.Plateau); for (int i = 0; i < e.Code.TailleMax; ++i) e.Code.AjouterJeton(codesPossibles.ElementAt(0).Jetons[i]); } /// /// Génère tous les codes possibles pour une taille de code donnée. /// /// La taille du code. /// Une liste de tous les codes possibles pour la partie private static List GenererTousCodesPossibles(int tailleCode) { // Obtient toutes les valeurs de l'énumération Couleur Couleur[] couleurs = Enum.GetValues(); // 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]); } } List codes = new List(); // 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 codes!.Add(code); } return codes; } /// /// Vérifie si un code est possible sur le plateau. /// /// Le plateau de jeu. /// Le code à vérifier. /// True si le code est possible, sinon False. private static 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 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; } /// /// Supprime les codes impossibles du plateau. /// /// Le plateau de jeu. /// Une liste de tous les codes restants possibles. private static void SupprimerCodesImpossibles(List codes, Plateau plateau) { if (codes == null) return; List indicesASupprimer = new List(); // Pour chaque code possible for (int i = codes.Count - 1; i >= 0; --i) { // Vérifie s'il est possible sur le plateau if (!EstCodePossible(plateau, codes.ElementAt(i))) indicesASupprimer.Add(i); } // Supprime les codes impossibles de la liste foreach (int indice in indicesASupprimer) codes.RemoveAt(indice); } } }