C++ Repetition

Thu Sep 18 2025
Updated: Tue Sep 23 2025
Facebook share linkTwitter/X share linkLinkedIn share linkReddit share linkReddit share link

Introduction

Repetition (also called looping) is a type of control structure that allows a block of code to be executed multiple times. The block of statements executed each time the loop iterates is called the loop body, and a single execution of the loop body is called an iteration of the loop. Repetition is used to automate repeated work, process collections, and react to ongoing conditions.

In C++ there are 3 simple repetition structures:

  • While Loops: Useful when a loop body needs to be run 0 or more times, but the amount of times is unknown.
  • Do...While Loops: Useful when a loop body needs to be run at least once to an unknown amount of times.
  • For Loops: Useful when the amount of times a loop body needs to be run is known.

Increment and Decrement

Many loops may need to keep track of what iteration number they are at in the execution cycle. This is done manually in C++ using a counter variable that increments or decrements through the cycle count. Take for example the following snippet of code which increments a variable similar to how a variable will be incremented when keeping track of loop execution counts:

int count = 0; count = count + 1;

The variable count is first initialized to 0. Then, for the arithmetic count + 1 takes precedence in the order of operations, thus the original value of count, which is 0, will have 1 added to it resulting in 1. This 1 is then stored into the count variable overriding the original value of 0 that was inside of it. This effectively increments the value in count by 1, and if a further increment is needed 1 can just be added to count to increment the value to 2 (and to decrement the value 1 just needs to be subtracted).

Since this is so common in programming and loops in general, most programming languages have increment and decrement operators built in that increment or decrement integer variables by 1. In C++ there are 2 increment and 2 decrement operators, but for now only 1 of each will be focused on:

NameOperatorMeaningNotes
Post-Incrementv++v = v + 1Increases an integer variable by 1
Post-Decrementv–-v = v - 1Decreases an integer variable by 1

So if a variable is initialized to 0 and the increment operator is then used on the variable:

int count = 0; count++;

Then count will now have 1 in it since the line count++ replaces count = count + 1. To decrement the count to -1 after initializing it to 0:

int count = 0; count--;

While Loop

Recall the simple one-way selection statement:

