/*______________________________________________________________________
 * mastermind
 * par Martin Robinson
 * c'est un jeu
 * ______________________________________________________________________
 * preprocesseur
 */
#include "mastermind.hpp"

#include <time.h>
#include <stdlib.h>
#include <iostream>
#include <assert.h>

/*______________________________________________________________________
 * methode
 */

//---------------------------objet ligne caché---------------------------
//semblable à l'objet analyse
//il sert de classe de base 
//contien le code aléatoire sans répétition
//-----------------------------------------------------------------------
//constructeur
//à l'initialisation, l'objet se randomise un chaine de couleure différente
master::master()
{
    int nuColor = vide;     //nouvelle couleur temporaire
    _arr.resize(5,0);       //initialise le vector
    srand ( time(NULL) );   //initialisation du randomizer
    for (int i=0;i<5;i++)
    {
        do{
            nuColor = (rand() % 8) + 1; //numéraux de couleur aléatoir entre 1 et 8 inclusivement
        }while (have(nuColor));         //recommence tanque la couleur est déjà là
        _arr[i] = nuColor;              //avec un success on stock la couleur
    }
}

//destructeur
master::~master()
{
    for (int i=0;i<5;i++)   //initialiser le tableau à 0
        _arr[i] = vide;     //histoir de rendre le destructeur utile
}

//setter
void master::setColor(const int index, const int color)
{
    assert(index < 5 && index >= 0);    //s'assurer que l'index soit valide
    assert(color >=0 && color < 9);     //s'assurer que la couleur soit valide
    _arr[index] = color;
}

//getter
const int master::getColor(const int index)const
{
    assert(index < 5 && index >= 0);    //s'assurer que l'index est valide
    return _arr[index];
}

//verifi si la couleur est présente dans la liste
//si une seule couleur est égale à la couleur donnée
bool master::have(const int color)const
{
    for (int i=0;i<5;i++)
        if (_arr[i] == color)
            return true;
    return false;
}

//-------------------------objet ligne joué-------------------------------
//ce sont les 12 ligne que le joueur pourra modifier
//c'est littéralement l'objet combinaison

//------------------------------------------------------------------------

//constructeur
//initialise toute les couleurs à vide
mind::mind()
{
    _arr.resize(5,vide);    //initialise le vector à 5
    for (int i=0;i<5;i++)
        setColor(i,vide);
}

//destructeur
//remet le vector à 0 histoire d'être utile
mind::~mind()
{
    for (int i=0;i<5;i++)
        setColor(i,vide);
}

//compte le nombre de couleur qui sont reciproque entre le master et le mind
//pour chaque couleur dans la reference, est-il présent dans la combinaison donné
int mind::matchingColor(const master & ref)const
{
    int count = 0;
    for (int i=0;i<5;i++)
        if (have(ref.getColor(i)))
            count++;
    return count;
}

//compte le nombre de couleur à la bonne place
//simple verification si les deux tableau sont identique
//compte les index identique
int mind::rightPlace(const master & ref)const
{
    int count = 0;
    for (int i=0;i<5;i++)
        if (getColor(i) == ref.getColor(i))
            count++;
    return count;
}

//verifie si la ligne est completer
//facilite la saisie de donné
bool mind::done()
{
    for (int i=0;i<5;i++)
        if (getColor(i) == vide)
            return false;
    return true;
}

//--------------------------objet partie----------------------------------

//constructeur
masterMind::masterMind()
{
    _current = 0;
    _turn.resize(12);
}

//destructeur
masterMind::~masterMind()
{
    _current = 0;
}

//la partie est terminé s'il n'y a plus de ligne à jouer
//ou que c'est gagné
bool masterMind::done()
{
    return _current >= 12 || win();
}



//condition gagnante
//verifie la ligne courrante si elle est gagnante
//impossible de rendre "const" cette fonction car elle dépend de currentM()
bool masterMind::win()
{
    return (currentM().rightPlace(_hidden) == 5);
}

//mutator
//iterator
//on avance d'une ligne
//si il en reste
//si on a pas encore gagné
//si la ligne courrante est completé
void masterMind::inc()
{
    if (_current < 12 && !win() && currentM().done())
        _current++;
}

//iterator
//donne la ligne courrante
mind& masterMind::currentM()
{
    if (_current < 12)
        return _turn[_current];
    return _turn[11];
}

//surcharge pour acceder à n'importequelle ligne
mind& masterMind::operator[](const int index)
{
    assert(index >= 0 && index < 12);
    if (index < 12)
        return _turn[index];
    return _turn[11];
}

