My function being called twice for some reason?

Hi,

I have a question about my code here. I implemented a system where it tracks the number of attempts a player takes and will stop the game at a certain amount of guesses (the AttemptedGuesses() function). However, I have found that when I answer (either correct or incorrect) it always somehow calls the function twice.

For example, if I enter in the correct code, it prints something like:

You entered: 111
— Correct! Move on to the next vault for even MORE money! —

— Oh no! Wrong code, try again but be careful. You only have 3 total attempts! —
— Attempts Left: 3 —

And when I enter the wrong code it prints something like:

You entered: 112
— Oh no! Wrong code, try again but be careful. You only have 3 total attempts! —
— Attempts Left: 2 —

— Oh no! Wrong code, try again but be careful. You only have 3 total attempts! —
— Attempts Left: 2 —

I’m not sure why this is happening. Could someone read over my code and tell me the issue?

Thank you so much!

P.S. I’m not sure if this is the most effective way of sharing my code in C++, if there is a better way, please let me know! Thanks :slight_smile:

#include <iostream>
#include <ctime>

// Any variables I need throughout code
int Attempts;

void PrintIntroduction(int Difficulty)
{
  // Story for the game
    std::cout << "\n--- You're a bank robber currently at the door of a level " << Difficulty;
    std::cout << " vault. ---\n--- You must find the code that opens the vault door in order to get your money... ---\n";
    std::cout << "--- You will have 3 attempts at each level. ---\n--- If you fail on your third attempt, the police will catch up and you will fail the mission. ---\n\n";
}

// Code to determaine how many guesses they are at
bool AttemptedGuesses()
{
    if (Attempts == 0) {
        return true;
    }
    else {
        std::cout << "\n--- Oh no! Wrong code, try again but be careful. You only have 3 total attempts! ---\n";
        std::cout << "--- Attempts Left: " << Attempts << " ---" << std::endl << std::endl;
        return false;
    }
}

bool PlayGame(int Difficulty) 
{
    
    PrintIntroduction(Difficulty);

    // Declare the 3 number code
    const int CodeA = rand() % Difficulty + 1;
    const int CodeB = rand() % Difficulty + 1;
    const int CodeC = rand() % Difficulty + 1;

    const int CodeSum = CodeA + CodeB + CodeC;
    const int CodeProduct = CodeA * CodeB * CodeC;
    
    // Print the sum and product to the terminal
    std::cout << CodeA << CodeB << CodeC;
    std::cout << "There are 3 numbers in the code\n";
    std::cout << "The codes add up to: " << CodeSum;
    std::cout << "\nThe codes multiply to give: " << CodeProduct << std::endl;

    // Store player guess
    int GuessA, GuessB, GuessC;
    std::cout << "\nFirst Number of the Code: ";
    std::cin >> GuessA; 
    std::cout << "Second Number of the Code: ";
    std::cin >> GuessB; 
    std::cout << "Third Number of the Code: ";
    std::cin >> GuessC;
    std::cout << "\n\nYou entered: " << GuessA << GuessB << GuessC;

    int GuessSum = GuessA + GuessB + GuessC;
    int GuessProduct = GuessA * GuessB * GuessC;

    // Check player message
    if (GuessSum == CodeSum && GuessProduct == CodeProduct) 
        {
        //  std::cout << std::endl << Attempts << std::endl;
        std::cout << "\n--- Correct! Move on to the next vault for even MORE money! ---\n";
        Attempts = 3;
        return true;
        }
    else {
        Attempts = Attempts - 1;
        AttemptedGuesses();
        return false;
        }
}

