Thread: Slot Machine program c++ bug

  1. #1
    Registered User
    Join Date
    Sep 2009
    Posts
    8

    Slot Machine program c++ bug

    Well, i started my C++ book again after a year to learn more about the hardware of a computer, binary and others so i would understand more about my code and so i understand what i am doing.

    So here is my code and i will explain the bug at the bottom.

    Code:
    #include <iostream>
    #include <cstdlib>
    #include <time.h>
    
    using namespace std;
    
    typedef unsigned short int USHORT;
    
    const USHORT tokensThree = 3;
    const USHORT tokensTwo = 2;
    USHORT tokens = 12;
    const char playY = 'y';
    char inputYes;
    const USHORT highRandom = 6;
    USHORT randomNumber;
    USHORT randomNumberTwo;
    USHORT randomNumberThree;
    
    int winThreeTokens(int firstNumber, int secondNumber, int thirdNumber)
    {
        if(firstNumber==secondNumber==thirdNumber)
        {
            cout << "Congratulations! You WON 3 Tokens!" << endl;
            tokens = tokens + tokensThree;
            cout << "You know have " << tokens << "tokens.";
        }
        return(firstNumber, secondNumber, thirdNumber);
    }
    
    int winTwoTokens(int firstNumber, int secondNumber, int thirdNumber)
    {
        if(firstNumber==secondNumber || firstNumber==thirdNumber || secondNumber==thirdNumber)
        {
            cout << endl << "Congratulations! You WON 2 Tokens!" << endl;
            tokens = tokens + tokensTwo;
            cout << "You know have " << tokens << "tokens.";
        }
        return(firstNumber, secondNumber, thirdNumber);
    }
    
    int Lose(int firstNumber, int secondNumber, int thirdNumber)
    {
        if(firstNumber!=secondNumber!=thirdNumber)
        {
            cout  << endl << "HAHAHA Sorry, You lost THREE Tokens!";
            tokens = tokens - 3;
            if(tokens==0)
            {
                cout << endl << "You have " << tokens << "tokens.";
                cout << endl << "Game Over!";
                cout << endl << "Now Exiting...";
                exit(0);
            }
            cout << endl << "You know have " << tokens << "tokens.";
        }
        return(firstNumber, secondNumber, thirdNumber);
    }
    
    void lever()
    {
        time_t clockTimeSeconds;
        time(&clockTimeSeconds);
        srand((unsigned int) clockTimeSeconds);
        randomNumber = rand() % highRandom + 1;
        randomNumberTwo = rand() % highRandom + 1;
        randomNumberThree = rand() % highRandom + 1;
        cout << endl << "Do you want to pull the BIG Lever right beside you?" << endl;
        cout << "If so, Please type 'y' and press Return." << endl;
        cin >> inputYes;
        if(inputYes==playY)
        {
            cout << "Your numbers are:\t" << randomNumber << "\t" << randomNumberTwo << "\t" << randomNumberThree;
            winThreeTokens(randomNumber, randomNumberTwo, randomNumberThree);
            winTwoTokens(randomNumber, randomNumberTwo, randomNumberThree);
            Lose(randomNumber, randomNumberTwo, randomNumberThree);
        }
    }
    
    void welcome()
    {
        cout << "Welcome to the most amazing text-based Slot Machine!" << endl;
        cout << "Our fine Slot Machines are rigged so that you almost never win and so that we make BILLIONS of DOLLARS!" << endl;
        cout << "Anyways, You have " << tokens << "tokens" << endl;
        cout << "Soooo, have fun with these few tokens as you will have none left very, very, very SOON!" << endl;
    }
    
    int main()
    {
        welcome();
        for(int playTime = 0; playTime<30001; playTime++)
        {
            lever();
        }
        return 0;
    }
    the bug is that when you execute the application and you type "y" for your first set of random numbers and you get like "6 6 5" for example it will grant you your 2 tokens but then think that you lost and take away 3. After that happens once and get another set of 3 random numbers like "3 3 4", you get your 2 tokens and it doesn't take away the 3 like ti should work.

    I just finished lesson 3 where it went over brief explanation of a function, how to call one, what it is to get you familiar with it but not to explain the whole 9 yards, which is in another lesson.

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    This: if(firstNumber==secondNumber==thirdNumber) doesn't do what you think; whichever of the == gets executed first (I think it's the second one, but I'd have to look it up) will return either 0 or 1, and then the first number is compared to that result (not the values of the other variables). Ditto in your lose routine.

  3. #3
    Registered User
    Join Date
    Sep 2009
    Posts
    63
    I believe your problem might be in this condition:

    Code:
    firstNumber!=secondNumber!=thirdNumber
    I would rewrite it to use the && operator.

    Another problem is that you always call the functions for winning two tokens, for winning three tokens, and for losing tokens. So, if you managed to get the numbers 5 5 5, you would get five tokens. I don't know if this is by design or not (I'd have to assume not).

    As a further exercise, I would modify your program so that you call a function based upon how many numbers match, not call each function and have each function determine what we can do.

  4. #4
    Registered User
    Join Date
    Sep 2009
    Posts
    8
    Thanks for the advice. i will try to paste the new code tomorrow after my homework.

    For you saying that it was the != operator causing the problem, actually it's not. The && operator gives the same result.
    Last edited by nobo707; 09-21-2009 at 07:53 PM.

  5. #5
    Registered User
    Join Date
    Sep 2009
    Posts
    8
    Here is my new, with 3 functions, clean, using a while loop instead of for which i think was the problem.

    Code:
    #include <iostream>
    #include <cstdlib>
    #include <ctime>
    
    using namespace std;
    
    typedef unsigned short int USHORT;
    
    const USHORT tokensThree = 3;
    const USHORT tokensTwo = 2;
    USHORT tokens = 24;
    const char playYes = 'y';
    char inputYes;
    const USHORT highRandom = 6;
    const char playNo = 'n';
    USHORT randomNumber;
    USHORT randomNumberTwo;
    USHORT randomNumberThree;
    
    void welcome()
    {
        cout << "Welcome to the most amazing text-based Slot Machine!" << endl;
        cout << "Our fine Slot Machines may or maynot grant you wishes!" << endl;
        cout << "Anyways, You have " << tokens << "tokens." << endl;
        cout << "Soooo, have fun with these few tokens as you will have none left very, very, very SOON!" << endl;
    }
    
    int outcome(int firstNumber, int secondNumber, int thirdNumber)
    {
        if(firstNumber == secondNumber == thirdNumber)
        {
            tokens += tokensThree;
            cout << "Congrats! You won 3 Tokens!" << endl;
            cout << "You have " << tokens << "tokens." << endl;
        }
        if(firstNumber == secondNumber || firstNumber == thirdNumber || secondNumber == thirdNumber)
        {
            tokens += tokensTwo;
            cout << endl << endl << "Congrats! You won 2 Tokens!" << endl;
            cout << "You have " << tokens << "tokens." << endl;
        }
        else
        {
            tokens -= tokensThree;
            cout << endl << endl << "Sorry! You lost 3 Tokens." << endl;
            cout << "You have " << tokens << "tokens." << endl;
        }
        return (firstNumber, secondNumber, thirdNumber);
    }
    
    void lever()
    {
        time_t clockTime;
        time(&clockTime);
        srand((unsigned int) clockTime);
        randomNumber = rand() % highRandom + 1;
        randomNumberTwo = rand() % highRandom + 1;
        randomNumberThree = rand() % highRandom + 1;
        cout << endl << "Do you want to pull the Lever?" << endl;
        cout << "Press 'y' and Press Return to play or Press 'n' and Return to Quit." << endl;
        cin >> inputYes;
        if (inputYes == playYes)
        {
            cout << endl << endl << "Your random numbers are:\t" << randomNumber << "\t" << randomNumberTwo << "\t" << randomNumberThree;
            outcome(randomNumber, randomNumberTwo, randomNumberThree);
        }
        else
        {
            exit(0);
        }
    }
    
    int main()
    {
        welcome();
        while(tokens != 0)
        {
            lever();
        }
    }

  6. #6
    Registered User
    Join Date
    Sep 2009
    Posts
    63
    You've made some little improvements in the new version of your program, but some bugs still remain that have been previously pointed out.

    Check this line:

    Code:
    firstNumber == secondNumber == thirdNumber
    I believe that if you have the numbers X X 1, this statement will be true. Thankfully you also don't generate 0 as a number, because that would cause an even more interesting case: X Y 0 results in true.

    After you've fixed that line, you still have an issue with your functions. If you have 3 of the same number, you will be rewarded with 3 tokens. Your program then points out that you have 2 matching numbers and gives you a further 2 tokens. Check your if statements. As far as each individual statement goes, they are correct (save for the above).

  7. #7
    Registered User
    Join Date
    Sep 2009
    Posts
    8
    I am not trying to be rude here but if you tell em that there is still 2 bugs in my program, can you at least give me some sample program or a suggestion on how to fix it. Thanks for the tips but it didn't learn anything but getting knwoledge of 2 bugs in my program and i am here not knowing how to fix it or any suggestions to resolve those bugs.

  8. #8
    Registered User
    Join Date
    Sep 2009
    Posts
    63
    I stated clearly where one of the problems lies. In fact, I quoted the exact problem itself. But, in case you missed it, let me quote it for you again.

    Code:
    firstNumber == secondNumber == thirdNumber
    It doesn't work as you would think it would. Let's pick random values. As I mentioned above, let's pick 2, 2, and 1 and plug them in.

    Code:
    2 == 2 == 1
    What does this expression evaluate as? We have to know the order operators work in. These are all the same operators, so they have the same precedence. This particular operator works in a left to right fashion. That is, it will work on the left most statement before it will work on the right most statement. So, let's return to your statement and modify it to reflect the order of operations. This is how your program actually evaluates your code, and is the source of the bug.

    Code:
    (2 == 2) == 1
    In this case, it will evaluate 2 == 2, which resolves to true. Remember that boolean types can be represented in a few ways, such as true/false or 1/0. In this case, you are now testing this:

    Code:
    true == 1
    Finally, it results in this answer: true. Clearly this is not what you wanted to get. You wanted to get a true result if both the first number is equal to the second and the second is equal to the third. If it were possible to get, say, 2, 1, 0, that would also evaluate to true in the end. I'll leave that to you to find out why.


    Now, for your second bug. I will quote my previous post. This time, I will make sure you read the line you missed the first time.

    After you've fixed that line, you still have an issue with your functions. If you have 3 of the same number, you will be rewarded with 3 tokens. Your program then points out that you have 2 matching numbers and gives you a further 2 tokens. Check your if statements. As far as each individual statement goes, they are correct (save for the above).
    For another hint, I will point out how if statements work.

    Code:
    if (some statement goes here)
    {
         //do something
    }
    /**This does not magically end your function. That doesn't happen until your function, if void, 
    reaches the last statement, or, for any function (even void), you return.**/
    
    if (some other statement)
    {
         //If it is possible for this statement to also be true, this code will still execute
    }
    Last edited by Zach_the_Lizard; 09-23-2009 at 03:51 PM. Reason: Caused page to expand horizontally on smaller monitors

  9. #9
    Registered User
    Join Date
    Sep 2009
    Posts
    8
    thanks for your, it made me relax, focus on the code and to be all jumpy. Try to run the code through your head. I am still stumbled and i tried many ways to resolve it, i will come back to it and go on with the lessons in the book.

  10. #10
    Ex scientia vera
    Join Date
    Sep 2007
    Posts
    477
    Quote Originally Posted by nobo707 View Post
    thanks for your, it made me relax, focus on the code and to be all jumpy. Try to run the code through your head. I am still stumbled and i tried many ways to resolve it, i will come back to it and go on with the lessons in the book.
    I like how you (seemingly) willfully ignore all the help you have received. Your issues have clearly been pointed out, and you can fix them by simply READING what they say.
    "What's up, Doc?"
    "'Up' is a relative concept. It has no intrinsic value."

  11. #11
    Registered User
    Join Date
    Sep 2009
    Posts
    8
    I can't believe i was so blind from you post.
    /**This does not magically end your function. That doesn't happen until your function, if void,
    reaches the last statement, or, for any function (even void), you return.**/
    My Bad.

    Here is the new code.

    I know that there is still one more bug that if you have 1 token and lose 3 tokens that it wraps the unsigned int to 65,535 so that will be fixed.

    Code:
    #include <iostream>
    #include <cstdlib>
    #include <ctime>
    
    using namespace std;
    
    typedef unsigned short int USHORT;
    
    const USHORT tokensThree = 3;
    const USHORT tokensTwo = 2;
    unsigned short int tokens = 24;
    const char playYes = 'y';
    char inputYes;
    const USHORT highRandom = 6;
    const char playNo = 'n';
    USHORT randomNumber;
    USHORT randomNumberTwo ;
    USHORT randomNumberThree ;
    
    void welcome()
    {
        cout << "Welcome to the most amazing text-based Slot Machine!" << endl;
        cout << "Our fine Slot Machines may or maynot grant you wishes!" << endl;
        cout << "Anyways, You have " << tokens << "tokens." << endl;
        cout << "Soooo, have fun with these few tokens as you will have none left very, very, very SOON!" << endl;
    }
    
    int outcome(int firstNumber, int secondNumber, int thirdNumber)
    {
        if(firstNumber == secondNumber && secondNumber == thirdNumber && firstNumber == thirdNumber)
        {
            tokens += tokensThree;
            cout << endl << "Congrats! You won 3 Tokens!" << endl;
            cout << "You have " << tokens << " tokens." << endl;
            return (firstNumber, secondNumber, thirdNumber);
        }
        if(firstNumber == secondNumber || secondNumber == thirdNumber || firstNumber == thirdNumber)
        {
            tokens += tokensTwo;
            cout << endl << endl << "Congrats! You won 2 Tokens!" << endl;
            cout << "You have " << tokens << " tokens." << endl;
        }
        else
        {
            tokens -= tokensThree;
            cout << endl << endl << "Sorry! You lost 3 Tokens." << endl;
            cout << "You have " << tokens << " tokens." << endl;
        }
        return (firstNumber, secondNumber, thirdNumber);
    }
    
    void lever()
    {
        time_t clockTime;
        time(&clockTime);
        srand((unsigned int) clockTime);
        randomNumber = rand() % highRandom + 1;
        randomNumberTwo = rand() % highRandom + 1;
        randomNumberThree = rand() % highRandom + 1;
        cout << endl << "Do you want to pull the Lever?" << endl;
        cout << "Press 'y' and Press Return to play or Press 'n' and Return to Quit." << endl;
        cin >> inputYes;
        if (inputYes == playYes)
        {
            cout << endl << endl << "Your random numbers are:\t" << randomNumber << "\t" << randomNumberTwo << "\t" << randomNumberThree;
            outcome(randomNumber, randomNumberTwo, randomNumberThree);
        }
        else
        {
            exit(0);
        }
    }
    
    int main()
    {
        welcome();
        while(tokens != 0 != tokens > 65000)
        {
            lever();
        }
       if(tokens == 0 || tokens == 65535 || tokens == 65534 || tokens == 65533)
        {
            cout << endl << endl << "Game Over!";
            cout << endl << "You have no more tokens left!";
            exit(0);
        }
    }
    Last edited by nobo707; 09-23-2009 at 05:17 PM.

  12. #12
    Registered User
    Join Date
    Sep 2009
    Posts
    63
    Well, now your program should work more or less as expected, according to my quick scan. That is, except for the overflow error that you are aware of. With a little bit of thought, you'll be able to solve that issue, too. Wait: after a reread of your program, I just noticed something: a mistake that I already pointed out above.

    You saw how incorrect usage of a condition can end up in totally incorrect statements being regarded as true or false, causing all sorts of problems. Well, you did it again. Let's have a look.

    Code:
    tokens != 0 != tokens > 65000
    After examining some test values that statement might actually work, but it probably doesn't work how you think it does. It is executed like this:

    (tokens != 0) != (tokens > 65,000), tokens > 65,000 is executed first, then tokens != 0, and then the comparison of these two answers.



    Now that we've got your program working, we can focus on all of the bad practices you engage in. Yay us!

    It is generally bad practice to declare global variables, depending upon the circumstances. You always want to strive for your variables to be in the smallest scope possible. For example, you wouldn't do this:

    Code:
    int x = 0; //Only used in someFunction
    double y = 0.0; //Also only used in someFunction
    
    void someFunction()
    {
    //Code here
    }
    A better version of this would be like this:
    Code:
    void someFunction()
    {
    int x = 0; //only used in someFunction, and can only  be used in someFunction
    double y = 0.0 //only available in this function
    
    }
    That's one issue you have. I would also declare your outcome function as void, since you apparently don't actually need it to return anything. It can still accept the values you pass it, and you can still use return, but you just can't return values. You may have noticed compiler warnings about outcome's value not actually being used.

    Perhaps someone else will help you on whatever else this program needs.

  13. #13
    Registered User
    Join Date
    Sep 2009
    Posts
    8
    Thanks for sticking with me. Actually i am using G++ 4.3.3 on linux and it didn't issue any warnings. I will put in the variables, the global variables, that aren't used by more than one function in that function and to put outcome as void.

    Is the code:
    Code:
    tokens != 0 != tokens > 65000
    fine to keep and thanks for explaining how it is executed so i will keep that in mind.

    and is the overflow you are talkig about:
    Code:
    firstNumber == secondNumber && secondNumber == thirdNumber && firstNumber == thirdNumber

    Here is the new code with the overflow still:
    Code:
    #include <iostream>
    #include <cstdlib>
    #include <ctime>
    
    using namespace std;
    
    typedef unsigned short int USHORT;
    
    unsigned short int tokens = 24;
    
    void welcome()
    {
        cout << "Welcome to the most amazing text-based Slot Machine!" << endl;
        cout << "Our fine Slot Machines may or maynot grant you wishes!" << endl;
        cout << "Anyways, You have " << tokens << "tokens." << endl;
        cout << "Soooo, have fun with these few tokens as you will have none left very, very, very SOON!" << endl;
    }
    
    void outcome(int firstNumber, int secondNumber, int thirdNumber)
    {
    
        const USHORT tokensThree = 3;
        const USHORT tokensTwo = 2;
        if(firstNumber == secondNumber && secondNumber == thirdNumber && firstNumber == thirdNumber)
        {
            tokens += tokensThree;
            cout << endl << "Congrats! You won 3 Tokens!" << endl;
            cout << "You have " << tokens << " tokens." << endl;
            return;
        }
        if(firstNumber == secondNumber || secondNumber == thirdNumber || firstNumber == thirdNumber)
        {
            tokens += tokensTwo;
            cout << endl << endl << "Congrats! You won 2 Tokens!" << endl;
            cout << "You have " << tokens << " tokens." << endl;
        }
        else
        {
            tokens -= tokensThree;
            cout << endl << endl << "Sorry! You lost 3 Tokens." << endl;
            cout << "You have " << tokens << " tokens." << endl;
        }
        return;
    }
    
    void lever()
    {
        const USHORT highRandom = 6;
        const char playYes = 'y';
        char inputYes;
        USHORT randomNumber;
        USHORT randomNumberTwo ;
        USHORT randomNumberThree ;
        time_t clockTime;
        time(&clockTime);
        srand((unsigned int) clockTime);
        randomNumber = rand() % highRandom + 1;
        randomNumberTwo = rand() % highRandom + 1;
        randomNumberThree = rand() % highRandom + 1;
        cout << endl << "Do you want to pull the Lever?" << endl;
        cout << "Press 'y' and Press Return to play or Press 'any other letter' and Return to Quit." << endl;
        cin >> inputYes;
        if (inputYes == playYes)
        {
            cout << endl << endl << "Your random numbers are:\t" << randomNumber << "\t" << randomNumberTwo << "\t" << randomNumberThree;
            outcome(randomNumber, randomNumberTwo, randomNumberThree);
        }
        else
        {
            exit(0);
        }
    }
    
    int main()
    {
        welcome();
        while(tokens != 0 != tokens > 65000)
        {
            lever();
        }
       if(tokens == 0 || tokens == 65535 || tokens == 65534 || tokens == 65533)
        {
            cout << endl << endl << "Game Over!";
            cout << endl << "You have no more tokens left!";
            exit(0);
        }
    }
    I even got rid of an unnecessary char.
    Last edited by nobo707; 09-23-2009 at 07:55 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Disappearing Bug
    By el-sid in forum C++ Programming
    Replies: 4
    Last Post: 08-16-2009, 12:12 PM
  2. Bug favour needed re: C++ Program
    By Nicole in forum C++ Programming
    Replies: 2
    Last Post: 12-05-2001, 07:13 AM
  3. Repetitive Bug with C++ Program - Needs Help
    By kuphryn in forum C++ Programming
    Replies: 5
    Last Post: 11-15-2001, 08:07 PM
  4. Bug in Program - please help!
    By muffin in forum C Programming
    Replies: 4
    Last Post: 08-31-2001, 09:33 AM
  5. My program, anyhelp
    By @licomb in forum C Programming
    Replies: 14
    Last Post: 08-14-2001, 10:04 PM