20 Guesses

closed account (1Cj3ko23)
For this assignment, write a program that will guess a secret number within 20 guesses or less. The user will choose a secret number between 0-1,000,000 and the program will make guesses at the number. If the program finds the number within 20 guesses it wins; otherwise, the user wins.

For each guess, the user will let the program know whether the guess is too low, too high, or correct. For example, a simple game might look like the following:

Hi, my name is Brent. Think of a number between 1-1,000,000 and
I'll try to determine it in 20 guesses or less.
You just tell me if my guess is too Low, too High, or Correct [L|H|C].

1. Is your number 1000 [L|H|C]? H
2. Is your number 500 [L|H|C]? L
3. Is your number 750 [L|H|C]? H
4. Is your number 650 [L|H|C]? L
5. Is your number 660 [L|H|C]? H
6. Is your number 655 [L|H|C]? C
I win! I guessed your number in only 6 guesses!
Thanks for playing. Goodbye.

The coding of this program does require an abstracted main(), which means that subprograms will be used to implement the various functions involved. For example, a separate function will display the greeting and a different function will ask each new guess, and another function will report the results of the game.
Please note that this is not a homework site. We won't do your homework for you. The purpose of homework is that you learn by doing. However we are always willing to help solve problems you encountered, correct mistakes you made in your code and answer your questions.

We didn't see your attempts to solve this problem yourself and so we cannot correct mistakes you didn't made and answer questions you didn't ask. To get help you should do something yourself and get real problems with something. If your problem is "I don't understand a thing", then you should go back to basics and study again.
closed account (1Cj3ko23)
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
#include <iostream>
#include <math.h>
using namespace std;

int main()
{
    const int max_value =100;
    const int min_value = 1;
    int guess=0, high=max_value, low=min_value;
    char choice;

    cout<< "Think about a number between " <<min_value<<" and " <<max_value<<endl;
    while((high-low)!=1)
    {
        cout<<"is your number less than or equal to " << guess << "?\n Enter H/h or L/l"<<endl;
        cin>>choice;
        if(choice=='h' || choice=='H')
        {

            guess-=(high-low)/2; //C+=A  ==> C=C+A
            high=guess;

        }
        else if (choice == 'l' || choice== 'L')
        {
            low=guess;
        }
        cout<<"Your number is: " <<high<<endl;
    }


    return 0;
}


This is my code but it does not work.
Last edited on
Here is a start:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>

int main() 
{
  int lb = 0, ub = 1'000'000;  
  char input = '\0'; 
  
  do 
  {
    int const range = ub - lb;
    int const guess = (range + 1) / 2 + lb;
    
    std::cout << guess << ".  Am I low, high, or correct?\n";    
    if (! (std::cin >> input)) break;
    if (input == 'l') ub = guess; 
    if (input == 'u') lb = guess;
  } while (input != 'c'); 
}

Live demo:
https://godbolt.org/z/PearMz
Last edited on
The coding of this program does require an abstracted main(), which means that subprograms will be used to implement the various functions involved. For example, a separate function will display the greeting and a different function will ask each new guess, and another function will report the results of the game.


So a simple solution turns into a convoluted one! Ahh..
Hello koltonj20,

A good start, but what I first see is:

#include <math.h> . This is a C header file and you should be using the C++ version "<cmath>". That is the correction, but the header is not needed for what you are doing. The operators (+, -, *, /, %) are built in to the IDE and compiler. Nothing special is needed to use them. Have a look at http://www.cplusplus.com/reference/cmath/ This will show you all the functions available in the header file.

Something that you could make use of is "<cctype>" then the line: if(choice=='h' || choice=='H') could be written as: if(std::toupper(choice) =='H'). Then it would not matter what case was entered.

The while condition I would have to test, but inside the while loop you only test for "L" and "H", but not "C".

Line 28 I believe should be outside the while loop to print only when the computer makes a correct guess. To keep this from always printing the line would need an if statement based on "choice" having a value of "C".

