A failed attempt to create "PC guesses a number" game..

Can you please tell me what is wrong in this code? I basically want PC to guess my number with me only telling LOWER or HIGHER. But it's not working as it should, sometimes it generates numbers higher than I stated before.

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
#include <iostream>
#include <time.h>
#include <cstdlib>
#include <windows.h>
#include <conio.h>

using namespace std;
int main()
{
    int x[10000],t=0;
    int a=1;
    string y[10000];
cout << "Think of a two digits or one digit number and I will guess it " << endl;
srand(time(NULL));
x[a]=rand()%100+1; //
do {
    hello:
    cout << "Is your number " << x[a] << " ?" ; //
    cin >> y[a];
    t++;
    lie:
    if (a==8) {cout << "Don't lie. Your number is " << x[a] << " for sure."<< endl; break;}
    if (a>1) goto main;
    if (y[a]=="l")
       {
        cout << "I see, the number is lower" << endl;
        x[a+1]=rand()%(x[a]-1)+1;
        a++; goto hello;
       }
    else if (y[a]=="h")
       {
        cout << "I see, the number is higher" << endl;
        x[a+1]=rand()%100+(x[a]+1);
        a++; goto hello;
       }

    main:

     if ((y[a]=="l") and (y[a-1]=="h"))
       {
        cout << "I see, the number is lower" << endl;
        x[a+1]=rand()%(x[a]-1)+(x[a-1]+1);
        a++;
       }
     else if ((y[a]=="l") and (y[a-1]=="l"))
       {
        cout << "I see, the number is lower" << endl;
        x[0]=0; x[a<0]=0;
        if (x[a-2]+1==x[a]-1) {cout << "Is your number " << x[a]-1 << " ?"; cin >> y[a]; if (y[a]=="y") goto win; else goto lie;}
        x[a+1]=rand()%(x[a]-1)+(x[a-2]+1);
        a++;
       }
     else if ((y[a]=="h") and (y[a-1]=="l"))
       {
        cout << "I see, the number is higher" << endl;
        x[a+1]=rand()%(x[a-1]-1)+(x[a]+1);
        a++;
       }
     else if ((y[a]=="h") and (y[a-1]=="h"))
       {
        cout << "I see, the number is higher" << endl;
        x[0]=100; x[a<0]=100;
        if (x[a-2]-1==x[a]+1) {cout << "Is your number " << x[a]+1 << " ?"; cin >> y[a]; if (y[a]=="y") goto win; else goto lie;}
        x[a+1]=rand()%(x[a-2]-1)+(x[a]+1);
        a++;
       }


    }
    while (y[a]!="y");
    win:
if (y[a]=="y") cout << "I won ! It took me " << t << " tries.";
system("PAUSE");
    return 0;
}
Last edited on
Looks like this is way over complicated. Look into a binary search, it will make life much simpler.
I think I got it, however, I encountered very silly problem. When I'm declaring I want to assign values from 1 to 99 to x, so I could to that:

x[]={1,2,3 ... 97,98,99}

Is there a shorter way to do it besides typing all the numbers? I know this is extremely begginerish question but I'm extremely begginerish myself.
You can use a for loop, like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
using namespace std;

int main()
{
    const int ARRAY_LENGTH = 99; 
    int x[ARRAY_LENGTH]={0}; 
   
  
        
   for(int Index = 1; Index <= ARRAY_LENGTH; ++Index) // This for loop assigns 1 through 99 to each element of the array. 
       x[Index] = Index; 
       
    for (int Index = 1; Index <= ARRAY_LENGTH; ++Index) // This for loop displays each of the elements of the array (i.e., 1-99). 
        cout <<  x[Index] << endl; 
    
 
    
    return 0; 
}
Last edited on
I give up. I don't even know how to use binary search. I really need someone to at least give me directions how to use that thing in the first place.
You do not need any arrays here at all. Think about how you would approach this if you were trying to 'guess' the number a friend had picked. It might help to actually 'play' the game with someone.
That reminds me a lot of this: http://www.cplusplus.com/forum/beginner/96043/
@Vidminas , it would be easy but I have to make sure that computer won't say higher than x when I said it's lower than x. To make computer remember I use arrays.
... And what if you got rid of the arrays and goto?
Using labels and jumping to them is a bad practice as that can cause many problems, while from my experience, arrays sometimes misbehave.
Just try rewriting your code and see what you get ;)
1
2
3
4
5
6
7
8
9
10
11
12
13
let min be 1
let max be 100
let number be a random number beteen min and max, inclusive

let guess be some value between min and max

while guess is not equal to number
{
    if guess is too high, then set max to guess.
    if guess is too low, then set min to guess.

    set guess to some value between min and max
}
@cire, that's basically what I tried to do in previous program.

I tried to do as simple as I can now with cire help, but it still doesn't work as it should - it even gives numbers above 100, and totally disregards L/H logic.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <windows.h>
#include <conio.h>
using namespace std;
int main()
{
srand(time(NULL));
int a=99,b=1,x,t=0;
string guess;
while ((guess!="y") or (t<=7))
{
x=rand()%a+b;
cout << "Is this your number " << x << " ? h/l" << endl;
cin >> guess;
if (guess=="h") b=x+1; // that means it should be higher
if (guess=="l") a=x-1; // it should be lower
t++;
}
if(t>=7) cout << "Don't lie to me, it's " << x << endl;
    return 0;
}
Last edited on
Try this: x = rand()%(a-b+1) + b;
Thank you, it worked like a charm :) Sometimes it takes for PC more than 7 tries, I have no idea why, but besides this it's working fine.
Sometimes it takes for PC more than 7 tries

