SO I'm trying to:
Do dual input validation inside a do while loop
Check to see if the move has been made yet and whether it is a logical input. (# 1-9)
I originally thought if else statement but im not sure how to use the else statement to get back to the start of the loop.
do
{
cout << "Interesting move, What is your next choice?: ";
cin >> play;
Pused[1] = play;
if(play != Pused[0] && play != cantuse[0] && play != cantuse[1] )
{
switch(play)
{
default:cout << "Your choice is incorrect\n\n";
break;
}
}
else
{ }
}
while(play != 1 && play != 2 && play != 3 && play != 4 && play != 5 && play != 6 && play != 7 && play != 8 && play != 9);
Dis_board(board);
use "continue" keyword to go back to start of the loop.
Just remove else. I think it is not required. Automatically your loop will be continued if conditions in while are satisfied.
Your question is a bit hard to understand, but you've got a few conditions to solve in this loop:
Ask the user for input
Check if the users input is valid (Between 1-9 and not been used before)
Exit the loop if we have a valid choice
So we need to record what moves have been done and also check that the user's input is within the valid choices, we can use a loop that exits only when a valid choice is chosen.
int choice;
bool used[9] = { false }; // Set all values to false
std::cout << "Interesting move, what is your next choice?: ";
do {
std::cin >> choice;
// Here we check if the choice is within the range we care about
// and not used, note if the first condition isn't true then
// the second condition won't be evaluated, so if choice is 11
// we won't check used[10] because the && will short circuit, this
// lets us avoid array out of bounds. We also need to
// offset the choice by 1 for the array because arrays in C++
// are indexed from 0 so used runs from used[0] to used[8]
if((choice >= 1 && choice <= 9) && !used[choice - 1]) {
// If we're here we have a valid choice, mark it as used
// and leave the loop
used[choice - 1] = true;
break; // Exit the loop regardless of the while condition
}
// If we've made it here it means the above if failed and we have
// an invalid choice. Restart the loop!
std::cout << "\nInvalid choice! Input: ";
} while (true);
Related
I've just started learning the basics in C++ and currently am trying to make a program that does a few basic things. The problem I have is occurring in the pasted function below.
At this point it literally does nothing when it runs. All I'm trying to do it make it so the function runs over and over again forever, until the user enters the letter 'q'.
The function must keep running even if the user enters some random string, anything, 'q' is the only keystroke that should stop the loop.
I have tried toying around with 'cin.whatever" and haven't found success. If you have an answer please provide as much explanation as possible. Thank you!
void menu()
{
cin.clear();
cin.ignore();
char quit = 'w';
while (quit != 'q') // while loop to allow the user infinite tries
{
cout << "Which story would you like to play? Enter the number of the story (1, 2, or 3) or type q to quit: " << endl;
cin >> quit;
if (quit < '1' or quit > '3') // make sure the user picks a valid choice
{
cout << "Valid choice not selected." << endl;
}
if (quit == '1')
{
story1(); // run story 1
}
if (quit == '2')
{
story2(); // run story 2
}
if (quit == '3')
{
story3(); // run story 3
}
if (quit == 'q')
{
cout << "good bye" << endl;
break;
}
}
}
Try adding single quotes around your 1,2,3 like you did with the q. The cin is expecting a char to be entered so evaluate it as such. e.g: if (quit == '1')
Note: This is a homework assignment.
I am trying to make a program that plays the game Pig! Pig is a game with the following rules:
1. First to get 100 GAME POINTS is the victor.
2. On your turn, you roll a dice. If you get a 1 at any roll, you end your turn and add 0 to your GAME SCORE.
3. If you roll any value other than a 1, you have the option to HOLD or PLAY. If you PLAY, your roll is added to your TURN SCORE and you roll again. If you HOLD, your TURN SCORE is added to your GAME SCORE and the turn passes to the computer.
The game is coming along very easily until I get to the following problem (see code):
int player(){
char PlayAgain = 'Y';
int turn_score = 0;
while (PlayAgain != 'N' || PlayAgain != 'n'){
int dice;
srand(time(NULL));
dice = rand() % 6 + 1;
turn_score = turn_score + dice;
if (dice != 1){
cout << "You rolled a " << dice << "! Would you like to roll again? [Y/N]: ";
cin >> PlayAgain;
if (PlayAgain == 'N' || PlayAgain == 'n'){
/*END TURN AND return turn_score;*/
}
}
if (dice == 1){
cout << endl << "Oops! You rolled a 1! Your turn is ended, and you add nothing to your score.\n";
system("PAUSE");
/*END TURN, NO SCORE ADDED*/
}
}
}
How can I have the program end the loop prematurely (if either the play HOLDS or dice == 1) and return the proper value (if HOLD, return turn_score. Else return 0)? [See two noted sections]
You can use break to get out of a loop. Since you're saying that you want to return "the right value" then you should do something like that:
On the first if clause
if (PlayAgain == 'N' || PlayAgain == 'n'){
/**Game-Specific logic here**/
return turn_score
}
and on the second one:
if (dice == 1){
cout << endl << "Oops! You rolled a 1! Your turn is ended, and you add nothing to your score.\n";
/**Game-Specific logic here**/
cin.get();
return turn_score;
}
A return statement doesn't need to be at the end of the function and more than one return statements can co-exist inside the same function
Rather then correcting your code I would like to make you clear about what actually is needed here.
Ever heard of break; statement.Let us understand with a simple example
see the following code snippet where your program is taking input from the user,it keeps on taking input from the user until you press 'A'
char var;
while(true)
{
cin>>var;
if(var=='A') break;
}
Now in this program,the while loop is set to true and will keep on running and taking input from the user,and the if statement will not run until the user have entered 'A'. AND the moment 'A' is given as the input,break will take the control out of the while loop for you.
How about having your 'return' statement (with the proper value depending on the case) inside your loop? This will break both the loop and the function, but returning the value you needed.
I'm working on a Programming assignment and I can't figure out why this while loop is looping infinitely. There has been other input before this loop occurs, but I have cin.ignore() to clear any junk out before this loop. I'm scratching my brain, help?
//Prompt for readiness
char ready = 'x';
while (ready != 'Y' || ready != 'y') {
cout << "READY TO START YOUR TURN " << playerName << "? ";
ready = cin.get();
}
You need to change || (OR) to && (AND). Also, reset the stream after you read with cin.get(), i.e. put the following line after:
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cin.clear();
(you need to #include <limits>)
Otherwise, cin.get() returns a char and leaves an extra \n (newline) in the stream, that gets read once more and you basically end up with the loop executing twice for each non-yes response.
think of boolean algebra. OR gate results in true if one or both sides are true. so, if you input 'y' or 'Y', your statement will result in returning true, since of the sides would still be true.
if you change || to && (AND gate), which returns true only if both of the sides are true, then your statement makes sense. user inputs 'y' or 'Y' (he's ready, so get him out of that loop!) and one of the sides is equal to false, hence loop terminates.
while (ready != 'Y' && ready != 'y') {
or
while (ready == 'Y' || ready == 'y') {
are statements that you meant.
change the code to this -
char ready = 'x';
while (ready != 'Y' && ready != 'y') {
cout << "READY TO START YOUR TURN " << playerName << "? ";
ready = cin.get();
}
It will resolve your issue.
I need to figure out how to validate 2 conditions.
Check if a previous number has been played.
Check if the number is between 1 and 9.
In either case, it should loop back to the beginning. With the first situation, it shouldn't run till the user enters a number that hasnt been played.
do
{
cout << "Interesting move, What is your next choice?: ";
cin >> play;
Pused[1] = play;
if(play != Pused[0] && play != cantuse[0] && play != cantuse[1] )
{
switch(play)
{
default:
cout << "Your choice is incorrect\n\n";
break;
}
}
}while(play != 1 && play != 2 && play != 3 && play != 4
&& play != 5 && play != 6 && play != 7 && play != 8 && play != 9);
Dis_board(board);
Instead of do-while loops, i like to use the combination of infinite loops + break statements, like this:
cout << "What is your first choice? ";
while (true)
{
// Input the choice, including validation
// Do the move
if (game_over)
break;
cout << "Interesting move; what is your next choice? ";
}
In the code above, the two comments represent code, which may itself contain loops. In order to reduce confusion, you might want to stuff this code into a separate function. For example, to input the choice:
while (true)
{
cin >> play;
bool is_illegal =
play == cantuse[0] ||
play == cantuse[1] ||
play < 1 ||
play > 9;
if (is_llegal)
cout << "Your choice is incorrect; please enter again: ";
else
break;
}
Note: to implement good handling of user errors, you also have to account for the case when the user enters nonsense instead of a number; look up istream::ignore and ios::clear for that.
bool choose() {
int answer = 0;
while(answer != 1 || answer != 2) {
cout << endl << "Do you want to encrypt(enter 1) or decrypt(enter 2)?" << endl;
cin >> answer;
}
if(answer == 1) return true;
return false;
}
What is the best way to read from line and compare input with integers?
I know ways cin , gets , getline(cin, answer) .
Which should I use and why?
At the moment, this way is not working, because when i enter 1 or 2, it still stays in while.
Your condition is incorrect. By De Morgan's laws, you should be using && instead.
while(answer != 1 && answer != 2) {
You're reading the value correctly. However, the loop condition is wrong; it should be
while(answer != 1 && answer != 2)
Using || makes the condition always true, since no number is equal to both 1 and 2.
This code is a very good candidate for do-while loop, and if you use that you're not required to initialize the variable answer.
int answer; //= 0; no need to initialize!
do {
cout<<"Do you want to encrypt(enter 1) or decrypt(enter 2)?"<<endl;
cin >> answer;
}while(answer != 1 && answer != 2);
And of course, you need to use && as others has already pointed out. :-)
By the way, what would happen if user entered any non-integer input such as hgjkhg? cin>>answer would fail to read the input and it will remain there forever, and the flag of cin will be set failure, and cin will not be able to read futher input. That means, the loop will never exit!
To avoid this, and to make the code more robust and complete you should write it as:
int answer = 0;
while(answer != 1 && answer != 2) {
cout<<"Do you want to encrypt(enter 1) or decrypt(enter 2)?"<<endl;
if ( !(cin >> answer) )
{
cin.clear(); //clear the failure flag if there is an error when reading!
std::string garbage;
std::getline(cin, garbage); //read the garbage from the stream and throw it away
}
}
Yes. You can use your while loop instead of do-while. All that you need to add the if(!(cin>>answer)) { ... } in your code. :-)