mbozzi has shown you a way to shorten your code, but you may want to stick with what you started with first to understand how it works then change things later. mbozzi example of the do/while loop I think is better choice. This way when you leave the loop the line cout<<"Your number is: " <<high<<endl; would be all that you need.

I also notice that the program does not keep track of the number of guesses. Based on the output that you have shown you will need this information.

Also you will need to deal with the computer taking more than 20 guesses.

Andy

Edit:
Last edited on
Using the required functions:

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
#include <iostream>

void header()
{
	std::cout << "Hi, my name is Brent.Think of a number between 1 - 1,000,000 and\n";
	std::cout << "I'll try to determine it in 20 guesses or less.\n";
	std::cout << "You just tell me if my guess is too Low, too High, or Correct [l, h, c].\n\n";
}

int getguess(size_t guesses, int guess)
{
	char input {};

	std::cout << guesses << ". Is your number " << guess << " [l, h, c]: ";
	std::cin >> input;

	return input;
}

void report(size_t guesses, size_t maxguess)
{
	if (guesses <= maxguess)
		std::cout << "\nI win! I guessed your number in only " << guesses << " guesses\n";
	else
		std::cout << "\nI failed. I didn't manage to guess the number\n";
}

int main()
{
	header();

	const size_t maxguess {20};
	const int maxnum {1'000'000};
	size_t guesses {1};

	for (int input {'l'}, lb {1}, ub {maxnum}; (guesses <= maxguess) && (input != 'c'); guesses += (input == 'l' || input == 'h')) {
		int const guess {(ub + lb + 1) / 2};

		if (input = getguess(guesses, guess); input == 'l') lb = guess;
		else if (input == 'h') ub = guess;
		else if (input == 'c') break;
		else std::cout << "Not a valid response\n";
	}

	report(guesses, maxguess);
}



Hi, my name is Brent.Think of a number between 1 - 1,000,000 and
I'll try to determine it in 20 guesses or less.
You just tell me if my guess is too Low, too High, or Correct [l, h, c].

1. Is your number 500001 [l, h, c]: h
2. Is your number 250001 [l, h, c]: h
3. Is your number 125001 [l, h, c]: h
4. Is your number 62501 [l, h, c]: h
5. Is your number 31251 [l, h, c]: h
6. Is your number 15626 [l, h, c]: h
7. Is your number 7814 [l, h, c]: h
8. Is your number 3908 [l, h, c]: h
9. Is your number 1955 [l, h, c]: h
10. Is your number 978 [l, h, c]: h
11. Is your number 490 [l, h, c]: l
12. Is your number 734 [l, h, c]: h
13. Is your number 612 [l, h, c]: l
14. Is your number 673 [l, h, c]: h
15. Is your number 643 [l, h, c]: l
16. Is your number 658 [l, h, c]: h
17. Is your number 651 [l, h, c]: l
18. Is your number 655 [l, h, c]: c

I win! I guessed your number in only 18 guesses

Last edited on
Hello koltonj20,

Working on your original code I made these changes. Not all are necessary, bu a suggestions.

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
#include <iostream>
#include <cctype>  // <--- For "std::tolower() and std::toupper()" + others.

using namespace std;  // <--- Best not to use.

int main()
{
    constexpr int MAX_VALUE{ 100 };
    constexpr int MIN_VALUE{};

    int guess{ MAX_VALUE / 2 }, tries{ 1 }, high{ MAX_VALUE }, low{ MIN_VALUE };
    char choice{};

    cout << "\n Think about a number between " << MIN_VALUE + 1 << " and " << MAX_VALUE << '\n';

    do
    {
        cout << "\n Is your number " << guess << "? Enter [H][L][C] ";
        cin >> choice;

        choice = (std::toupper(choice));

        if (choice == 'H')
    } while (choice != 'C');

    cout << "\n\n  Your number is: " << guess <<
        " And I guessed it in " << tries << ' ' << (tries > 1 ? "tries" : "try") << '\n';

    return 0;
}

The program is good until line 23. After this the if and else if need reworked to make the proper guess.