With a random choice, it could take many attempts.

Two comments. First, you can determine that the value has been found when the max and min limits of the range (a and b in your code) are equal.

Secondly, if you want the most efficient (but rather unexciting) guess from the computer, instead of a random number, just use x = (a+b)/2;
Last edited on
May I ask a question now?
I felt like writing a very similar game and now I'm thinking if there's a way to make the computer "smart" and prevent it from guessing the same number twice (not just the last guess, but from the whole history of its guesses)...
Last edited on
In the above code, that is handled like this:
15
16
if (guess=="h") b=x+1; // that means it should be higher
if (guess=="l") a=x-1; // it should be lower 


The upper or lower limit is adjusted to be one more or one less than the latest guess. Then there's no way the new guess can be the same as the old, as it would be out of range.
I wrote the code without arrays or labels and gotos while using this article http://www.cplusplus.com/forum/articles/6046/ to read in values (it's quite a bit larger, because of that).
This isn't the main.cpp which is why it is in a function, also srand(time(NULL)); is in the main.

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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#include "clearscreen.hpp"
#include <iostream>
#include <cstdlib>
#include <string>
#include <sstream>

void computerguesses()
{
    std::string input;
    unsigned short cpuguess, guesses = 0, gumballs = 0;
    unsigned short mingumballs = 1, maxgumballs = 1000;
    ClearScreen();
    gumballs = rand() % 1000 + 1;

    while(true)
    {
        std::cout << "There is a gumball jar, which can hold up to 1000 gumballs." << "\n";
        std::cout << "You decide how many gumballs to put in the jar!" << "\n";
        std::cout << ": ";
        getline(std::cin, input);
        std::stringstream myStream(input);
        if (myStream >> gumballs)
        {
            if (gumballs >= 1 and gumballs <= 1000)
                break;

            else
            {
                std::cout << "The jar can only fit 1000 gumballs and you must add at least one!";
                std::cin.clear();
                std::cin.ignore(10000, '\n');
                ClearScreen();
            }
        }
        ClearScreen();
    }

    do
    {
        cpuguess = rand() % (maxgumballs - mingumballs + 1) + mingumballs;

        std::cout << "\n" << "Here's my guess: " << cpuguess << "\n";

        if (cpuguess > gumballs)
        {
            while (true)
            {
                std::cout << "Is this right? (yes or no) : ";
                getline(std::cin, input);
                std::cout << "\n";

                if (input == "yes")
                {
                    std::cout << "Let's see... No! You can't fool me!" << "\n";
                    std::cout << "I don't know how many gumballs are there, but it's obvious that there are less!" << "\n";
                    maxgumballs = cpuguess;
                    std::cin.clear();
                    std::cin.ignore(10000, '\n');
                    break;
                }

                else if (input == "no")
                {
                    std::cout << "Hmmm, I see there are less..." << "\n";
                    maxgumballs = cpuguess;
                    std::cin.clear();
                    std::cin.ignore(10000, '\n');
                    break;
                }
            }
        }

        else if (cpuguess < gumballs)
        {
            while (true)
            {
                std::cout << "Is this right? (yes or no) : ";
                getline(std::cin, input);
                std::cout << "\n";

                if (input == "yes")
                {
                    std::cout << "Let's see... No! You can't fool me!" << "\n";
                    std::cout << "I don't know how many gumballs are there, but it's obvious that there are more!" << "\n";
                    mingumballs = cpuguess;
                    std::cin.clear();
                    std::cin.ignore(10000, '\n');
                    break;
                }

                else if (input == "no")
                {
                    std::cout << "Hmmm, I see there are more..." << "\n";
                    mingumballs = cpuguess;
                    std::cin.clear();
                    std::cin.ignore(10000, '\n');
                    break;
                }
            }
        }

        guesses ++;
    } while (cpuguess != gumballs);

    if (cpuguess == gumballs)
    {
        while (true)
        {
            std::cout << "Is this right? (yes or no) : ";
            getline(std::cin, input);
            std::cout << "\n";

            if (input == "yes")
            {
                std::cout << "\n" << "Haha, I got it!" << "\n";
                std::cout << "Well, well, well... Let's see..." << "\n\n";
                std::cout << "This took me " << guesses << " guesses, not bad, huh?" << "\n\n";
                std::cin.clear();
                std::cin.ignore(10000, '\n');
                break;
            }

            else if (input == "no")
            {
                std::cout << "Hmmm, do you think I'm a fool?! Don't lie! I was right!" << "\n";
                std::cout << "Well, well, well... Let's see..." << "\n\n";
                std::cout << "This took me " << guesses << " guesses, not bad, huh?" << "\n\n";
                std::cin.clear();
                std::cin.ignore(10000, '\n');
                break;
            }
        }
    }
}


This works for numbers up to 1000. Even though I haven't implemented the thing where the computer does not guess a value it has tried before, it is *cough* I guess.... *cough* better...
Last edited on
A way to make the computer never repeat the same thing twice is to first set max to 1 more than there should be, and min to 1 less. Then once you generate a new number tell the computer that
if (cpuguess == max) cpuguess -= 1; and
if (cpuguess == min) cpuguess += 1;
This way the computer is able to guess the number, even if it is set to the lowest or the highest possible value :)
Topic archived. No new replies allowed.