using CoreLibrary.Exceptions;
using System.Security.Cryptography;
namespace CoreLibrary.Core
{
///
/// Classe représentant un plateau de jeu composé de codes et leurs indicateurs ainsi que les méthodes associées.
///
public class Plateau
{
private readonly Code codeSecret;
private readonly Code?[] grille;
private readonly IEnumerable[] indicateurs;
private readonly int tailleCode;
///
/// Le numéro de tour actuel.
///
public int Tour { get; private set; } = 1;
///
/// La victoire du joueur, True si le joueur a gagné sinon False
///
public bool Victoire { get; private set; } = false;
///
/// Initialise une nouvelle instance de la classe .
///
/// Taille des codes du plateau.
/// Taille du plateau de jeu.
/// Levée lorsque la tailleCode est inférieure ou égale à 0.
/// Levée lorsque la tailleGrille est inférieure ou égale à 0.
public Plateau(int tailleCode, int tailleGrille)
{
if (tailleCode <= 0)
{
throw new TailleCodeException(tailleCode);
}
if (tailleGrille <= 0)
{
throw new TailleGrilleException(tailleGrille);
}
codeSecret = new Code(tailleCode);
grille = new Code?[tailleGrille];
indicateurs = new IEnumerable[tailleGrille];
this.tailleCode = tailleCode;
GenererCodeAleatoire();
}
///
/// Génère un code secret aléatoire en utilisant des jetons de couleurs aléatoires.
///
private void GenererCodeAleatoire()
{
Couleur[] couleurs = (Couleur[])Enum.GetValues(typeof(Couleur));
for (int i = 0; i < tailleCode; ++i)
{
codeSecret.AjouterJeton(new Jeton(couleurs[RandomNumberGenerator.GetInt32(0, couleurs.Length)]));
}
}
///
/// Vérifie si le plateau de jeu est plein.
///
/// True si la tableau est plein, sinon False.
public bool EstComplet()
{
return Tour - 1 == grille.Length;
}
///
/// Ajoute le code fourni au plateau de jeu.
///
/// Le code à ajouter au plateau de jeu.
/// Levée lorsque le code fourni à une taille invalide.
/// Levée lorsque le code fourni est incomplet.
public void AjouterCode(Code code)
{
if (code.NbJetonsMax != tailleCode)
{
throw new CodeInvalideException(code.NbJetonsMax, tailleCode);
}
if (!code.EstComplet())
{
throw new CodeIncompletException();
}
indicateurs[Tour - 1] = codeSecret.Comparer(code);
grille[Tour - 1] = code;
++Tour;
if (EstBonCode(code))
{
Victoire = true;
}
}
///
/// Vérifie si le code fourni correspond au code secret.
///
/// Le code à vérifier.
/// True si le code fourni correspond au code secret, sinon False
/// Levée lorsque le code fourni à une taille invalide.
/// Levée lorsque le code fourni est incomplet.
public bool EstBonCode(Code code)
{
if (code.NbJetonsMax != tailleCode)
{
throw new CodeInvalideException(code.NbJetonsMax, tailleCode);
}
if (!code.EstComplet())
{
throw new CodeIncompletException();
}
IEnumerable indicateursCode = codeSecret.Comparer(code);
if (indicateursCode.Count() != tailleCode)
{
return false;
}
foreach (Indicateur indicateur in indicateursCode)
{
if (indicateur != Indicateur.BONNEPLACE)
{
return false;
}
}
return true;
}
///
/// Récupère le plateau de jeu.
///
/// Le plateau de jeu représenté sous forme d'un tableau de tableau de jetons.
public IEnumerable> Grille()
{
IEnumerable[] grilleJetons = new IEnumerable[grille.Length];
for (int i = 0; i < grille.Length; ++i)
{
grilleJetons[i] = grille[i]?.Jetons ?? new Code(tailleCode).Jetons;
}
return grilleJetons;
}
///
/// Récupère les indicateurs pour chaque tour.
///
/// Les indicateurs pour chaque tour représentés sous forme d'un tableau de tableau d'indicateurs.
public IEnumerable> Indicateurs()
{
return indicateurs;
}
}
}