The idea of the program is divide and conquer, so you start with the first guess is at 1/2 the maximum value and go from there. The second guess would 1/2 way between the guess and the "high" or "low" and these values would need to be set B4 the next guess is made.

See what you can come up with for the if and else if statements.

Andy
closed account (1Cj3ko23)
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
#include <bits/stdc++.h>
using namespace std;

void header()
{
	cout << "Hi, my name is Kolton Johnson. Think of a number between 1-1,000,000 and ";
	cout << "I'll try to determine it in 20 guesses or less." << endl;
	cout << "You just tell me if my guess is too Low, too High, or Correct [L|H|C]." << endl << endl;
}

int getguess(size_t guesses, int guess)
{
	char input;

	cout << guesses << ". Is your number " << guess << " [L|H|C]: ";
	cin >> input;

	return input;
}

void report(size_t guesses, size_t maxguess)
{
	if (guesses <= maxguess)
		cout << "I win! I guessed your number in only " << guesses << " guesses" << endl;
	else
		cout << "I failed. I didn't manage to guess the number in " << guesses - 1 << " guesses." << endl;
}

int main()
{
	header();

	const size_t maxguess (20);
	const int maxnum (1000000);
	size_t guesses (1);

	for (int input ('l'), lb (1), ub (maxnum); (guesses <= maxguess) && (input != 'c'); guesses += (input == 'l' || input == 'h')) {
		int const guess ((ub + lb + 1) / 2);

		if (input = getguess(guesses, guess); input == 'l') lb = guess;
		else if (input == 'h') ub = guess;
		else if (input == 'c') break;
		else cout << "Not a valid response" << endl;
	}

	report(guesses, maxguess);
	
	cout << "Thanks for playing!! Goodbye.";
	return 0;
}


error message
C:\Users\kolto>g++ "20 Guesses.cpp" -o "20 Guesses.exe"
20 Guesses.cpp: In function 'int main()':
20 Guesses.cpp:53:39: error: expected ')' before ';' token
if (input = getguess(guesses, guess); input == 'l') lb = guess;
_____________________________^
20 Guesses.cpp:53:53: error: expected ';' before ')' token
if (input = getguess(guesses, guess); input == 'l') lb = guess;
_______________________________________^
20 Guesses.cpp:54:3: error: 'else' without a previous 'if'
else if (input == 'h') ub = guess;
^
Last edited on
1. Whitespace in filenames is an abomination. IMHO.

2. You did post 50 lines of code. Your error messages point to lines 53 and 54.

Please explain the logic of
1
2
if ( input = getguess(guesses, guess); input == 'l' )
    lb = guess;
@koltonj20 - what you have posted is what I had in my post above. This requires compiling as C++17. It compiles/runs OK with VS. There's an option for g++ so that it will compile as C++17 but I don't know as I don't use g++. Perhaps some one who does use g++ could provide the requuired incantation.
The manual of g++ can be accessed with: man g++
The name of option is -std=

The possible values of of that option depend on the version of g++.
On more recent versions the value is c++17.

Hence:
g++ -std=c++17 "20 Guesses.cpp" -o "20 Guesses.exe"

Old versions of g++ have no, or partial support for C++17.
The value on latter might be c++1z
closed account (1Cj3ko23)
Here is my code

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
#include <bits/stdc++.h>
using namespace std;

void header()
{
	cout << "Hi, my name is Kolton Johnson. Think of a number between 1-1,000,000 and ";
	cout << "I'll try to determine it in 20 guesses or less." << endl;
	cout << "You just tell me if my guess is too Low, too High, or Correct [L|H|C]." << endl << endl;
}

int getguess(int guesses, int guess)
{
	char input;

	cout << guesses << ". Is your number " << guess << " [L|H|C]: ";
	cin >> input;

	return input;
}

void report(int guesses, int maxguess)
{
	if (guesses <= maxguess)
		cout << "I win! I guessed your number in only " << guesses << " guesses" << endl;
	else
		cout << "I failed. I didn't manage to guess the number in " << guesses - 1 << " guesses." << endl;
}

