I am experiencing troubles with what I suspect to be while loops. I am working on building a simple game, and I think my two while loops are interfering with eachother somehow. here's the main function! Thanks in Advance!:
int main( int argc, char* argv[])
{
SDL_Startup();
while(Playing == false && quit == false)
{
StartingScreen.input();
StartingScreen.render();
character.input();
SDL_Flip( screen );
SDL_Delay(1000/FPS);
}
while(Playing == true && quit == false)
{
CAMERAGUY.Camera();
character.input();
character.adjust();
SuperSnail.move();
SuperSnail.attack();
TheWall.boundaries();
TheWall.render();
SuperSnail.render();
character.render();
character.reset();
HUD.render();
SDL_Flip(screen);
SDL_Delay(1000/FPS);
cout << StartingScreen.x << endl;
}
if(Playing == false)
cout << "Playing == false" << endl;
if(quit == true)
return 0;
}
So the bool playing is set to false to begin with, and is set to true when my character runs out of lives. so when Playing is set to false in the second loop, it doesn't repeat the first loop. I JUST thought, I think maybe it would work if I put the two loops in a separate loop.
I've edited your code with comments to explain what it is doing (and why it is not behaving as you expect):
int main( int argc, char* argv[])
{
SDL_Startup();
// Set `Playing` to false
while(Playing == false && quit == false)
{
// Do stuff which applies when `Playing` is false
//
// At some point, set `Playing` to true, so that
// the loop ends
}
while(Playing == true && quit == false)
{
// Now do stuff which applies when `Playing` is true
//
// At some point, set `Playing` to false, so that
// the loop ends
}
// Both loops have come to an end, and there
// is no code to return to the first loop
// so execution continues below:
// This line always executes because `Playing` is always false
// by this point:
if(Playing == false)
cout << "Playing == false" << endl;
// This conditional statement doesn't do what you think, because
// in the case that `quit == false`, the end of your `main` function
// is reached and returns 0 by default, meaning that the outcome
// is the same no matter what the value of `quit`
if(quit == true)
return 0;
}
The solution: enclose the both loops in a while(quit == false) loop. This means that both when the second loop completes, the first loop will be evaluated again, until you are ready to stop execution by setting quit to true.
A few other tips:
A neater way of expressing quit == false is !quit.
A neater way of expressing Playing == true is Playing.
Using global variables in the way that you are is almost certainly a bad idea, and you should probably rethink your design.
It is pretty simple. In your current implementation you will never return to your first while loop if your second loop is finished, because you reach the return of your main routine.
I guess you should always use only one main loop for your game.
Related
The error here is that the number never stops increasing (0 -> infinite). Why doesn't the loop stop once totalCareTime hits 25?
int totalCareTime = 0;
while (totalCareTime <= 25 || interrupted == false)
{
++totalCareTime;
cout << totalCareTime << endl;
if (time == time + emergencySam || time == time + emergencySid)
{
interrupted = true;
}
}
You use ||, so as long as either condition is true, the loop continues. If interrupted stays false (which will always be the case unless emergencySam or emergencySid have a value of 0; it's unclear how they are set or whether they can be changed at all), the loop will go forever. Change to && if you need both conditions to be true for the loop to keep going.
I have a problem with the while loop, I have instructed that the key1 variable should only be executed when at least some "if" instructions have been executed, however, it re-executes the while loop even if the variable key1 is equal to 0.
It should be noted that I do not change the value of the key1 variable in another part of the function
void form_table(...) {
int key1=1;
while (key1 != 0) <==(2)
{
key1=0;
if (dx->get_numero() == 1 && dy->get_numero() == 1)
{
key1++;
//Some code
}
else if (dx->get_numero() == 1 && dy->get_numero() == 0)
{
key1++;
//some code
}
else if (dx->get_numero() == 0 && dy->get_numero() == 1)
{
key1++;
//some code
} <==(1)
else
break;//I put it in case, but even with that it goes back into the buble while
}
}//Here is the problem, when finish the funcion execution the program comes back to the line (1), and then re-runs the while cycle (2)
the loop works if key1 is different from 0 if you increment key1 and therefore it is different from 0 the cycle reinitiates.
you have to do:
while (key1 == 0) {
// rest of the code
}
currently I'm having problems with this do ... while loop.
do {
// program code here
cout << "Would you like to run the program again?(yes/no)";
bool exit = false;
string strexit;
do {
getline(cin, strexit);
if (strexit == "no") {
exit = false;
break;
}
else if (strexit == "yes") {
exit = true;
}
else {
cout << "Enter yes to rerun the program, and no to exit.\n";
};
} while (!exit);
system("cls");
} while (exit);
return 0;
}
I researched online, how to break out of do ... while loops, and it's when the condition is true, it loops back again, but if its false it exits.
So if you look at the code, if the user types in no, it sets exit = false, which takes it out of the bigger do while loop, where the break takes it out of the current do while loop.
If the user enters yes, it changes exit to true, which breaks it out of the current do ... while loop, but it doesn't break out of the second.
My question is, (or what I need help with) is that when the user inputs 'no', it cannot exit the do ... while loops, and I'm severely confused as to why. (It loops back to the beginning of the program.)
In the (shortened) code
do
{
bool exit = false;
// ...
} while (!exit);
you actually have two different symbols named exit. Inside the loop you have the variable. Outside of the loop, and used for the condition, you have the function std::exit. Which will be plain exit if you have using namespace std;.
The function exit when used in the condition will decay to a pointer to the function, and it will never be "false". So the condition !exit is always true and you have an infinite loop.
To solve this there are two things you need to do:
Learn that using namespace std; is very bad practice
Move the variable exit to be defined outside the loop. And you should really rename to something more descriptive it as well (the word "exit" is a little bit to general).
I think #SomeProgrammerDude has given excellent advice that's well worth following--but I'd go a step further, and advise moving the code to get the user's response into a separate function so you can more easily reason about each part of the code in isolation:
bool check_for_exit() {
std::string prompt = "\nDo you want to exit the program? ";
std::string strexit;
do {
std::cout << prompt;
std::getline(std::cin, strexit);
prompt = "\nPlease enter yes or no";
} while (strexit != "yes" && strexit != "no");
return strexit == "yes";
}
Then you use that function in the code that does the real work, something on this order:
do {
whatever();
} while (!check_for_exit());
It seems to me that this approach helps avoid many of the problems you encountered in your code.
This question already has answers here:
What is a debugger and how can it help me diagnose problems?
(2 answers)
Closed 5 years ago.
Was making a small code for a text based game but i tried to do thinks a bit different than the tutorial sort of to test my understanding but i tried to get a function value to make a do while statement but it seems whether the statement false or true the code just keep looping infinitely im a beginner so pls if you have a time explain why the code is faulty and Thank you in Advance
The main function
int main() {
PrintIntroStart();
do {
PlayGame();
AskToPlayAgain();
} while (AskToPlayAgain() == true);
return 0;
}
the Bool Function
bool AskToPlayAgain(){
//Asking The Player Whether To Play Again Or Not
std::string PlayerResponse = "";
std::cout << "Do You Want To Play Again? (Yes/No)" << std::endl;
std::cin >> PlayerResponse;
if (PlayerResponse[0] == 'y' || 'Y')
return true;
else
return false;
}
Also, here you are asking twice to play again
do {
PlayGame();
AskToPlayAgain();
} while (AskToPlayAgain() == true);
this should be
do {
PlayGame();
} while (AskToPlayAgain() == true);
if (PlayerResponse[0] == 'y' || 'Y') this one should be
if (PlayerResponse[0] == 'y' || PlayerResponse[0] == 'Y')
Otherwise your if condition is always true, because 'Y' itself is non-zero.
And in fact you don't need this if statement, just
return PlayerResponse[0] == 'y' || PlayerResponse[0] == 'Y';
So first of all, you are only checking the outcome of the game every second play.
You should follow #ziza s answer and remove the function call inside the loop.
The second problem, that causes the infinite loop is your input check.
A bool value in c++ is not a single bit, but just anoter regular value that is evaluated as false if it is 0 and to true if it has any other value. In your case the first comparison will evauate to 1 if the player input is 'y' and the second part of the condition will be the value of the 'Y' character (which is not 0). So your condition will always be true like #liliscent stated.
I am trying to increment a lap counter in my game by one but because I have to put this code in the game loop my counter goes over every time by about 500 instead or moving up one. Here is my code. The checkpointPassed variable is only true when a checkpoint is passed through. I know this works and the checkpoint number is the current checkpoint and they start at 0.
if(checkpointNumber == 0 && checkpointPassed == true)
{
lapNumber += 1;
}
I can't post the game loop because it is quite large.
Any Help is appreciated.
EDIT
Here is some more of the code so you can see what I am trying to do.
if(distance > carRadius && markerCounter < 5000)
{
if(checkpointPassed == true)
{
markerCounter++;
}
}
if(checkpointNumber == 0 && checkpointPassed == true)
{
lapNumber += 1;
}
if(distance < carRadius)
{
markerCounter++;
cross->SetX(checkpointX);
cross->SetY(checkpointY);
cross->SetZ(checkpointZ);
checkpointNumber += 1;
checkpointPassed = true;
}
if(markerCounter > 4999)
{
checkpointPassed = false;
cross->SetPosition(0,-50,0);
markerCounter = 0;
}
Add another two variable called inCheckpoint, which stores whether the user is currently "inside" the checkpoint or not. This allows you to detect when the user enters a checkpoint and only increment the lapNumber then. The code would look as follows:
if(checkpointNumber == 0 && checkpointPassed == true)
{
if (inCheckpoint == false) /* previously not inside a checkpoint */
lapNumber += 1;
inCheckpoint = true;
}
else
{
inCheckpoint = false;
}
UPDATE: Don't rely on checkpointPassed:
if(distance < carRadius)
{
if (inCheckpoint == false) /* previously not inside a checkpoint */
lapNumber += 1;
inCheckpoint = true;
}
else
{
inCheckpoint = false;
}
You could set/pass a gueard value that indicates how many iterations in the game loop you are (or whether this is the first iteration). If it is the first iteration (within the current lap), increment the variable as you do now, otherwise don't
You will need to reset this guard value for each lap -- e.g. right after you increment lapNumber.
You might need to cancel the 'checkpointPassed` state.
if (checkpointNumber == 0 && checkpointPassed == true)
{
lapNumber += 1;
checkpointPassed = false;
}
This means that you won't be counting the lap again until the next time a checkpoint is passed, which is presumably when you need it counted.
However, if you need checkpointPassed true later in the loop, then you'll need to think whether you need yet another variable, such as lapCounted, which is set to false when checkpointPassed is set to true, and reset to true by the code above (instead of setting checkpointPassed, not as well as setting it).
If I understand correctly what you said, your 'if' statement is inside the main loop and when you pass a checkpoint, 'checkpointPassed' becomes true. For how long?
If it stays 'true' for a few iterations, then each time your game loop does an iteration,your lap counter is incremented. In this case, you should either set checkPointPassed to false at the end of the iteration, or use a different variable, that you set to true at the same time that checkPointPassed becomes true and false after incrementing.
If this does not answer your question, can you give a little more context as with only this part of the code, it is hard to figure out what you want to do.