Break and rerun while loop c++ Windows - c++

I'm a rookie programmer, so please be polite.
Well i'm trying to write a simple Terminal Backgammon game, just for fun, but i have a problem.
The entire game runs in a while loop which keeps re running as long as nobody moved all their bricks to the end of the board.
A simple integer controls whatever it is black or white who plays.
I wrote a function to check for any possible moves, cause i want to program to skip the turn in case absolutely no moves can be made.
Well, i want this function to run and in case it returns false(No possible moves) then i want the rest of the code to skip and change the turn to the next player. For example if the dice combination gives no possible moves for black, then i want the program to skip black and go to white.
So i sort of want to break the rest of the while loop, but keep it running.
It's a little complicated for me to explain the issue, but i hope you guys understand.
Thanks alot
- Martin

It sounds like you want to use continue:
while (someCondition)
{
doSomething();
if (someOtherCondition)
continue;
doSomethingElse();
}
In this example, if someOtherCondition is true, the continue statement will cause the program to jump back to the top of the loop rather than continuing to execute the following statements. If someOtherCondition is false, doSomethingElse() will get run as normal.

I think this is roughly what you want to know.
Hope it helps.
while( keepRunning )
{
bool noPossibleMoves = checkForPossibleMoves();
setup for each loop iteration
Do things here that are always necessary.
if( noPossibleMoves )
{
continue; // This will go to the top of the while loop
}
wait for user input etc...
...
...
}

Related

Is there any function available to transfer the flow in c++ programming alternative to while or do while loop?

I am new to programming. & generally used to do programming on weekends. While working on a mini ATM project the problem arrives when i need to transfer the flow of the program back to up to the first line. i have already written the code of 1256 line so i can't re-structured it for while or do while loop.I searched for it a lot in the online portals but couldn't found a satisfactory results. My question is that is there any in-build function or way available for that cause.
my first line was.std::cout<<"Wlcome to your account \n";
Then my selecting option.
std::cout<<"press 12 to go to main manue \n";
that was my else if statement from where i want to send back my flow towards the first line.
else if (in.amount==12) { }
what could i write in that brackets to send back the flow of program to first line and the screen show's me agian "Welcome to your account"
i have already written the code of 1256 line so i can't re-structured it for while or do while loop.
Why not? You could just wrap a while loop around the whole thing.
That said, there is a way to do exactly what you're asking for: goto.
First you need to label one of your statements. For example:
int main() {
the_beginning:
std::cout << "Welcome to your account\n";
...
}
Then you can do goto the_beginning; to transfer control to the statement labeled the_beginning.
See goto on cppreference for more information and examples.
There is no need for a goto (which is a very bad practice in a high-level language). You can simply wrap your whole function in an infinite loop:
You had:
void foo()
{
// code
// you want to restart here
// you want to quit here
// code
}
You will have:
void foo()
{
for(;;)
{
// code
// you want to restart here
continue;
// you want to quit here
break;
// code
break; // if you want to terminate at the end;
}
}

do-while doesn't quit on first 'q'