int main()
{
	header();

	int maxguess (20);
	int maxnum (1000000);
	int guesses (1);

	for (int input ('l'), lb (1), ub (maxnum); (guesses <= maxguess) && (input != 'c'); guesses += (input == 'l' || input == 'h')) {
		int guess ((ub + lb + 1) / 2);

		if (input = getguess(guesses, guess), input == 'l') lb = guess;
		else if (input == 'h') ub = guess;
		else if (input == 'c') break;
		else cout << "Not a valid response" << endl;
	}

	report(guesses, maxguess);
	
	cout << "Thanks for playing!! Goodbye.";
	return 0;
}


Is there a simpler way to write this.
1
2
3
4
5
6
7
8
for (int input ('l'), lb (1), ub (maxnum); (guesses <= maxguess) && (input != 'c'); guesses += (input == 'l' || input == 'h')) {
		int guess ((ub + lb + 1) / 2);

		if (input = getguess(guesses, guess), input == 'l') lb = guess;
		else if (input == 'h') ub = guess;
		else if (input == 'c') break;
		else cout << "Not a valid response" << endl;
	}
the section under your question?

define simpler ... what are you looking for, and why?
if you don't understand it, ask something. If you want it written like a beginner so you can hand it in, .. the keyboard is that way ->
Last edited on
closed account (1Cj3ko23)
Like what does the lb(1), ub (maxnum)mean?

Also, what does guesses += (input == 'l' || input == 'h') mean?
Last edited on
seeplus wrote:
1
2
3
4
5
6
7
8
9
10
11
for ( int input {'l'}, lb {1}, ub {maxnum};
      (guesses <= maxguess) && (input != 'c');
      guesses += (input == 'l' || input == 'h') )
{
  int const guess {(ub + lb + 1) / 2};

  if ( input = getguess(guesses, guess); input == 'l' ) lb = guess;
  else if (input == 'h') ub = guess;
  else if (input == 'c') break;
  else std::cout << "Not a valid response\n";
}

kj20 wrote:
1
2
3
4
5
6
7
8
9
10
11
for ( int input ('l'), lb (1), ub (maxnum);
      (guesses <= maxguess) && (input != 'c');
      guesses += (input == 'l' || input == 'h') )
{
  int guess ((ub + lb + 1) / 2);

  if ( input = getguess(guesses, guess), input == 'l' ) lb = guess;
  else if (input == 'h') ub = guess;
  else if (input == 'c') break;
  else cout << "Not a valid response" << endl;
}

How did you manage to replace {} with () on copy-paste (and size_t with int)? Overall, one should avoid copy-pasting. Particularly when not knowing what you are copying.

You apparently know how to declare a variable: char choice;
You know how to initialize the value of the variable during declaration: const int max_value =100;
You also know that you can declare multiple variables within same statement (and initialize too):
int guess=0, high=max_value, low=min_value;
The only thing that differs in int input {'l'}, lb {1}, ub {maxnum}; is that the initializer syntax has {} and not =.
The brace initialization syntax, {}, was added to language in C++11 -- a decade ago.

1
2
size_t guesses;
guesses += (input == 'l' || input == 'h')

The guesses is an integer.
input == 'l' returns true or false
input == 'h' returns true or false
The || is logical OR. x||y is false only if x and y are both false.
(input == 'l' || input == 'h') is true or false.
false converts to 0. Therefore, guesses += false is same as guesses += 0

true converts to 1. Therefore, guesses += true is same as guesses += 1
Last edited on
@kj20,
Why are you using the <bits/stdc++.h> header file? That's nonstandard and platform-dependent...or at least, my computer doesn't have it.

@seeplus,
How exactly does this work?
 
if (input = getguess (guesses, guess); input == 'l') lb = guess;

I had no idea you could use an if statement like that. But it works! I just never saw that before.
@agent max init-statement within if statement was added by C++17.
See https://en.cppreference.com/w/cpp/language/if
Thanks!
Topic archived. No new replies allowed.