using CoreLibrary.Exceptions;
using System.Collections.ObjectModel;
using System.Runtime.Serialization;
namespace CoreLibrary.Core
{
///
/// Classe représentant un code composé de jetons et ses différentes méthodes.
///
[DataContract]
public class Code
{
private readonly ObservableCollection lesJetons = new ObservableCollection();
///
/// Le nombre maximum de jetons dans le code.
///
[DataMember]
public int NbJetonsMax { get; private set; }
///
/// Le nombre de jetons dans le code.
///
[DataMember]
public int NbJetons { get => lesJetons.Count; }
[DataMember]
public ObservableCollection Jetons => lesJetons;
///
/// Initialise une nouvelle instance de la classe avec la longueur de code spécifiée.
///
/// La longueur du code.
/// Levée lorsque la longueur du code spécifiée est inférieure ou égale à zéro.
public Code(int tailleCode)
{
NbJetonsMax = tailleCode;
if (tailleCode <= 0)
{
throw new TailleCodeException(tailleCode);
}
}
///
/// Initialise une nouvelle instance de la classe avec les jetons spécifiés.
///
/// Les jetons pour initaliser le code.
/// Levée lorsque la collection de jetons spécifiée est vide.
public Code(IEnumerable jetons)
{
if (!jetons.Any())
{
throw new TailleCodeException(jetons.Count());
}
NbJetonsMax = jetons.Count();
foreach (Jeton jeton in jetons)
{
AjouterJeton(jeton);
}
}
///
/// Ajoute un jeton au code.
///
/// Le jeton à ajouter.
/// Levée lorsque le code est plein.
public void AjouterJeton(Jeton jeton)
{
if (lesJetons.Count == NbJetonsMax)
{
throw new CodeCompletException();
}
lesJetons.Add(jeton);
}
///
/// Supprime le dernier jeton ajouté au code.
///
/// Levée lorsque le code est vide.
public void SupprimerDernierJeton()
{
if (lesJetons.Count == 0)
{
throw new CodeVideException();
}
lesJetons.RemoveAt(lesJetons.Count - 1);
}
///
/// Récupère le jeton à l'indice spécifié dans le code.
///
/// L'indice du jeton a récupéré.
/// Le jeton situé à l'indice spécifié.
/// Levée lorsque l'indice est supérieur à la taille maximale du code, inférieur à 0 ou qu'il n'y a pas de jeton à l'indice spécifié
public Jeton RecupererJeton(int indice)
{
if (indice < 0 || indice >= lesJetons.Count)
throw new IndiceCodeException(indice, lesJetons.Count - 1);
Jeton? jeton = lesJetons[indice];
if (!jeton.HasValue)
throw new IndiceCodeException(indice, lesJetons.Count - 1);
return jeton.Value;
}
///
/// Vérifie si le code est complet.
///
/// True si le code est complet, sinon False.
public bool EstComplet()
{
return lesJetons.Count == NbJetonsMax;
}
///
/// Compare le code avec un autre code et génère des indicateurs.
///
/// Le code à comparer avec le code actuel.
/// Les indicateurs de bonne place et bonne couleur entre les deux codes.
public IEnumerable Comparer(Code autreCode)
{
// Mon code est le code correct, l'autre code est celui qui teste
Indicateur[] indicateurs = [];
if (!autreCode.EstComplet())
return indicateurs;
List mesJetons = new List(Jetons);
List sesJetons = new List(autreCode.Jetons);
for (int i = 0; i < mesJetons.Count; ++i)
{
Jeton? monJeton = mesJetons[i];
Jeton? sonJeton = sesJetons[i];
if (monJeton.HasValue && sonJeton.HasValue && monJeton.Value.Couleur.Equals(sonJeton.Value.Couleur))
{
indicateurs = indicateurs.Append(Indicateur.BONNEPLACE).ToArray();
mesJetons[i] = null;
sesJetons[i] = null;
}
}
for (int i = 0; i < sesJetons.Count; ++i)
{
Jeton? sonJeton = sesJetons[i];
if (sonJeton.HasValue && mesJetons.Contains(sonJeton.Value))
{
indicateurs = indicateurs.Append(Indicateur.BONNECOULEUR).ToArray();
mesJetons[mesJetons.IndexOf(sonJeton)] = null;
sesJetons[i] = null;
}
}
return indicateurs;
}
}
}