So I'm working on a simple little text-based game in D to gain some experience working with the language. Here is a do-while loop that I'm currently struggling with:
do{
writeln("a. Advance 1 year\tc. Advance 10 years\tq. Quit");
writeln("b. Advance 5 years\td. Modify faction");
input = chomp(stdin.readln());
switch(input){
...
default:
break;
}
writeln(input[0]);
}while(input[0] != 'q');
Now the problem I'm running into is that when I hit q and enter the loop doesn't exit. It just keeps going. But then after the first time q is input, another q will terminate the loop. The writeln is in there as a sanity check, and it prints out the characters I type in exactly as typed. I feel like I'm going crazy, but it's probably just a simple type-o or something you guys will spot instantly. Nothing in the switch statement modifies 'input'.
EDIT: Okay some people have been asking to see all of the code. Here it is: http://pastebin.com/A7qM5nGW
When I said nothing in the switch modified input, it was to hide the fact I hadn't written anything in the switch yet. I've been trying to get the quit part to work right before adding the more complicated stuff. Also, here's a sample file for what I run it on: http://pastebin.com/4c2f4Z5N
Okay my friend found it. It has nothing to do with the while loop itself. I briefly forgot that args[0] is the name of the program. So it's actually running through the parent loop once with nothing, then actually quitting, and then running through the appropriate loop. It was fixed by making the parent loop like so...
foreach(filename; args[1..$]){
...
do{
...
while(input[0] != 'q');
}
as opposed to:
foreach(filename; args){
etc...

C++ File outputting strange number, and part of code not running

Yeah. So, I'm trying to make a code for a guessing game. In this game, there's a hard mode. In hard mode, you have 15 guesses, and have to guess between 1 and 500. But my problem is this:
I'm trying to have hard mode save & display your wins/losses, but when it outputs the contents of wins.txt it outputs something like this:
Wins: 0x7fffee26df78
Losses: 0x7fffee26e178
It's really confusing me. Here's the part of the code I have for that:
ifstream losses_var("losses.txt");
ifstream wins_var("wins.txt");
losses_var>> loss;
wins_var>> win;
wins_var.close();
losses_var.close();
Then it gets called with:
cout<<"Wins: "<< wins <<"\nLosses: "<< losses <<"\n"
If you would like to see the full source code, it's here: http://pastebin.com/gPT37uBJ
My second problem:
Hard mode won't display when you win. That's pretty much the whole problem. In my code, the loop for asking users for input uses
while (guess != randNum)
So at the end bracket I have what I want the code to display when a user wins, but it just doesn't run. It just stops. I would like it if someone could help me with this. The line that has the bug is line 97 through 105. Again, source code is here: http://pastebin.com/gPT37uBJ
You've got your variable names confused
cout<<"Wins: "<< wins <<"\nLosses: "<< losses <<"\n";
should be
cout<<"Wins: "<< win <<"\nLosses: "<< loss <<"\n";
It's important to pick good variable names. One reason is so that you don't confuse yourself about what your variables mean (if you confuse yourself think how it's going to be for someone else looking at your code).
Others have already answered the output problem (win vs. wins). The other problem is probably in your logic of while loop nesting. The outer loop (while (guess != randNum)) starts, but its body contains the entire inner loop (while (guesses_left != 0)). This means that the outer condition is not checked again until the inner loop terminates, which means you've run out of guesses. Also note that if you guess correctly, inner loop will never terminate. You probably want something like this:
while (guesses_left > 0) {
// input user's guess
if (guess < randNum) {
// process it
} else if (guess > randNum) {
// process it
} else {
// it's equal, user won
// do what's necessary for a win
return 0;
}
}
// ran out of guesses
// do what's necessary for a loss
return 0;
You are not writing your variables win and loss to cout. From your pasted code, I can see that wins and losses are ofstream objects, which means you are probably seeing addresses there. I would advise you to choose more informative variable names to avoid hard to spot mistakes like this.

How do I make something happen on the screen even without a key being pressed?

I am making Pacman in C++ with the Ncurses library. I am able to move Pacman with my code, but I want to move it so that pacman keeps moving even when I am not pressing any key and when I press another direction key, it changes direction. Right now, the pacman only takes one step when I press a key. Also I have to press a key 2 or 3 times before pacman moves in that direction.
if (ch==KEY_LEFT)
{
int b,row,column;
getyx(stdscr,row,column);
int h;
do // do-whileloop to move the pacman left until it hits the wall
{
column-=1;
mvprintw(row,column,">"); //print the ">" symbol
refresh();
waitf(0.1); //this pauses the game for 0.1sec
attron(COLOR_PAIR(1));
mvprintw(row,column,">");
attroff(COLOR_PAIR(1));
refresh();
waitf(0.1);
mvprintw(row,(b),"O"); //showing the open mouth of pacman
refresh();
waitf(0.1);
attron(COLOR_PAIR(1));a
mvprintw(row,column,"O");
attroff(COLOR_PAIR(1));
h = getch();
}
while(h == KEY_LEFT);
}
right = getch();
loop to move right in an if condition
up = getch();
loop to move up in an if condition
down = getch();
oop for moving down in an if condition.
The standard solution to this is the finite-state machine. The character has six or so possible states: standing, moving up, moving right, moving down, moving left, dead. Rather than a keypress directly moving the character, the keypress should change the character's state.
In such a small application, rather than implementing an incredibly flexible finite-state machine, you may use a very simple implementation as such:
enum PlayerState {
Standing,
MovingUp,
MovingRight,
MovingDown,
MovingLeft,
Dead
};
Then, inside your game loop you can add a very simple state check which then takes the appropriate action for the frame.
switch(state) {
case Standing:
break;
case MovingUp:
player.PositionY += 1;
break;
// ...
}
The last step is to hook input, which depends on your method of retrieving input. Using callbacks, an example is:
void KeyDown(Key k) {
switch(k) {
case UpArrow:
if(state != Dead)
state = MovingUp;
break;
case RightArrow:
if(state != Dead)
state = MovingRight;
// ...
}
}
You can see why in a larger project it would be important to implement a more flexible finite-state machine, but hopefully this example has given you an easy-to-understand idea.
You need an equivalent of kbhit, ie. a non-blocking getch. Which really gives the solution, set O_NONBLOCK on the input. See an example here. Once you have this, simply loop contiguously and just check for the key hit, w/o waiting on actual key press.
Function getch is blocked until some key is pressed. If you don't want to be blocked then call _kbhit before getch too make sure that there is something in input buffer.
EDIT: Take a look at ncurses functions nodelay and cbreak. They enable asynchronous input.
I suggest you take a look at the model-view-controller model, it will help you with this problems and all the other problems that you will have if you continue your program like this.
Edit: shortcut
To move your pacman continuously you will need a separate thread to control it and make it move. Take a look at pthreads for that.
If you keep only the user input in the main run loop of your program, the problem that you have to press the keys a few times will go away too (the problem here is that the processor has to be on the getch() line when you press the key, otherwise it will not be detected.
It is pretty easy
for each direction make 4 function
and inside the function,put in the other 3 direction function which get activated by kbhit.
and put a else statement in which it keeps moving forward if you do not hit a button i.e (!kbhit());
and then put all this in a loop.
If you do this for all the direction functions you should be able to get the desirable outcome.

c++ having strange problem

I have a function that creates and insert some numbers in a vector.
if(Enemy2.dEnemy==true)
{
pt.y=4;
pt.x=90;
pt2.y=4;
pt2.x=125;
for(int i=0; i<6; i++)
{
Enemy2.vS1Enemy.push_back(pt);
Enemy2.vS2Enemy.push_back(pt2);
y-=70;
pt.y=y;
pt2.y=y;
}
Enemy2.dEnemy=false;
Enemy3.cEnemy=0;
}
It should insert 6 numbers in two vectors, the only problem is that it doesn't - it actually inserts more.
I don't think the snippet will run unless Enemy2.dEnemy == true, and it won't stay true for ever.
The first time the snippet runs, then Enemy2.dEnemy is set to false and it shouldn't run again.
I don't set Enemy2.dEnemy to true anywhere except when the window is created.
If I insert a break point any where in the snippet, the program will work fine - it will insert ONLY 6 numbers in the two vectors.
Any ideas what's wrong here?
ok so i did some debugging.
i found that Enemy2.dEnemy=false; is being skipped for some reason.
i tried to do this to see if it was.
if(Enemy2.dEnemy)
{
pt.y=4;
pt.x=90;
pt2.y=4;
pt2.x=125;
for(int i=0; i<6; i++)
{
Enemy2.vS1Enemy.push_back(pt);
Enemy2.vS2Enemy.push_back(pt2);
y-=70;
pt.y=y;
pt2.y=y;
}
TCHAR s[244];
Enemy2.dEnemy=false;
if(Enemy2.dEnemy)
{
MessageBox(hWnd, _T("0"), _T(""), MB_OK);
}
else
{
MessageBox(hWnd, _T("1"), _T(""), MB_OK);
}
Enemy3.cEnemy=0;
}
well the message box popped saying 1 and my code worked fine. it seems that Enemy2.dEnemy=false; doesn't have time to run ;/
blahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblah!
ok i found where is the real problem which was causing to insert more than 6 numbers..
it was where i was asigning Enemy2.dEnemy=true;
if(Enemy2.e1)
{
Enemy2.now=time(NULL);
Enemy2.tEnemy=Enemy2.now+4;
Enemy2.e1=false;
}
if(Enemy2.tEnemy==time(NULL))
{
check=1;
Enemy2.aEnemy=0;
Enemy2.dEnemy=true;
}
the problem seems that the second if runs more than one time, which is weird!
First things first: get rid of that abominable if (Enemy2.dEnemy == true) - it should be:
if (Enemy2.dEnemy)
(I also prefer to name my booleans as a readable sentence segments like Enemy2.isABerserker or Enemy3.hasHadLeftLegCutOffThreeInchesBelowTheKnee but that's just personal preference).
Other than that, the only thing I can suggest is a threading problem. There's nothing wrong with that code per se, but there is a window in which two threads could enter the if statement and both start pushing values into your vector.
In other words, if thread 1 is doing the pushing when thread 2 encounters the if statement, thread 2 will also start pushing values, since thread 1 has yet to set dEnemy to true. And don't think you can just move the assignment to the top of the if block - that will reduce but not remove the window.
My advice is to print out the contents of the vectors in the situation where they have more than six entries and that may give a clue as to what's happened (post the output here if you wish).
Re your update that the second if below is running twice:
if(Enemy2.e1)
{
Enemy2.now=time(NULL);
Enemy2.tEnemy=Enemy2.now+4;
Enemy2.e1=false;
}
if(Enemy2.tEnemy==time(NULL))
{
check=1;
Enemy2.aEnemy=0;
Enemy2.dEnemy=true;
}
If this code is executed twice in the same second (and that's not beyond the bounds of possibility), the second if statement will run twice.
That's because time(NULL) give you the number of seconds since the epoch so, until that second is over, you may well be executing the contents of that if thousands of times (or more).
If this problem disappears when you put in a breakpoint or a diagnostic output message, that's a strong clue that the problem is undefined behavior, which is usually caused by something like dereferencing an uninitialized pointer or careless use of const_cast.
The cause of the problem probably has nothing to do with the code you're looking at. It's caused somewhere else and just happens to show up here. It's like someone being hit by a falling brick: the obvious symptom is a man lying unconscious on the sidewalk, but the real problem has nothing to do with the man or the sidewalk, it's several stories up.
If you want to find the cause of the error, remove your diagnostics until the problem reappears, then start removing everything else. Prune away all of the other code. Whenever the error stops, back up until it starts again; if you don't see the cause of the error, start pruning somewhere else. Eventually the bug will have nowhere to hide.