Text adventure: Can't get this while loop to work

Hi,

I am trying to do the text adventure project (https://www.codecademy.com/practice/projects/build-a-text-adventure), and I’m having some problems. I’ll paste the code below. Note that I am using filler text here:


#include <iostream>

int main () {

  
  std::cout << "\nLorem ipsum\n\n";

  char choice1;

  std::cout << "Make a choice: A, B or C?";  
  std::cin >> choice1;
  
  while (choice1 != 'A', 'a', 'B', 'b', 'C', 'c') {
    
    std::cout << "Invalid entry. Try again!";    
    std::cin >> choice1;
    
  }
  
    
  if (choice1 == 'A' or choice1 == 'a') {
    
    std::cout << "\nYou chose A.\n\n";
    
  }
  
  else if (choice1 == 'B' or choice1 == 'b') {
    
    std::cout << "\nYou chose B.\n\n";
    
  }
  
  else if (choice1 == 'C' or choice1 == 'c') {
    
    std::cout << "\nYou chose C.\n\n";
    
  }


}

I am coding in notepad and compiling/executing in Windows, as Codecademy keeps disconnecting on me, at least in this exercise. In any case, when I execute the program I get to the “Make a choice” line, but when I try to make an input, I get the “Invalid entry” line no matter what I type, whether I type “A” or “b” or “x” or “1”. And if I type several characters, like “ax”, I get the “Invalid input” line an equal number of times, repeatedly. After a while, the program crashes.

What I want is that the player will get the “Invalid entry” line (one of them, not one for each character they type), no matter what they type unless it’s one of the six charcters I have entered, and that they will get this indefinitely until they enter a valid character. Then I want them to get the “You chose X” line, corresponding to what character they typed.

I have tried several alternatives, including:


 while (choice1 != 'A' and choice1 != 'a' and choice1 != 'B' and choice1 != 'b' and choice1 != 'C' and choice1 != 'c')

But I can’t get it to work, so I imagine I must be doing something fundamentally wrong.

Any help would be greatly appreciated.

there’s only one comparison being made there
you could start with figuring out how to compare one character to several, without involving a loop or user input, and when you know how to do that you can move on to the next problem whatever that is

comparing one thing to several is repetition, I suggest using a loop

and, if you’re writing code to handle one character at a time, then you probably shouldn’t expect it to do something smart when you input several characters at once, that seems a bit like you haven’t entirely decided what should happen there

1 Like

there’s only one comparison being made there
you could start with figuring out how to compare one character to several, without involving a loop or user input, and when you know how to do that you can move on to the next problem whatever that is

I am not sure I understand. First, I don’t understand what you mean with “comparing” in this context. Secondly, I am not sure how I would figure out how to figure that out. That’s kind of the problem.

comparing one thing to several is repetition, I suggest using a loop

I thought using while is using a loop?

and, if you’re writing code to handle one character at a time, then you probably shouldn’t expect it to do something smart when you input several characters at once, that seems a bit like you haven’t entirely decided what should happen there

My assumption was that as long as the player types anything except for the characters I have entered, he would get the “Invalid entry” line. Do I have to include code for all types of input? As in, explicitly prohibiting the player inputting integers, strings, etc.? Seems like it would be better to say “you can only enter this”, instead of “you can not enter this nor this nor this nor this nor this”.

You’re using a comparison operator !=, meaning “not equal to”. :slight_smile:

If you were told to write a function that accepts a char and a string, and returns whether the char can be found in that string, is that something you could do?
You would probably write a loop where you look at each char in the string, comparing it to the char to search for.

If you write such a function, you could then use that in your condition, and there would be no messing around with manually repeating code to compare the char to each of the other ones.

while (!isOneOf(choice1, "aAbBcC")) {
    ...
}

That’s giving your program different input from what you seem to be trying to make it do.

If you program A and test B then yeah B probably won’t do what you want, maybe you should test A instead, or also implement B.


There’s nothing there saying that choice1 should be compared to 'a', for that to happen you would need to use some comparison operator and pass it the two values you want to compare.
Code is instructions, so if you want something to happen, you’ve got to write instructions that makes it so.

1 Like

If you were told to write a function that accepts a char and a string, and returns whether the char can be found in that string, is that something you could do?
You would probably write a loop where you look at each char in the string, comparing it to the char to search for.
If you write such a function, you could then use that in your condition, and there would be no messing around with manually repeating code to compare the char to each of the other ones.

I see. I think I could write something that checked whether there is an “a” if the user typed something like “large”, for instance, but I don’t know how I would account for the user typing something like “Aab” or “ball”, in which case they would be typing several letters that count as valid choices. How can I restrict the player from typing several things in the ‘stdcin >> choice1;’ ? Ideally, they should only be able to type one character. I don’t believe the course has covered that, however.

Thank you for your help thus far.

You can’t physically prevent a user from giving that input, that’s probably not what you mean should happen. Instead you would need to decide how your program should react to that happening.

Presumably you’d want to do this:

https://asciinema.org/a/zu6gH3SE0sYUDvbTeJw9aIj22

But you can’t really talk about how to write that as code yet, because you haven’t yet decided what should happen.

When you firmly decide what should happen, you are giving yourself a reference, something that you can compare to what you currently have, which in turn tells you what needs to change. You give yourself the ability to identify problems, and it is only when you’ve done that that you can begin to solve them.

You can’t physically prevent a user from giving that input, that’s probably not what you mean should happen. Instead you would need to decide how your program should react to that happening.

Obviously I can’t prevent the user from pressing several keys on their keyboard, but surely it’s possible to limit the amount of characters they can enter in a field? For instance, if I try paying a bill on my online banking service and I have to enter my social security number, I can’t enter more than 11 numbers. If I try, nothing will show up.

This is a bit beside the point, however, since this is not something that is being learnt in this course (at least not thus far).

It’s not the input that changes. It’s what you do with the input that changes.
So what should your program do?

You can’t say that the input isn’t there. It is. How should your program react to it?
Why would you “not be able” to enter further input? What would the program need to be doing when it receives that input?
What is your program doing when you seemingly can enter input?

What happens when you press a key? What happens currently, and what do you want to happen instead?

There’s no prevention. There are things happening. What are those?


There are some parts to this that you do not know and are not able to figure out entirely on your own. But by observing what you can see and combining that with what you do know, you can say a LOT about what needs to be different.

Who controls that field? Do they still receive keystrokes? What do they do when they receive those keystrokes? What do they do when it seems like something can be entered, what do they do when it seems like something can’t be entered, what’s the controller of that field doing differently?

So, let’s say you run your program.

You press K on your keyboard.
k shows up. SOMETHING printed k. What?
Is your program able to see that k?
If not, then who printed k?
When can your program see k?

I’m not entirely sure I’m following you. However, I did make some changes to my code, following the logic I had used from the beginning. I then got it to work as I wanted, although only in the terminal on Codecademy; when I compile and execute on my own computer, the program crashes after I make a “right” choice. So I’m not sure what that’s all about, but the code now demonstrably works the way I want it to. I’m sure there is a more elegant way of doing it, and I will try to look closer at what you’ve written to try and figure it out, but I thought I should share that I got it to work decently for now.


#include <iostream>

int main () {

  
  std::cout << "\nLorem ipsum\n\n";

  std::string choice1;

  std::cout << "Make a choice: A, B or C?";  
  std::cin >> choice1;
  
  while (choice1 != "A" and choice1 != "a" and choice1 != "B" and choice1 != "b" and choice1 != "C" and choice1 != "c") {
    
    std::cout << "Invalid entry. Try again!";    
    std::cin >> choice1;
    
  }
  
    
  if (choice1 == "A" or choice1 == "a") {
    
    std::cout << "\nYou chose A.\n\n";
    
  }
  
  else if (choice1 == "B" or choice1 == "b") {
    
    std::cout << "\nYou chose B.\n\n";
    
  }
  
  else if (choice1 == "C" or choice1 == "c") {
    
    std::cout << "\nYou chose C.\n\n";
    
  }


}

By what measurement does it crash? What does that look like? What input did you use? If your run it in a debugger (for example gdb, and make sure to compile with debug info (-g) and without optimisations (no -O2)), the debugger should be able to tell you what line the crash happened at.

But maybe when you say crash you really mean that the program exited. This would again be a comparison of expectations and observations - did you expect it to do something else, and how exactly is that different.

Your terminal doesn’t send input to your program until you press enter. You’d notice this because, even if you only read one character, it still never reaches the program until enter is pressed. You also have the ability to use backspace, arrow keys and a bunch of other things, none of which your own code is providing. After the realization that your terminal does this, you can then consider, can the terminal be asked to behave differently? It can.

By crash, I mean that the program exits and then restarts shortly after. What I expect to happen is for the program to print “You chose A.”, for instance (given that I entered “A” or “a” in the program), but instead the program exits and restarts. Again, this issue does not arise when I use the terminal to compile and execute here on Codeacademy; then I get the printed text as expected.

I had not heard of gdb, I will definitely check that out.

Maybe it printed “You chose A” and then exited, would you be able to tell the difference?

Because it sounds to me like you’re saying that a window closes. It would do that when the program finishes, wouldn’t it?

Pretty sure it isn’t restarting itself. You didn’t write code that says to do that, did you?

1 Like

It seems my overeager antivirus software was to blame for the restarting issue. After I turned it off, the program stopped restarting itself. Then after I did that and added some more code, it went on to that code, so it seems the problem was indeed that it printed “You chose A” and then exited, as you suggested. Thus it seems that I am currently able to continue writing my program the way I had planned. For now, at least.

Thanks a lot for your help.