TrippleX Bug in my code

I am playing around with trying to make the trippleX game on my own to see if i can. I am having a bit of trouble with my code, if you enter a non-integer in the guess portion, the loop just runs 5 times (MaxTries number) and exits. I am using std::cin.fail() to check for non-integers after declaring the input variables as int’s. This works in a “closed” test but in the method mentioned below it fails, i expect it to return an array of int size 3 holding 1, 1, 1 and then proceed to check that against the pre-defined code. I’m not sure what the problem is to be honest.

EDIT:

i think this is because the std::cin will stop processing after the first instance of a non-integer. So i guess my question would be what is a good way to account for a non-integer or should i just let it convert to 0 ?

#include <iostream>
#include <array>

// print intro
void PrintIntro()
{
    std::cout << "Enter the correct code to live. When you fail, I take your life.\n";
    std::cout << "Your guess friend: \n";
}

// print hints
void PrintHints(std::array<int, 2> CodeHints)
{
    std::cout << "There are 3 numbers in this code. \n";
    std::cout << CodeHints[0] << " Is what the code adds up to.\n";
    std::cout << CodeHints[1] << " is the product of the code.\n";
}

// Check Guess
std::array<int, 2> &CheckGuess(std::array<int, 3> Guess, std::array<int, 3> Code)
{
    int CorrectPlace = 0;
    int CorrectNumbers = 0;
    for ( int i = 0; i < Guess.size(); i++ )
    {
        for ( int j = 0; j < Code.size(); j++)
        {
            if ( Guess[i] == Code[j])
            {
                if ( i == j)
                {
                    CorrectPlace++;
                } else
                {
                    CorrectNumbers++;
                }
                
            }
        }

    }
    std::array<int, 2> GuessCount = { CorrectPlace, CorrectNumbers};
    return GuessCount;
}

// get guess returns array of size 3
std::array<int, 3> &GetGuess()
{
    int GuessA, GuessB, GuessC;
    std::cin >> GuessA >> GuessB >> GuessC;
    if ( std::cin.fail() )
    {
        std::cout << "Only integers are allowed you dirty human.\n";
        std::array<int, 3> Guess = { 1, 1, 1 };
        return Guess;
    }
    std::array<int, 3> Guess = {GuessA, GuessB, GuessC};
    return Guess;
}

// Setup Code and Generate Hints
std::array<int, 2> &SetCode(std::array<int, 3> Code)
{
    int CodeSum = Code[0] + Code[1] + Code[2];
    int CodeProduct = Code[0] * Code[1] * Code[2];
    std::array<int, 2> CodeHints;
    CodeHints = {CodeSum, CodeProduct};
    return CodeHints;
}

// main game
void PlayGame()
{
    std::array<int, 3> Code = { 2, 3, 7};
    std::array<int, 2> CodeHints = SetCode(Code);
    std::array<int, 3> Guess =  GetGuess();
    std::array<int, 2> GameWon = CheckGuess(Guess, Code);
    bool HintShown = false;
    if (HintShown == false)
    {
        PrintHints(CodeHints);
        HintShown = true;
    }
    if ( GameWon[0] == 3 )
    {
        std::cout << "Unclear how you made it, but you may live.\n";
    } else
    {
        std::cout << "I have a right to your life, when and how I may choose.\n";
        std::cout << "You had: " << GameWon[0] << " numbers in the correct place.\n";
        std::cout << "You had: " << GameWon[1] << " numbers correct, but in the wrong place.\n";
    }
    
}

int main()
{
    int MaxTries = 5;
    int CurrentTry = 1;
    PrintIntro();
    do
    {
        PlayGame();
        CurrentTry++;
    }while ( CurrentTry != MaxTries); 
    return 0;
}    

if ( std::cin.fail() )

If this is true then it will be true for the rest of the program. You need to clear the fail bit and discard the buffer.

std::cin.clear();
std::cin.ignore();

First line clears the failbit so std::cin can extract characters again
Second extracts a character and discards it. If you want to discard the entire contents of std::cin instead of just a single character then you would need to #include <limits> and then do this instead

std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

std::streamsize is the type used for std::cin's stream size
std::numeric_limits allows you to get the numeric limits of a type e.g.
std::numeric_limits<int>::max() would give you the max size of an int.


On a side note addition and multiplication are both associative and cumulative so the orders of the operations don’t matter i.e. a + b + c == b + c + a.
So someone can get the code “correct” according to the message in your intro but not validate your check.

And in your functions you are returning a reference to a local variable. Local variables are destroyed at the end of their scope so returning a reference to that would mean referencing something that no longer exists.

Awesome! i should have looked more closely at the documentation for std::cin.fail() and I wouldn’t have had to bother you. I just assumed that once std::cin hit a fail condition it would clear the buffer and allow the next iteration to pass.

For the side note, i want the user to guess not only the numbers but the ordering as well. Not that anyone will be running this but me : )

That was more of a “just in case you aren’t aware” side note :stuck_out_tongue:.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms