Number Guessing Program

So I have this program in which the computer tries to guess your number. After each guess you tell it whether the guess was too low, too high or correct.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>

using namespace std;

int main()
{
    srand(static_cast<unsigned int>(time(0)));  //seed random number generator

	int compGuess = rand() % 100 + 1;  // random number between 1 and 100
	int tries = 0;
	int answer;
	bool guess;
	int lo=1;
	int hi=100;
	int nothing;

	cout<<"\tWelcome to Guess your Number!\n";
	cout<<"\tThink of a number between 1 and 100.\n\n";

	do
	{
	    cout<<"My guess is "<<compGuess <<"\n\n";
	    cout<<"Is this: \n";
	    cout<<"1: Too low\n";
	    cout<<"2: Too high\n";
	    cout<<"3: correct\n";
	    cin>>answer;
	    ++tries;
	    guess = false;


	    if (answer == 2)    //if guess was too high
	    {
	        hi = compGuess;
	        compGuess = rand() % (hi-lo+1)+lo;
	    }

	    else if (answer == 1)   //if guess was too low
	    {
	        lo = compGuess;
	        compGuess = rand() % (hi-lo+1)+lo;
	    }

	    else if (answer == 3)
	    {
	        cout<<"I win! It only took me " << tries << " guesses!\n";
	        guess = true;
	    }
	}while(!guess);
cout<<"Type anything to exit!"<<endl;
cin>>nothing;
}


The problem is that since the program uses the rand() function, it occasionally guesses the same number twice. I was wondering if anyone had ideas on how to eliminate the program outputting guesses it's already used.
Change line 37 to:
hi = compGuess-1;
Change line 43 to:
lo = compGuess+1;
That does remove the issue but ends up crashing the program if the user enters "too low" after the bounds have been limited to a single number.

For example if the number in question were 92 and you run the program until hi=92 and low=92 and then submit either "too low" or "too high" it ends up diving by 0 and crashes.
Is there a way to add some type of loop that re-executes the "if statement" if the output was the same?

such as

1
2
3
4
5
6
7
8
9
	    if (answer == 2)    //if guess was too high
	    {
	        hi = compGuess;
	        compGuess = rand() % (hi-lo+1)+lo;
	        if (compGuess == hi)
	        {
	            command that re-executes if statement
	        }
    


so basically is there a command that will re-do the if loop whenever the out is the same as the previous output?
I believe I figured it out

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
// Guess My Number
// The classic number guessing game

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>

using namespace std;

int main()
{
    srand(static_cast<unsigned int>(time(0)));  //seed random number generator

	int compGuess = rand() % 100 + 1;  // random number between 1 and 100
	int tries = 0;
	int answer;
	bool guess;
	int lo=1;
	int hi=100;
	int nothing;

	cout<<"\tWelcome to Guess your Number!\n";
	cout<<"\tThink of a number between 1 and 100.\n\n";

	do
	{
	    cout<<"My guess is "<<compGuess <<"\n\n";
	    cout<<"Is this: \n";
	    cout<<"1: Too low\n";
	    cout<<"2: Too high\n";
	    cout<<"3: correct\n";
	    cin>>answer;
	    ++tries;
	    guess = false;


	    if (answer == 2)    //if guess was too high
	    {
	        hi = compGuess;
	        compGuess = rand() % (hi-lo+1)+lo;
	        while (compGuess == hi)                          //causes function to create new numbers until it does not equal the previous guess
	        {
	            compGuess = rand() % (hi-lo+1)+lo;       
	            if(hi == lo)
	            break;               //prevents infinite loop
	        }
	    }

	    else if (answer == 1)   //if guess was too low
	    {
	        lo = compGuess;
	        compGuess = rand() % (hi-lo+1)+lo;
	        while(compGuess == lo)                           //causes function to create new numbers until it does not equal the previous guess
	        {
	           compGuess = rand() % (hi-lo+1)+lo;      
	           if(hi == lo)
	           break;                           //prevents infinite loop
	        }
	    }

	    else if (answer == 3)
	    {
	        cout<<"I win! It only took me " << tries << " guesses!\n";
	        guess = true;
	    }
	}while(!guess);
cout<<"Type anything to exit!"<<endl;
cin>>nothing;
}



Should this cause it to work properly or will I run into some other problems?
I tried your version, it seemed the computer repeated the same guess several times.

I didn't study all the code, as I wanted to try this binary chop version. Instead of a random guess, the computer chooses midway between high and low.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
// Guess My Number
// The classic number guessing game

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>

using namespace std;

int nextGuess(int low, int high) 
{
    return ( low + high  + 1) / 2;
}

int main()
{
    srand(static_cast<unsigned int>(time(0)));  //seed random number generator

    int answer;
    bool guess = false;
    int tries = 0;
    int lo = 1;
    int hi = 100;

    // int compGuess = nextGuess(lo, hi);
    int compGuess = rand() % 100 + 1;  // random number between 1 and 100

    cout<<"\tWelcome to Guess your Number!\n";
    cout<<"\tThink of a number between 1 and 100.\n\n";

    do
    {
        cout<<"My guess is "<<compGuess <<"\n\n";
        cout<<"Is this: \n";
        cout<<"1: Too low\n";
        cout<<"2: Too high\n";
        cout<<"3: correct\n";
        cin >> answer;

        ++tries;

        switch (answer) {
            case 2: // too high
                hi = compGuess - 1;
                compGuess = nextGuess(lo, hi);
                break;

            case 1: // too low
                lo = compGuess + 1;
                compGuess = nextGuess(lo, hi);
                break;

            case 3: // correct
                cout<<"I win! It only took me " << tries << " guesses!\n";
                guess = true;
                break;

            default:
                cout << "Please enter 1, 2 or 3" << endl;
        }

    } while(!guess);

    cout<<"Type anything to exit!"<<endl;

    char nothing;
    cin >> nothing;
    return 0;
}


If line 26 is used instead of line 27, the computer's opening guess is always 51, which may be an optimum strategy, but not much fun.

It also isn't bulletproof. There is no validation of whether the user's responses are consistent, and it may misbehave with input which doesn't agree with previous inputs.
Last edited on
I decided to fiddle around with this as well...tried to keep the integrity of your code as much as possible but will try to highlight changes.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
// Guess My Number
// The classic number guessing game

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>

using namespace std;

int compGuess;

int nextGuess(int low, int high)
{
    return ( low + high  + 1) / 2;
}

int main()
{
    srand(time(0));  //seed random number generator *changed to a simpler use*

    int answer;
    bool guess = false;
    int tries = 0;
    int lo = 1;
    int hi = 100;



    cout<<"\tWelcome to Guess your Number!\n";
    cout<<"\tThink of a number between 1 and 100.\n\n";

    do                              //added two do loops, one for generator (simple) and other text.
    {
        // int compGuess = nextGuess(lo, hi);
        compGuess = rand(); // random number between 1 and 100
    }
    while ((compGuess < 1) || (compGuess > 100) & guess == false);
    do
    {
        cout<<"My guess is "<<compGuess <<"\n\n";
        cout<<"Is this: \n";
        cout<<"1: Too low\n";
        cout<<"2: Too high\n";
        cout<<"3: correct\n";
        cin >> answer;


        ++tries;

        switch (answer) {
            case 2: // too high
                hi = compGuess - 1;
                compGuess = nextGuess(lo, hi);
                break;

            case 1: // too low
                lo = compGuess + 1;
                compGuess = nextGuess(lo, hi);
                break;

            case 3: // correct
                cout<<"I win! It only took me " << tries << " guesses!\n";
                guess = true;
                break;
            default:
                cout << "Please enter 1, 2 or 3" << endl;
        }
    }while(!guess);


    cout<<"Type anything to exit!"<<endl;

    char nothing;
    cin >> nothing;
    return 0;
}


I think I only really changed your srand and rand() commands, kinda simplified it a little since you are only dealing with 1-100 (at least for me lol). Computer will start with a random number, does math right and goes hi/lo based on answer, and ends on input of 3.

Over time I've begun to dislike switch statements...I am a fan of the flexibility of the if/else. If you were going to expand this program you might want to add in a Lie Detector, which would involve having to change your switch to an if/else and adding a 4th "case" and adding a tracker for your guesses. Like right after the computer guesses you could just put a=compGuess; and make sure the comp guess is stored in a every time just replacing whatever is in A. Then in your if/else you could now check for if(compGuess == a) and type w/e...was going to reformat the code to fit it...but it's not mine it is yours so figured I'd just plant the idea.
@ Edwards
Don't worry about preserving the integrity of my code. The OP is the one looking for answers. :)
@Chervil
Did you try the second version I posted? It shouldn't be repeating the guess.

@Edwards
In this program, the switch statement does make it somewhat simpler but I do agree with you on the if/else statements

I don't see how the lie detector would work, because with each guess you limit hi and lo, eliminating the possibility of having the same guess. If you could elaborate a little more that would be great.

I do appreciate the input on the program :D

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
// Guess My Number
// The classic number guessing game

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>

using namespace std;

int main()
{
    srand(static_cast<unsigned int>(time(0)));  //seed random number generator

	int compGuess = rand() % 100 + 1;  // random number between 1 and 100
	int tries = 0;
	int answer;
	bool guess;
	int lo=1;
	int hi=100;
	char nothing;

	cout<<"\tWelcome to Guess your Number!\n";
	cout<<"\tThink of a number between 1 and 100.\n\n";

	do
	{
	    cout<<"My guess is "<<compGuess <<"\n\n";
	    cout<<"Is this: \n";
	    cout<<"1: Too low\n";
	    cout<<"2: Too high\n";
	    cout<<"3: correct\n";
	    cin>>answer;
	    ++tries;
	    guess = false;

        switch(answer)
        {
            case 1: //too low
                lo=compGuess+1;
                if((hi-lo+1)==0)       //fail safe to prevent dividing by zero
                    lo=compGuess;
                compGuess=rand()%(hi-lo+1)+lo;
                while(compGuess==lo)
                {
                    compGuess=rand()%(hi-lo+1)+lo;
                    if(hi==lo)
                        break;
                }
                break;
            case 2: //too hi
                hi=compGuess-1;
                if((hi-lo+1)==0)      //fail safe to prevent dividing by zero
                    hi=compGuess;
                compGuess=rand()%(hi-lo+1)+lo;
                while(compGuess==hi)
                {
                    compGuess=rand()%(hi-lo+1)+lo;
                    if (hi==lo)
                        break;
                }
                break;
            case 3: //correct
                cout<<"I win! It only took me "<<tries<<" guesses!\n";
                guess = true;
                break;
        }
	}while(!guess);

cout<<"Type anything to exit!"<<endl;
cin>>nothing;
}


So here is the revised copy:
removed the duplicate answer (where if lo=51 it was possible to get 51 again)
used switch case to make it look nice




Last edited on
Ok! Finally...fiddle fiddle fiddle and I got shoddy code lol...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
// Guess My Number
// The classic number guessing game

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>

using namespace std;

int compGuess;

int nextGuess(int low, int high)
{
    return ( low + high  + 1) / 2;
}

int main()
{
    srand(time(0));  //seed random number generator

    int answer;
    bool guess = false;
    int tries = 0;
    int lo = 1;
    int hi = 100;

    cout<<"\tWelcome to Guess your Number!\n";
    cout<<"\tThink of a number between 1 and 100.\n\n";

    do
    {
        // int compGuess = nextGuess(lo, hi);
        compGuess = rand(); // random number between 1 and 100
    }
    while ((compGuess < 1) || (compGuess > 100) & (guess == false));
    do
    {
        cout<<"My guess is "<<compGuess <<"\n\n";
        cout<<"Is this: \n";
        cout<<"1: Too low\n";
        cout<<"2: Too high\n";
        cout<<"3: correct\n";
        cin >> answer;
        ++tries;

        if (lo == hi)
        {
                cout << "LIAR!!! I don't want to play anymore!" << endl;
                break;
        }
        else if (answer == 2)
        {
                hi = compGuess - 1;
                compGuess = nextGuess(lo, hi);
        }
        else if (answer == 3)
        {
                cout<<"I win! It only took me " << tries << " guesses!\n";
                guess = true;
        }
        else if (answer == 1)
        {
                lo = compGuess;
                compGuess = nextGuess(lo, hi);
        }
        else
        {
                cout << "Please enter 1, 2 or 3" << endl << endl;
        }

    }while(!guess);


    cout<<"Type anything to exit!"<<endl;

    char nothing;
    cin >> nothing;
    return 0;
}


Ok, so there it is...was harder for me to explain in words rather than just showing. Now this will generate a number 1-100, user specifies if to high or low, regenerates accordingly, but now on top of all this...if statement #1 - if hi and lo are equal we quit cause now you just being silly.

Also, just my opinion here...this is why I am not a fan of case statements...you still had to use if/whiles in the case making it appear just as cluttered as if/else. I do see the point of using them but I really only like using them for constants that need ifs/cases and not really dealing with computer/user variables that could change in the same instance if that makes any sense...idk maybe I'm just more comfortable with IFs.

12 code lines for case/while and only 4 for if/else...I feel sometimes either way you view it you will almost always have the same number of cases vs ifs...and again perhaps I just suck with cases lol.
I found a minor bug with yours.
If you were to run the program and hit "too high" until it reaches 100 then hit "too high" it will display 100 again. If you follow this up with "correct" it will call you a liar and then quit the program.

A simple fix to this is change line 47 to
if (lo == hi && answer != 3)
@Fovv
nice find!...now the program is essentially complete lol...Good Game. :)
If I can make a 1 cent worth, trivial & pedantic (hopefully not irrelevant) contribution:D

If using a do loop, put the while part on the same line as the closing brace !! Otherwise it looks like a while loop with a null statement.

I try to avoid using do loops, unless I really do need to use one. They can almost always be rewritten as a while or for loop.
Sorry, just a simple q:


a=6;
b=a++;
b+=4;
why is that 10 and not 11?
Many thanks!
@TheIdeasMan
I have to say you're kinda right lol...tiny bit more esthetically pleasing :)
Please,


if I want to write lines:


aaaaa
aaaaa
aaaaa

using a loop

how do I make a break to a new line?
Many thanks!
If I have:

#include <iostream>
using namespace std;
int main() {

string a;
a="a";
int x;
for ( x=1; x<=100; x++ )
{
cout<<a;
}
x=x++;
if (x%10==0)
{
cout<<endl;
}

return 0;
}

it does not go to the next line after each 10 signs?
@enemy

Please start your own separate thread for your question, as it is not related at all to the Number Guessing Program.
Topic archived. No new replies allowed.