Home > database >  How to store the value of an int in a while loop without changing the value once user input is taken
How to store the value of an int in a while loop without changing the value once user input is taken

Time:09-17

I'm trying to make a guessing game and the problem is I have to say how many tries it took, but only to count unique tries. So if I guess 1, 2, and 3. Its 3 tries, but if I guess 1, 1, and 2 or 1, 2, and 1, it's supposed to be 2 tries. This is my game portion so far.

int g = 0;
int tries = 0;
// loop for the user to guess
while (g != numberToGuess) {
    printf("Guess a number between 0 and 99: ");
    cin >> g;
    int t1 = 0, t2 = 0;
    tries  ;
    if (g < numberToGuess) {
        printf("The number is higher\n");
    }
    else if (g > numberToGuess) {
        printf("The number is lower\n");
    }
    else if (g > 100) {
        printf("Number has to be lower than 100. ");
    }
    else {
        printf("You guess the correct number. You tried %d ", tries, tries == 1 ? "time" : "times");
        break;
    }

I'm trying to take g,my guess, and store it to compare it to the last guess to determine if it is the same or not.

CodePudding user response:

As it was already pointed out, you can't store just one variable since the user can enter numbers like 1, 2, 3, 1 ... so you will need to store each number and the best way is to use an array.

    while(g != numberToGuess){
        printf("Guess a number between 0 and 99: ");
        cin >> g;
        //check if number is in array before storing it
        //you will either have to write a function or use something like std::find
        if(/*checkIfInArray*/) { 
             triesArray[tries] = g;
             tries  ;
         }
         .
         .
         .
        }

If you are allowed to use std::find search on how to use it, if not just make a function that returns true if the element is in the array and false if not.

CodePudding user response:

Using C std::set

C provides std::set which is a container holding unique objects as keys. In your case the objects are simple integer values from 0 - 99, but the type of object can be anything. The key (no pun intended) is that since the objects are stored as the keys for the std::set, there can only be one of each, the keys will always be unique.

So in your case, all you need to do is std::set::insert each of the user guesses and when done the set will will hold the unique set of guesses made by the user. All you need to do at that point is get the .size() of the set to get the number of unique entries by the user.

For example, you can do:

#include <iostream>
#include <set>

int main (void) {
  
  int g = -1, numberToGuess = 23;     /* g, numberToGuess */
  std::set<int> guesses{};            /* set of int */
    
  /* loop for the user to guess */
  while (g != numberToGuess) {
    
    std::cout << "Guess a number between 0 and 99: ";
    
    if (!(std::cin >> g)) {
      std::cerr << "  error: invalid integer input.\n";
      return 1;
    }
    
    if (g < 0 || 99 < g) {
      std::cout << "Number must be from 0 to 99\n";
      continue;
    }
    
    guesses.insert(g);      /* insert g in set - duplicates ignored */
    
    if (g < numberToGuess) {
      std::cout << "The number is higher\n";
    }
    else if (g > numberToGuess) {
      std::cout << "The number is lower\n";
    }
    else {
      size_t tries = guesses.size();
      std::cout << "\nYou guessed the correct number. You tried " <<
                tries << (tries == 1 ? " time.\n" : " times.\n");
      break;
    }
  }
}

(note: you are using C , there is no need to mix C stdio.h output functions with iostream functions [there are times when that can be advantageous, but not here]. Learning C make a point to use the features it provides. C and C are different languages. Also see Why is “using namespace std;” considered bad practice? -- it's fine for short examples, but just be aware of the downside)

Example Use/Output

./bin/numtoguess-set
Guess a number between 0 and 99: 23

You guessed the correct number. You tried 1 time.

Or with more tries:

$ ./bin/numtoguess-set
Guess a number between 0 and 99: 50
The number is lower
Guess a number between 0 and 99: 25
The number is lower
Guess a number between 0 and 99: 10
The number is higher
Guess a number between 0 and 99: 20
The number is higher
Guess a number between 0 and 99: 22
The number is higher
Guess a number between 0 and 99: 23

You guessed the correct number. You tried 6 times.

Always make sure you handle invalid input errors as well, e.g.

./bin/numtoguess-set
Guess a number between 0 and 99: 40
The number is lower
Guess a number between 0 and 99: What about 30?
  error: invalid integer input.

Using simple Frequency Arrays

If you cannot use the containers C provides, then a simple Frequency Array (initialized all zero) where there is one element in the array for each of the possible values you need to track for uniqueness or count. When a user enters a value, you simply increment the number at that element in your array. (e.g. guesses[g] = 1;) When you need to determine the unique number of guesses, you just loop over the array and count the number of elements that are not zero.1

Rewriting the code to use a frequency array simply requires replacing the std::set by your array, e.g.

#include <iostream>

#define VALUES_IN_RANGE 100

int main (void) {
  
  int g = -1, numberToGuess = 23,     /* g, numberToGuess */
      guesses[VALUES_IN_RANGE] = {0}; /* array of 100 int initialized zero */
  
  /* loop for the user to guess */
  while (g != numberToGuess) {
    
    std::cout << "Guess a number between 0 and 99: ";
    
    if (!(std::cin >> g)) {
      std::cerr << "  error: invalid integer input.\n";
      return 1;
    }
    
    if (g < 0 || 99 < g) {
      std::cout << "Number must be from 0 to 99\n";
      continue;
    }
    
    guesses[g]  = 1;    /* add one to the element at g */
    
    if (g < numberToGuess) {
      std::cout << "The number is higher\n";
    }
    else if (g > numberToGuess) {
      std::cout << "The number is lower\n";
    }
    else {
      int tries = 0;
      
      /* loop over array to get number of unique tries */
      for (int i = 0; i < VALUES_IN_RANGE; i  ) {
        if (guesses[i]) {   /* if element non-zero */
          tries  = 1;       /* add 1 to tries */
        }
      }
      
      std::cout << "\nYou guessed the correct number. You tried " <<
                tries << (tries == 1 ? " time.\n" : " times.\n");
      break;
    }
  }
}

(output is the same)

Here, since you are not concerned with the count of each of the guesses, just whether the user made a guess of that number, you could make the array an array of char and simply set guesses[g] = 1; saving 3-bytes per-element in storage. Something to consider if you have a large range of values you are dealing with and only need uniqueness.

Lastly, and this is a tip, space your code a little more. That makes in much easier to read and maintain (especially for people with older-eyes). You may even find it makes errors easier to find and resolve yourself when not looking at code where all expressions and operators are packed tightly together. Up to you.

There are two ways to approach the problem. Let me know if you have further questions.

Footnotes:

1. A fuller explanation of Frequency Arrays is provided in answer to How to remove duplicate char in string in C

CodePudding user response:

I'm going to sugegst you save yourself some trouble. A for loop can manage incrementing tries and terminating the loop when a correct guess is made.

As the loop only exits when a correct guess is made, the success message might as well be after the loop. As long as tries is not local to the loop, it is still available afterwards to be printed.

I've shown the use of continue to skip the remainder of the loop body and go to the next iteration if the input is incorrect.

int g = -1;
int tries;

for (tries = 1; g != numberToGuess, tries  ) {
    cout << "Guess a number between 0 and 99: ";
    cin >> g;
    
    if (g < 0 || g > 99) {
        cout << "Number has to be between 0 and 100.\n";
        continue;
    }
    
    if (g < numberToGuess) {
        cout << "The number is higher.\n";
    }
    else {
        cout << "The number is lower.\n";
    }
}

cout << "You guessed the correct number. You tried " 
     << tries << (tries == 1 ? "time" : "times")
     << endl;
  •  Tags:  
  • c
  • Related