int main()
{
    srand(time(NULL));
    int LevelDifficulty = 1;
    int const MaxDifficulty = 10;
    
    // To display what level player failed on
    int CurrentLevel = 0;
    CurrentLevel = LevelDifficulty;

    while (LevelDifficulty <= MaxDifficulty) // Loop game until all levels are completed.
    {
        bool bLevelComplete = PlayGame(LevelDifficulty);   
        std::cin.clear();
        std::cin.ignore();
        
        if (bLevelComplete) 
        {
            ++LevelDifficulty;
        }

        if (AttemptedGuesses()) 
        {
            LevelDifficulty = 15;
        }
    }
    
    // To determain a win or loss
    if (LevelDifficulty == 11)
    {
        std::cout << "--- Congrats! You emptied out the bank and are driving away in your runaway care to live a life of luxury on a private island! ---\n\n";
        return 0;
    }
    else 
    {
        std::cout << "\n\n--- You failed your third attempt and were caught by the police! Oh no! Better luck next time! :) ---\n";
        std::cout << "--- You were on level: " << CurrentLevel << ". ---\n\n";
        return 0;
    }
    
    
}

It’s called twice because you call it twice.

In main:

if (bLevelComplete) 
{
    ++LevelDifficulty;
}

if (AttemptedGuesses()) // here
{
    LevelDifficulty = 15;
}

In PlayGame:

if (GuessSum == CodeSum && GuessProduct == CodeProduct)
{
    //  std::cout << std::endl << Attempts << std::endl;
    std::cout << "\n--- Correct! Move on to the next vault for even MORE money! ---\n";
    Attempts = 3;
    return true;
}
else {
    Attempts = Attempts - 1;
    AttemptedGuesses(); // here
    return false;
}

Could you explain what your intention of AttemptedGuesses is for? Because the comment says one thing but the code does another. I would expect a function with the comment “Code to determaine how many guesses they are at” to return an integer not a bool.

As an aside non-const global variables are generally best avoided and your situation here isn’t an exception. If you make Attempts a local variable of main and pull out code in PlayGame that handles whether the guess was correct or not, then it you don’t need Attempts across functions.

End of PlayGane:

int GuessSum = GuessA + GuessB + GuessC;
int GuessProduct = GuessA * GuessB * GuessC;

return GuessSum == CodeSum && GuessProduct == CodeProduct

In main:

int Attempts = 0;
while (LevelDifficulty <= MaxDifficulty) // Loop game until all levels are completed.
{
    bool bLevelComplete = PlayGame(LevelDifficulty);
    std::cin.clear();
    std::cin.ignore();

    if (bLevelComplete)
    {
        // Do something with Attempts
        // Print some text
        ++LevelDifficulty;
    }
    else
    {
        // Do something else with Attempts
        // Print some text
    }
}

Ok, so to be clear, whenever I write AttemptedGuesses() in the main function it will call it, no matter where that function call is (Ex. in this case, it was inside of an “if” statement)

My original intention with AttemptedGuesses() was to record the number of tries the player took on the level, and as long as the number of tries was not equal to zero, the code would loop and they could have another try at the level. I thought of using booleans because it felt easier to return TRUE (when the player used up all their guesses) and FALSE (when the player had guessed). The “if” statement as the bottom was meant to be something like if (AttemptedGuesses returns true) then do etc etc. Rather than trying to call the function.

And I took your suggestion and it ended up working! I guess I was trying to be too fancy when trying to a separate function to count the number of attempts the player had taken. I included my code at the bottom again if you can make any more suggestions.

Thank you so much for the help!

#include <iostream>
#include <ctime>

// Any variables I need throughout code
// int Attempts = 3;

void PrintIntroduction(int Difficulty)
{
  // Story for the game
    std::cout << "\n--- You're a bank robber currently at the door of a level " << Difficulty;
    std::cout << " vault. ---\n--- You must find the code that opens the vault door in order to get your money... ---\n";
    std::cout << "--- You will have 3 attempts at each level. ---\n--- If you fail on your third attempt, the police will catch up and you will fail the mission. ---\n\n";
}

// Code to determaine how many guesses they are at
// bool AttemptedGuesses()
// {
//     if (Attempts == 0) {
//         return true;
//     }
//     else {
//         std::cout << "\n--- Oh no! Wrong code, try again but be careful. You only have 3 total attempts! ---\n";
//         std::cout << "--- Attempts Left: " << Attempts << " ---" << std::endl << std::endl;
//         return false;
//     }
// }

