/// G. Hagopian - PPP5 Ex 12

/**
Implement a little guessing game called (for some obscure reason) “Bulls and Cows.”
The program has a vector of four different integers in the range 0 to 9
(e.g., 1234 but not 1122) and it is the user’s task to discover those numbers by
repeated guesses. Say the number to be guessed is 1234 and the user guesses 1359;
the response should be “1 bull and 1 cow” because the user got one digit (1) right
and in the right position (a bull) and one digit (3) right but in the
wrong position (a cow). The guessing continues until the user gets four bulls,
that is, has the four digits correct and in the correct order.
*/

#include "std_lib_facilities.h"

const int nSlots{4}; ///number of different ints in secret code
const int range{7};

void createSecretCode(vector<int> &secretCode);
void getGuess(vector<int> &guess);
int scoreBulls(vector<int> secretCode, vector<int> &guess);
int scoreCows(vector<int> secretCode, vector<int> &guess);
void show(vector<int>);

int main() {
    srand(time(0));
    int bulls{0}, cows{0};
    vector<int> secretCode;
    ///create secret code
    createSecretCode(secretCode);
    //show(secretCode);
    ///get a guess
    vector<int> guess;
    vector<vector<int> > guesses;
    getGuess(guess);
    guesses.push_back(guess);
    cout << "\nYour guess is: ";
    show(guess);
    ///score the guess
    bulls = scoreBulls(secretCode,guess);
    cows = scoreCows(secretCode, guess);
    cout << "\nThat's " << bulls
         << " bull" << ((bulls!=1) ? "s" : "")
         << " and " << cows
         << " cow" << (cows!=1 ? "s" : "") << ".";
    while(bulls != nSlots) {/// while game not over
        ///get guess
        getGuess(guess);
        ///score guess
        bulls = scoreBulls(secretCode,guess);
        cows = scoreCows(secretCode, guess);
        cout << "\nThat's " << bulls
             << " bull" << ((bulls!=1) ? "s" : "")
             << " and " << cows
             << " cow" << (cows!=1 ? "s" : "") << ".";

        ///show guesses
        guesses.push_back(guess);
        for(int i = 0; i < guesses.size(); ++i)
            show(guesses[i]);
    }
    cout << "\n\nCongratulations, you won after "
         << guesses.size() << " guesses.";
}

void createSecretCode(vector<int> &secretCode) {
    int cntr{0}, rndNum{0};
    bool isNew;
    secretCode.push_back(rand()%range);
    do {
        rndNum = rand()%range;
        isNew = true;
        for(int i = 0; i < secretCode.size(); ++i)
            if(rndNum == secretCode[i])
                isNew = false;
        if(isNew) {
            secretCode.push_back(rndNum);
        }
    } while(secretCode.size()<nSlots);
}

void show(vector<int> v) {
    cout << endl;
    for(int i = 0; i < v.size(); ++i) {
        if(i>=nSlots) cout << "  ";
        cout << v[i] << " ";
    }

}

void getGuess(vector<int> &guess) {
    int n{0};
    guess.clear();
    cout << "\nEnter " << nSlots << " positive integers less than "
         << range << ": ";
    for(int i = 0; i < nSlots; ++i) {
        do {
            cin >> n;
            if(n < 0 || n > range-1)
                cout << "\nThat's not a good entry, try again: ";
        } while(n < 0 || n > range-1);
        guess.push_back(n);
    }
}


int scoreBulls(vector<int> secretCode, vector<int> &guess) {
    int bulls{0};
    for(int i = 0; i < nSlots; ++i)
        if(secretCode[i]==guess[i])
            ++bulls;
    guess.push_back(bulls);
    return bulls;
}

int scoreCows(vector<int> secretCode, vector<int> &guess) {
    int cows{0};
    for(int i = 0; i < nSlots; ++i) /// for each secret code
        for(int j = 0; j < nSlots; ++j) {
            if(guess[j]==secretCode[i] && i != j) {
                ++cows;
                break;
            }
        }
    guess.push_back(cows);
    return cows;
}