if (expression) { // code to run when expression is true }

Which only runs a block of code if a boolean expression is true, otherwise the block of code is skipped over. Then in both cases, when the selection is over any code after the block is run (if the block of code does not divert execution elsewhere or terminate the program). When the if is changed to while the selection statement becomes a while loop:

while (expression) { // body -- code to run when expression is true }

Which is similar to the if statement where the block of code is executed if the expression is true. But this time when the block of code, or the loop body, finishes executing the expression is reevaluated, and if it is true then the body is executed again. This causes the loop body to continue to be run over and over again until the expression is false. This expression is known as a loop condition which is a boolean expression checked by a loop to determine whether to execute another iteration.

Since the loop condition jurisdicts whether the loop continues executing or not it must be updated within the block of code, otherwise the loop will run forever. This is called an infinite loop or a loop that executes without terminating because its loop condition is always true. Loop conditions are updated by updating loop control variables--variables whose value determines whether a loop should execute another iteration or not. Loop control variables can be of any type they just must:

  1. Be initialized prior to the loop executing

  2. Be compared in the loop condition to determine if the loop should continue executing.

  3. Be updated inside of the loop body.

For example the a variable can be initialized, and used as a loop control variable:

int lcv = 0; while (lcv < 5) { cout << lcv << “ “; } cout << endl;

Here the loop control variable lcv is set to 0 and then is compared in the expression lcv < 5 to make the loop body execute as long as the value in lcv is less than 5. But this program will just continuously output the value 1 over and over again as the loop control variable is never being updated. To get the loop to output the values from 0 to 4 the loop control variable must be incremented by 1 each time, this way each iteration of the loop the value in the loop control variable that is to be output is only 1 more than the previous iteration.

int lcv = 0; while (lcv < 5) { cout << lcv << “ “; lcv++; } cout << endl;

Now, since lcv is being updated at the end of the loop the first iteration will output 0 followed by the second outputting 1 all the way through 4 being output. Once the value is incremented to 5 the expression lcv < 5 becomes false so the loop finishes executing and the endl gets output. This causes ”0 1 2 3 4\n” to be output to the screen.


Example: PIN Entry

Write a program that accepts characters and concatenates them into a PIN until the # key is entered.

First a loop will be set up with the the variable that will hold the characters being entered as the loop control variable:

#include <iostream> using namespace std; int main() { // variables char input = 0; // loop until # is entered while (input != ‘#’) { } return 0; }

The loop control variable input is checked to see if it contains the value ’#’ and if it does then the loop will stop executing, otherwise the loop will continue execution. As the loop executes it needs to do 2 things:

  1. Get a character from the user.

  2. Concatenate the character onto a string holding the rest of the characters entered.

To do this the user can be prompted for a character, then a character read in and concatenated into a string representing the PIN:

#include <iostream> using namespace std; int main() { // variables char input = 0; string pin = “”; // loop until # is entered while (input != ‘#’) { // get next character in pin cout << “Next char in PIN:; cin >> input; // concatenate character onto pin pin += input; } // output entered pin cout << “Your pin is:<< pin << endl; return 0; }

The string pin is initialized to the empty string so when the first character is entered then concatenated it is the only character in the string. Then when subsequent characters are entered they are contented after the previous characters so the characters appear in the string in the order they were entered. There is a problem with how the characters are being concatenated though. When # is entered it is also concatenated to the string so it is included in the pin:

Next char in PIN: 3 Next char in PIN: 8 Next char in PIN: x Next char in PIN: 9 Next char in PIN: # Your pin is: 38x9#

To fix this a one-way selection can be used that makes it so the character only gets concatenated if it is not the pound key (which is used just to terminate the loop):

#include <iostream> using namespace std; int main() { // variables char input = 0; string pin = “”; // loop until # is entered while (input != ‘#’) { // get next character in pin cout << “Next char in PIN:; cin >> input; // concatenate character onto pin if it is not # if (input != ‘#’) { pin += input; } } // output entered pin cout << “Your pin is:<< pin << endl; return 0; }

Now when the user enters their pin followed by the pound only the valid characters of the pin are added to the string:

Next char in PIN: 3 Next char in PIN: 8 Next char in PIN: x Next char in PIN: 9 Next char in PIN: # Your pin is: 38x9

A while loop works very well with this example since it is unknown how many characters will be part of the pin, and every time the loop runs the amount of characters in the pin could be different. The pin always needs at least one character in it though, so a better loop to use for this would be a do...while loop.


Do...While Loop

The do...while loop is used when a while loop is needed, but the loop must be executed at least one time. The syntax of the do...while loop is as follows:

do { // code to run when expression is true } while (expression);

The loop body now comes before the expression being checked by the while, thus the body will be run prior to the expression being checked since the program is being read top to bottom/left to right. This guarantees at least one execution of the loop body regardless of the value of the expression.

Going back to the PIN Entry example, a do...while loop could be used instead of a while loop, since at least one character must be read for the pin:

#include <iostream> using namespace std; int main() { // variables char input = 0; string pin = “”; // loop until # is entered do { // get next character in pin cout << “Next char in PIN:; cin >> input; // concatenate character onto pin if it is not # if (input != ‘#’) { pin += input; } } while (input != ‘#’); // output entered pin cout << “Your pin is:<< pin << endl; return 0; }

Now the loop will get a character from the user regardless of the value of input != ‘#’, so even if the initial value of input is ‘#’ the loop will execute.


Example: Validating Input

Validate an input read from the input stream before continuing execution with a program.

Consider the following program:

#include <iostream> using namespace std; int main() { // variables int input = 0; // get a whole number cout << “Whole Number:; cin >> input; // validate a number was entered if (cin.fail()) { cout << “Invalid number\n”; return 0; } // output entered number cout << “You entered:<< input << endl; return 0; }

The selection forces the user to actually enter a number otherwise the program outputs an error and terminates. It is not practical to just terminate the program. It is much more practical to reset the failure then retry getting the input again. This can be done with a loop, which first let’s look at using a while loop:

#include <iostream> using namespace std; int main() { // variables int input = 0; // get a whole number cout << “Whole Number:; cin >> input; while (cin.fail()) { // output error cout << “Invalid number\n”; // retry getting a whole number cout << “Whole Number:; cin >> input; } // output entered number cout << “You entered:<< input << endl; return 0; }

The if is replaced with a while and the return 0 with a second reading of the input. To use a while loop the input had to be read in using a secondary prompt/read of the input just for the error state. It would be much more readable to be able to utilize the same prompt/input that originally failed. To do this let’s instead use a do...while loop:

#include <iostream> using namespace std; int main() { // variables int input = 0; do { // get a whole number cout << “Whole Number:; cin >> input; // validate input if (cin.fail()) { cout << “Invalid number\n”; } } while (cin.fail()); // output entered number cout << “You entered:<< input << endl; return 0; }

Now, if the user enters a value that is not a number cin.fail() will be true causing the program will output “Invalid number”, then when the function body is complete cin.fail() will still be true so the function body will be run again and the user prompted for another input. But if this program is run and any invalid number is entered it will just infinitely loop:

iMac % ./a.out Whole Number: error Invalid number Whole Number: Invalid number Whole Number: Invalid number Whole Number: Invalid number ...

This is because of 2 issues:

  1. The input stream has fallen into the fail state (cin.fail() == true) so any further inputs will also fail.

    To reset the input stream so it is not in the fail state (cin.fail() == false) use:

    cin.clear()

    This will set cin.fail() from true to false so the input stream is no longer in the fail state.

  2. When the value ”error” is entered it is not able to be placed in the input variable so the value is left in the input stream:

    SHOW VALUE FAILING TO GO INTO VARIABLE/LEFT IN INPUT STREAM

    To discard the failed input input in the input stream use:

    cin.ignore(256, ‘\n’)

    This will ignore 256 characters in the input stream, or if a ’\n’ is found in the input stream prior to 256 characters being ignored the characters up to and including the ’\n’ in the input stream.

So after the input failure has been detected, in order to properly reset the fail state of the input stream the fail state must be reset with cin.clear() and cin.ignore():

#include <iostream> using namespace std; int main() { // variables int input = 0; do { // get a whole number cout << “Whole Number:; cin >> input; // validate input if (cin.fail()) { cout << “Invalid number\n”; cin.clear(); cin.ignore(256, ‘\n’); } } while (cin.fail()); // output entered number cout << “You entered:<< input << endl; return 0; }

But this still is not without error. If the program is run and ”error” is entered the following interaction is produced:

iMac % ./a.out Whole Number: error Invalid number You entered: 0

This is because in the code the same check, cin.fail() is used as both the condition for input failure and the loop condition. When ”error” is entered cin.fail() becomes true so the one-way selection executes, which has a cin.clear() which resets cin.fail() from true to false. So when the code gets down to while (cin.fail()) the value of cin.fail() is false so the loop stops executing and You entered: 0 is output.

The simplest fix to this is to move the input failure check above the input of the number:

#include <iostream> using namespace std; int main() { // variables int input = 0; do { // validate input -- only will be true after input has been read first time if (cin.fail()) { cout << “Invalid number\n”; cin.clear(); cin.ignore(256, ‘\n’); } // get a whole number cout << “Whole Number:; cin >> input; } while (cin.fail()); // output entered number cout << “You entered:<< input << endl; return 0; }

This works because initially the input stream is not in the fail state, so cin.fail() is false when the program first enters the loop body and the resetting of the fail state is skipped over and input is prompted for/read in. If the value entered is not a number then the very next check is whether to loop or not through while (cin.fail()), which cin.fail() will be true if input failure just occurred so the loop body will be executed again. This time cin.fail() will be true which causes the one-way selection to run, resetting the input stream from the failed state. The user is then prompted for new input once the fail state has been reset which will be validated with the same input failure logic.

An interaction with this program follows:

iMac % ./a.out Whole Number: error Invalid number Whole Number: whoops Invalid number Whole Number: 10 You entered : 10

Now any amount of invalid numbers can be entered, but once a valid number is entered cin.fail() becomes true and the program continues on with execution of the later instructions.


For Loop

The for loop is used when it is known how many times to loop. The syntax of the for loop is as follows:

for (expression1; expression2; expression3) { // code to run when expression is true }

The for loop takes 3 expressions:

  1. expression1 - Which is run only 1 time prior to the loop ever executing. This expression is generally used to initialize a loop control variable to some value.

  2. expression2 - Which is the loop condition that determines if the loop body should be executed, or if the loop should stop executing. This expression is checked prior to each iteration of the loop.

  3. expression3 - Which is run after every iteration of the loop. This expression is generally used to update the loop control variable to a new value after the loop has executed.

So in general, the expressions are run:

GRAPHIC OF EXPRESSIONS BEING WORKED IN ORDER


Example: Is There Enough Time to Ride?

Let’s say on average a theme parkgoer gets on 5 rides in a day. Create a program that reads in the wait time for 5 rides, then outputs if the parkgoer will be able to get on exactly the 5 rides an average person would get on, less than the 5 rides, or more than the 5 rides. The theme park is open for 5 hours (300 minutes) each day.

First, since exactly 5 wait times need to be read it is known exactly how many times to loop. Since this is the case a for loop will be used to read in 5 values:

#include <iostream> using namespace std; int main() { for (int i = 0; i < 5; i++) { } return 0; }

A loop control variable i is first initialized to 0 and will be incremented by 1 after each execution of the loop body using i++. This causes i to go from 0 to 1 to 2 and so on until it is increased to 5 which causes i < 5 to be false which causes the loop to stop executing. This makes the loop run exactly 5 times (i being equivalent to the values 0-4 in the respective iterations of the loop).

During each execution a wait time first needs to be read:

#include <iostream> using namespace std; int main() { // variables int singleWait = 0; for (int i = 0; i < 5; i++) { // get a ride wait cout << “Ride Wait:; cin >> singleWait; } return 0; }

The entered wait time can then be summed into a variable holding the sum of the wait times:

#include <iostream> using namespace std; int main() { // variables int singleWait = 0, totalWait = 0; // constants const int totalTimeOpen = 300; for (int i = 0; i < 5; i++) { // get a ride wait cout << “Ride Wait:; cin >> singleWait; // sum waits together totalWait += singleWait; } return 0; }

The totalWait must be initialized to 0 otherwise it may get a random value from memory which will make the total wait be a random value when displayed. Then during each execution of the loop body the wait time being read in can be summed to the totalWait starting with the first entered wait being added to the initial totalWait of 0, and all subsequent waits being summed to the previous value in totalWait.

Once all 5 wait times have been read in a message can be output depending on whether the parkgoers will have enough time to ride the 5 rides while the park is open or not:

#include <iostream> using namespace std; int main() { // variables int singleWait = 0, totalWait = 0; // constants const int totalTimeOpen = 300; for (int i = 0; i < 5; i++) { // get a ride wait cout << “Ride Wait:; cin >> singleWait; // sum waits together totalWait += singleWait; } if (totalWait < totalTimeOpen) { cout << “You can squeeze in an extra ride with a wait under “ << totalTimeOpen - totalWait << “ minutes\n”; } else if (totalWait > totalTimeOpen) { cout << “You will not be able to ride the average amount of rides\n”; } else { cout << “You will have exactly enough time to ride the rides\n”; } return 0; }

When there’s extra time (totalWait < totalTimeOpen) the parkgoer can ride an extra ride. When there’s not enough time (totalWait > totalTimeOpen) the parkgoer won’t get to ride as many rides as everyone else that chooses rides with shorter waits. When there’s exactly enough time to wait (else -or- totalWait == totalTimeOpen) the parkgoer gets to ride exactly as many rides as expected. Although this is not actually true in a practical park setting since the rides take time, getting to rides takes time, food, rest, etc. it all takes time. But these factors can be implemented as an at home exercise.


Nesting

Like selection structures repetition structures can be nested in one another, as well as selections in repetitions and repetitions in selections (as some examples have already shown). For example, the program for getting 5 ride wait times has a numerical input, which can have input failure. The input:

cout << “Ride Wait:; cin >> singleWait;

Can be verified to be a number using the loop:

do { if (cin.fail()) { cout << “Error: Invalid number\n”; cin.clear(); cin.ignore(256, ‘\n’); } cout << “Ride Wait:; cin >> singleWait; } while (cin.fail());

Which a wait time can not be negative (unless time machines get invented) so verifying the number is not negative could also be added to this loop:

do { if (cin.fail()) { cout << “Error: Invalid number\n”; cin.clear(); cin.ignore(256, ‘\n’); } else if (singleWait < 0) { cout << “Error: Can’t have a negative wait\n”; } cout << “Ride Wait:; cin >> singleWait; } while (cin.fail() || singleWait < 0);

This loop can be nested in the for loop and regarded as a single statement where a valid wait time is read in:

#include <iostream> using namespace std; int main() { // variables int singleWait = 0, totalWait = 0; // constants const int totalTimeOpen = 300; for (int i = 0; i < 5; i++) { // get a ride wait do { if (cin.fail()) { cout << “Error: Invalid number\n”; cin.clear(); cin.ignore(256, ‘\n’); } else if (singleWait < 0) { cout << “Error: Can’t have a negative wait\n”; } cout << “Ride Wait:; cin >> singleWait; } while (cin.fail() || singleWait < 0); // sum waits together totalWait += singleWait; } if (totalWait < totalTimeOpen) { cout << “You can squeeze in an extra ride with a wait under “ << totalTimeOpen - totalWait << “ minutes\n”; } else if (totalWait > totalTimeOpen) { cout << “You will not be able to ride the average amount of rides\n”; } else { cout << “You will have exactly enough time to ride the rides\n”; } return 0; }

Now the user will be prompted for a wait time until a valid number that is not negative is entered. Once a valid wait time is entered it will be summed to the total and the next wait time read in. An interaction with the program entering the first wait time follows:

iMac % ./a.out Ride Wait: error Error: Invalid number Ride Wait: -1 Error: Can’t have a negative wait Ride Wait: 10 Ride Wait: ...

The inner do...while loop executes until a valid number is entered, pausing the execution of the outer for loop until the valid number is entered. Once the valid number is entered the for loop continues execution until it needs to run another iteration.


Break and Continue

Execution of the loop body can be interrupted in two ways:

  1. break - Stop execution of a loop, similar to how break stopped the execution of further switch statements. This ends the current execution of the loop body once the break is executed. Further, the loop ends execution entirely regardless of the value of the loop condition.

  2. continue - Continue on to the next iteration of the loop. This causes execution of the current iteration of the loop to be stopped immediately and the loop condition retested, and only if the loop condition is true rerun the loop body. So if there is any remaining code in the loop body (generally after the nested block of code the continue is in) the code will not be executed if a continue is hit earlier.

    • When continue is used in while and do...while loops the loop condition is immediately tested after a continue statement is executed.

    • When continue is used in for loops the update statement is executed (expression3) and then the loop condition (expression2) is tested immediately after a continue statement is executed.

For example, consider the following program:

#include <iostream> using namespace std; int main() { // variables int value = 0, sum = 0; while(true) { // get value cout << “Enter a positive number:; cin >> value; // only sum if value is positive if (value >= 0) { sum += value; continue; } // stop executing the loop once a negative is entered cout << “A negative was entered, terminating loop\n”; break; } // output the sum of the positive values entered cout << “The sum of the positive values entered is “ << sum << endl; return 0; }

When a positive value is entered the number is added to the value of the sum variable and then stored into the sum variable to be summed to later. The continue is then needed because without it the loop body would continue on to output “A negative was entered, terminating loop\n”. So the continue tells the loop to skip outputting the negative value message and go onto getting another value. Then when a negative value is entered the block of code containing the continue will be skipped over, causing the negative value message to be output and the loop to stop executing because of the break statement.


Example: Player Monster Attack Cycle

Write a program where the user fights a monster by kicking it (dealing 3 damage each kick) or running away. If the player decides to kick the monster then the monster will claw the player back (dealing 3 damage each claw).

First, the player needs to enter whether to kick or run:

#include <iostream> using namespace std; int main() { // variables char attack = 0; // get attack cout << "\n(k)ick -or- (r)un? "; cin >> attack; return 0; }

A character variable attack is used to store a character entered by the user, which is then used to determine if the player kicks (if the player enters k) or runs (if the player enters r):

#include <iostream> using namespace std; int main() { // variables char attack = 0; int monsterHealth = 10, playerHealth = 10; // get attack cout << "\n(k)ick -or- (r)un? "; cin >> attack; // kick if (attack == 'k') { // output message and remove monster’s health cout << "You kick the monster\n"; monsterHealth -= 3; } // run else if (attack == 'r') { // output message cout << "You run from the monster\n\n"; } // invalid attack else { // output error and kill the program cout << "Invalid selection\n"; } return 0; }

When k is entered a message is output and a variable holding the monster's health (which starts at 10) is reduced by the damage of 3. When r is entered a run message is output, and when anything else is entered an invalid entry message is output. The monster can then attack the player back:

#include <iostream> using namespace std; int main() { // variables char attack = 0; int monsterHealth = 10, playerHealth = 10; // get attack cout << "\n(k)ick -or- (r)un? "; cin >> attack; // kick if (attack == 'k') { // output message and remove monster’s health cout << "You kick the monster\n"; monsterHealth -= 3; } // run else if (attack == 'r') { // run! by killing the program cout << "You run from the monster\n\n"; return 0; } // invalid attack else { // output error and kill the program cout << "Invalid selection\n"; return 0; } // output message and remove player’s health cout << "The monster claws you\n\n"; playerHealth--; return 0; }

The monster attacks by simply decrementing the player’s health by 1, but this only can happen in the case k is entered. Thus when r or anything else is entered the program must be terminated early using return 0. This is only 1 attack cycle though, to keep having attack cycles until either the monster or player dies this attack cycle needs to be wrapped in a loop:

#include <iostream> using namespace std; int main() { // variables char attack = 0; int monsterHealth = 10, playerHealth = 10; // fight until one has no health while (monsterHealth > 0 && playerHealth > 0) { // display healths cout << “Monster Health:<< monsterHealth << endl << “Player Health:<< playerHealth << endl; // get attack cout << "\n(k)ick -or- (r)un? "; cin >> attack; // kick if (attack == 'k') { // output message and remove monster’s health cout << "You kick the monster\n"; monsterHealth -= 3; } // run else if (attack == 'r') { // output message and stop attacking (looping) cout << "You run from the monster\n\n"; break; } // invalid attack else { // output error and get new attack cout << "Invalid selection\n"; continue; } // output message and remove player’s health cout << "The monster claws you\n\n"; playerHealth--; } return 0; }

The reason a while loop is used is not apparent here, but there is a case where the monster is already dead and has 0 health. In this case there’s no sense in beating a dead horse so the loop does not need to run in that case (so 0 or more runs of the loop is what a while is for). The while loop runs while either the monster or the user has health, and once either runs out of health it will make one side of the && be false causing the loop to finish executing.

The return 0 inside of run has been changed to break. This is because now rather than kill the program the loop should break out of execution to continue executing the program after the loop. This way in the next steps the program can continue doing things after the player runs from the monster.

The return 0 inside of invalid attack has been changed to continue. When there was no loop killing the program was a simple way to not run any further code once an invalid attack was entered. Now that there is a loop it is better to recover from that failure rather than terminate execution. The only thing needed to recover is to get a new selection so continue causes the program to stop executing the loop body, recheck the loop condition, and rerun the loop body if the loop condition is true. Which if an invalid attack was entered then no health was taken from either the player or the monster so the loop condition will be true again, causing the player to be asked for another attack selection.

The monster and player’s health are also displayed at the beginning of the loop. This way the player can make an informed decision on whether to keep attacking or run.

Lastly, after the fight is over whoever dies needs to be announced:

#include <iostream> using namespace std; int main() { // variables char attack = 0; int monsterHealth = 10, playerHealth = 10; // fight until one has no health while (monsterHealth > 0 && playerHealth > 0) { // display healths cout << “Monster Health:<< monsterHealth << endl << “Player Health:<< playerHealth << endl; // get attack cout << "\n(k)ick -or- (r)un? "; cin >> attack; // kick if (attack == 'k') { // output message and remove monster’s health cout << "You kick the monster\n"; monsterHealth -= 3; } // run else if (attack == 'r') { // output message and stop attacking (looping) cout << "You run from the monster\n\n"; break; } // invalid attack else { // output error and get new attack cout << "Invalid selection\n"; continue; } // output message and remove player’s health cout << "The monster claws you\n\n"; playerHealth--; } // player died if (playerHealth <= 0) { cout << "You died\n"; } // monster died if (monsterHealth <= 0) { cout << "The monster died\n"; } // both live if (playerHealth > 0 && monsterHealth > 0) { cout << “Both the player and monster lived\n”; } return 0; }

If the player dies (which they currently can not) then the player’s death is announced. If the monster dies then the monster’s death is announced. If the player runs prior to killing the monster then both walk away with health and it is announced. The player killing the monster looks like the following:

Monster Health : 10 Player Health : 10 (k)ick -or- (r)un? k You kick the monster The monster claws you Monster Health : 7 Player Health : 9 (k)ick -or- (r)un? k You kick the monster The monster claws you Monster Health : 4 Player Health : 8 (k)ick -or- (r)un? k You kick the monster The monster claws you Monster Health : 1 Player Health : 7 (k)ick -or- (r)un? k You kick the monster The monster claws you The monster died

And the player running away from the monster is similar to the following:

Monster Health : 10 Player Health : 10 (k)ick -or- (r)un? k You kick the monster The monster claws you Monster Health : 7 Player Health : 9 (k)ick -or- (r)un? r You run from the monster Both the player and monster lived

But the player will always kill the monster since the player has a stronger attack, unless the monster can be fought multiple times...


Example: Keep Fighting That Monster

Add the ability to keep fighting the monster until the player wants to quit fighting.

Once the winner has been announced the user can be asked if they want to fight again:

#include <iostream> using namespace std; int main() { // variables char attack = 0; int monsterHealth = 10, playerHealth = 10; // fight until one has no health while (monsterHealth > 0 && playerHealth > 0) { // display healths cout << “Monster Health:<< monsterHealth << endl << “Player Health:<< playerHealth << endl; // get attack cout << "\n(k)ick -or- (r)un? "; cin >> attack; // kick if (attack == 'k') { // output message and remove monster’s health cout << "You kick the monster\n"; monsterHealth -= 3; } // run else if (attack == 'r') { // output message and stop attacking (looping) cout << "You run from the monster\n\n"; break; } // invalid attack else { // output error and get new attack cout << "Invalid selection\n"; continue; } // output message and remove player’s health cout << "The monster claws you\n\n"; playerHealth--; } // player died if (playerHealth <= 0) { cout << "You died\n"; } // monster died if (monsterHealth <= 0) { cout << "The monster died\n"; } // both live if (playerHealth > 0 && monsterHealth > 0) { cout << “Both the player and monster lived\n”; } // see if player wants to fight monster again if (playerHealth > 0) { cout << "(F/f)ight again (any other key to quit)? "; cin >> attack; } return 0; }

If the player has health then they are able to keep fighting so they are asked to fight again, and since the attack variable is done being used it can just be repurposed at this point to see what the player’s choice is. The player can only do this though if they have health, which them not having health can only happen when a loop is added to allow the player to keep fighting:

#include <iostream> using namespace std; int main() { // variables char attack = 0; int monsterHealth = 10, playerHealth = 10; do { // fight until one has no health while (monsterHealth > 0 && playerHealth > 0) { // display healths cout << “Monster Health:<< monsterHealth << endl << “Player Health:<< playerHealth << endl; // get attack cout << "\n(k)ick -or- (r)un? "; cin >> attack; // kick if (attack == 'k') { // output message and remove monster’s health cout << "You kick the monster\n"; monsterHealth -= 3; } // run else if (attack == 'r') { // output message and stop attacking (looping) cout << "You run from the monster\n\n"; break; } // invalid attack else { // output error and get new attack cout << "Invalid selection\n"; continue; } // output message and remove player’s health cout << "The monster claws you\n\n"; playerHealth--; } // player died if (playerHealth <= 0) { cout << "You died\n"; } // monster died if (monsterHealth <= 0) { cout << "The monster died\n"; } // both live if (playerHealth > 0 && monsterHealth > 0) { cout << “Both the player and monster lived\n”; } // see if player wants to fight monster again if (playerHealth >= 0) { cout << "(F/f)ight again (any other key to quit)? "; cin >> attack; } // player is dead and message has already been output, so just end the loop else { break; } // fight again if player has health and is willing } while (attack == 'f' || attack == 'F'); return 0; }

The reason a do...while loop is chosen is because if someone is running this program, they probably want to fight the monster at least one time.

If the player enters f or F it will be stored in attack and checking this in attack == 'f' || attack == 'F' will make the statement true allowing the player to be able to attack again. The attack variable then goes back to being used for its original purpose of holding the attack selection from the user when the loop body runs again. This works since the variable is not needed at this point, and what it is being used for (seeing if the user wants to run again or not) is only needed for these few lines. But there’s a problem when this runs:

Monster Health : 10 Player Health : 10 (k)ick -or- (r)un? k You kick the monster The monster claws you Monster Health : 7 Player Health : 9 (k)ick -or- (r)un? k You kick the monster The monster claws you Monster Health : 4 Player Health : 8 (k)ick -or- (r)un? k You kick the monster The monster claws you Monster Health : 1 Player Health : 7 (k)ick -or- (r)un? k You kick the monster The monster claws you The monster died (F/f)ight again (any other key to quit)? f The monster died (F/f)ight again (any other key to quit)?

The monster just stays dead every time the outer do...while loop iterates again. This is because the monster’s health stays at 0. The monster needs to be revived:

#include <iostream> using namespace std; int main() { // variables char attack = 0; int monsterHealth = 10, playerHealth = 10; do { // revive the monster monsterHealth = 10; // fight until one has no health while (monsterHealth > 0 && playerHealth > 0) { // display healths cout << “Monster Health:<< monsterHealth << endl << “Player Health:<< playerHealth << endl; // get attack cout << "\n(k)ick -or- (r)un? "; cin >> attack; // kick if (attack == 'k') { // output message and remove monster’s health cout << "You kick the monster\n"; monsterHealth -= 3; } // run else if (attack == 'r') { // output message and stop attacking (looping) cout << "You run from the monster\n\n"; break; } // invalid attack else { // output error and get new attack cout << "Invalid selection\n"; continue; } // output message and remove player’s health cout << "The monster claws you\n\n"; playerHealth--; } // player died if (playerHealth <= 0) { cout << "You died\n"; } // monster died if (monsterHealth <= 0) { cout << "The monster died\n"; } // both live if (playerHealth > 0 && monsterHealth > 0) { cout << “Both the player and monster lived\n”; } // see if player wants to fight monster again if (playerHealth >= 0) { cout << "(F/f)ight again (any other key to quit)? "; cin >> attack; } // player is dead and message has already been output, so just end the loop else { break; } // fight again if player has health and is willing } while (attack == 'f' || attack == 'F'); return 0; }

So the monster’s health is simply set back to 10 before the nested while loop (where the fight takes place) runs, which effectively revives the monster. The player can now die after trying to kill the monster a third time:

Monster Health : 10 Player Health : 10 (k)ick -or- (r)un? k You kick the monster The monster claws you Monster Health : 7 Player Health : 9 (k)ick -or- (r)un? k You kick the monster The monster claws you Monster Health : 4 Player Health : 8 (k)ick -or- (r)un? k You kick the monster The monster claws you Monster Health : 1 Player Health : 7 (k)ick -or- (r)un? k You kick the monster The monster claws you The monster died (F/f)ight again (any other key to quit)? F Monster Health : 10 Player Health : 6 (k)ick -or- (r)un? k You kick the monster The monster claws you Monster Health : 7 Player Health : 5 (k)ick -or- (r)un? k You kick the monster The monster claws you Monster Health : 4 Player Health : 4 (k)ick -or- (r)un? k You kick the monster The monster claws you Monster Health : 1 Player Health : 3 (k)ick -or- (r)un? k You kick the monster The monster claws you The monster died (F/f)ight again (any other key to quit)? f Monster Health : 10 Player Health : 2 (k)ick -or- (r)un? k You kick the monster The monster claws you Monster Health : 7 Player Health : 1 (k)ick -or- (r)un? k You kick the monster The monster claws you You died (F/f)ight again (any other key to quit)? f You died

Terms

  1. Repetition - A type of control structure that allows a block of code to be executed multiple times.

  2. Loop Body - The block of statements executed each time the loop iterates.

  3. Iteration of a Loop - a single execution of the loop body.

  4. While Loops - A loop used when a loop body needs to be run 0 or more times, but the amount of times is unknown.

  5. Do...While Loops - A loop used when a loop body needs to be run at least once to an unknown amount of times.

  6. For Loops - A loop used when the amount of times a loop body needs to be run is known.

  7. Post-Increment - Increases an integer variable by 1.

  8. Post-Decrement - Decreases an integer variable by 1.

  9. Loop Control Variable - Variables whose value determines whether a loop should execute another iteration or not.


Questions

To Be Added Later