bool PlayGame(int Difficulty) 
{
    
    PrintIntroduction(Difficulty);

    // Declare the 3 number code
    const int CodeA = rand() % Difficulty + 1;
    const int CodeB = rand() % Difficulty + 1;
    const int CodeC = rand() % Difficulty + 1;

    const int CodeSum = CodeA + CodeB + CodeC;
    const int CodeProduct = CodeA * CodeB * CodeC;
    
    // Print the sum and product to the terminal
    std::cout << CodeA << CodeB << CodeC;
    std::cout << "There are 3 numbers in the code\n";
    std::cout << "The codes add up to: " << CodeSum;
    std::cout << "\nThe codes multiply to give: " << CodeProduct << std::endl;

    // Store player guess
    int GuessA, GuessB, GuessC;
    std::cout << "\nFirst Number of the Code: ";
    std::cin >> GuessA; 
    std::cout << "Second Number of the Code: ";
    std::cin >> GuessB; 
    std::cout << "Third Number of the Code: ";
    std::cin >> GuessC;
    std::cout << "\n\nYou entered: " << GuessA << GuessB << GuessC << std::endl;

    int GuessSum = GuessA + GuessB + GuessC;
    int GuessProduct = GuessA * GuessB * GuessC;

    return GuessSum == CodeSum && GuessProduct == CodeProduct;

    // Check player message to see if its correct
    // if (GuessSum == CodeSum && GuessProduct == CodeProduct) 
    //     {
    //     std::cout << "\n--- Correct! Move on to the next vault for even MORE money! ---\n";
    //     Attempts = 3;
    //     return true;
    //     }
    // else {
    //     Attempts = Attempts - 1;
    //     AttemptedGuesses();
    //     return false;
    //     }
}

int main()
{
    srand(time(NULL));
    int LevelDifficulty = 1;
    int const MaxDifficulty = 10;
    
    // To display what level player failed on
    int CurrentLevel = 0;
    CurrentLevel = LevelDifficulty;
    int Attempts = 3;

    while (LevelDifficulty <= MaxDifficulty) // Loop game until all levels are completed.
    {
        bool bLevelComplete = PlayGame(LevelDifficulty);
        std::cin.clear();
        std::cin.ignore();
        
        if (bLevelComplete) {
            Attempts = 3;
            std::cout << "\n--- Correct! Move on to the next vault for even MORE money! ---\n";
            ++LevelDifficulty;
        }
        else {
            Attempts = Attempts - 1;
            std::cout << "\n--- Oh no! Wrong code, try again but be careful. You only have 3 total attempts! ---\n";
            std::cout << "--- Attempts Left: " << Attempts << " ---" << std::endl << std::endl;
        }

        if (Attempts == 0) {
            LevelDifficulty = 15;
        }
    }
    
    // To determain a win or loss
    if (LevelDifficulty == 11)
    {
        std::cout << "--- Congrats! You emptied out the bank and are driving away in your runaway care to live a life of luxury on a private island! ---\n\n";
        return 0;
    }
    else 
    {
        std::cout << "--- You failed your third attempt and were caught by the police! Oh no! Better luck next time! :) ---\n";
        std::cout << "--- You were on level: " << CurrentLevel << ". ---\n\n";
        return 0;
    }
    
    
}

In any function, but yes. If Foo is a function Foo() calls it

Then CanAtempt or similar would be a better name, can/is/has/etc. are yes/no questions so a bool is what you would expect to be returned. “AttemptedGuesses” on the other hand does not convey that and sounds more of a question of quantity i.e “how many guesses have been attempted”

Something to think about, how would it know what it returned without calling the function?


The code looks good, just one minor, there’s a shorthand for a = a - 1 which is --a (similarly with +).

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

Privacy & Terms