Nested Iteration Statements


The loop body of any iteration statement can consist of one or more statements. Because each iteration statement is a statement in itself, it can be nested inside the loop body of another iteration statement. An infinite number of iteration statements can be nested inside each other.

A nested loop consists of one loop (called an inner loop) residing inside another loop (called an outer loop).

Every time the outer loop executes its loop body once, the inner loop executes all of its loops. To illustrate this process, let's first have a look at an example containing only a single for loop and no nested loops yet. In a moment, we will expand this example with a nested for loop. Our first modest aim here is to construct a program that prints out five stars along a vertical line onscreen. Because a line is only one dimensional, the program is called StarsOneDimension.cs; it is displayed in Listing 9.10.

Listing 9.10 StarsOneDimension.cs
01: using System; 02: 03: class StarsOneDimension 04: { 05:     public static void Main() 06:     { 07:         for (int i = 0; i < 5; i++) 08:         { 09:             Console.Write("*"); 10:             Console.WriteLine(); 11:         } 12:     } 13: } * * * * * 

The loop body of the for loop is repeated five times. During each loop, a star (*) is printed on the console (line 9) and the cursor moved to the next line (line 10).

Our next goal is slightly more ambitious. We still want to write out 5 lines, but this time each line must contain seven stars instead of one. This, in effect, creates a picture of 5 x 7 stars in two dimensions. The picture is created by a program suitably called StarsTwoDimensions.cs displayed in Listing 9.11.

Listing 9.11 StarsTwoDimensions.cs
01: using System; 02: 03: class StarsTwoDimensions 04: { 05:     public static void Main() 06:     { 07:         for (int i = 0; i < 5; i++) 08:         { 09:             for (int j = 0; j < 7; j++) 10:             { 11:                 Console.Write("*"); 12:             } 13:             Console.WriteLine(); 14:         } 15:     } 16: } ******* ******* ******* ******* ******* 

The problem we achieve to solve can be expressed through pseudocode consisting of an outer and an inner loop:


To express the logic of the pseudocode in C#, we exchange line 9 of Listing 9.10, which merely printed out one star, with a statement that prints out seven stars next to each other. This one statement is here in the form of a for statement spanning lines 9 12 and repeating itself seven times.

Listing 9.11 prints in two dimensions. Had we inserted another for statement inside the inner for statement, and had the console been equipped with 3D image technology, we could have printed in three dimension. In the next chapters, we will look at how arrays of three dimensions can be traversed using this same idea of three nested loop statements inside each other.

Case Study: The Letter Guessing Game

The following case study explores how two do-while statements, one nested inside the other, can be utilized to create a letter guessing game.

Software specification:

The object of the Guess Two Letters game is to let the user guess a sequence of two letters randomly selected by the computer program from the four letters A, B, C, and D. Repeat letters are permitted.

The user starts by entering two letters. The program compares this guess with its secret combination and responds by providing two numbers that evaluates the guess:

  • The first number indicates how many letters of the guess were the correct letter and the correct position. This number is called CC.

  • The second number indicates how many letters were the correct letter but wrong position. This number is called CW.

The user then enters another combination of letters, triggering another response. This sequence of events is repeated until the user has worked out the correct sequence of letters.

The following is an example:

Secret combination generated by program: BD

Guess Response Comment
AB 0 1 B is correct letter but wrong position
BC 1 0 B is correct letter and correct position
DB 0 2 Both letters are correct but wrong position
BD 2 0 Both letters are correct and in correct positions

The user found the correct combination using four guesses.

The program we aim to design must be able to play the Guess Two Letters game and provide the same type of output as just shown. Further, the program must provide a suitable comment related to how many guesses it took the user to guess the combination. For example, if less than 8 guesses were used, write Well Done! In the case of 8 or more guesses, write Finally!. And lastly, whenever a game is over, the program must let the user choose whether he or she wants to terminate the program or continue with yet another game. Then, the game can be played repeatedly until the user decides to quit the program.

Software design:

Only one algorithm belonging to the Main() method is needed in this program, rendering the class and method identification stages of the software development process superfluous. As a result, we will jump straight to the internal method design of the Main() method.

Internal method design:

Observe that the word repeated is mentioned twice in the previous software specification, indicating a need for two loops. In fact, we need an outer loop repeating a whole game and its inner loop repeating the guess-response events. The overall algorithm is described with pseudocode in Listing 9.12. I chose exit condition do-while loops over the entry condition while and for loops because both the inner and outer loops require user input to evaluate its loop's condition, calling for a minimum of one execution of the loop body, as shown previously in Listing 9.3.

Listing 9.12 The Fundamental Pseudocode Behind Listing 9.13
01: do 02: { 03:     generate secret combination 04:     do 05:     { 06:         let user enter guess 07:         compare guess with secret combination 08:         provide feedback about the guess 09:         increment guess counter by one 10:     } while guess is wrong 11:     print the total number of guesses entered by user plus a fitting comment 12:     determine if user wants to play another game 13: } while user still wants to play another game 

The C# source code corresponding to the pseudocode of Listing 9.12 is shown in Listing 9.13.

Listing 9.13 GuessTwoLetters.cs
01: using System; 02: 03: class GuessTwoLetters 04: { 05:     public static void Main() 06:     { 07:         string letterCode; 08:         string letterGuess; 09:         string letters = "ABCD"; 10:         int ccCounter; 11:         int cwCounter; 12:         int guessCounter = 0; 13:         string anotherGame; 14:         Random Randomizer = new Random(); 15:         do 16:         { 17:             guessCounter = 0; 18:             letterCode = letters[Randomizer.Next(0,4)].ToString() + 19:                          letters[Randomizer.Next(0,4)].ToString(); 20:             Console.WriteLine("\nChoose two of the four letters A, B, C, D\n" + 21:                 "CC: Correct letter Correct position\n" + 22:                 "CW: Correct letter Wrong position\n" + 23:                 "Please enter letter guesses\n\n" + 24:                 "   CC CW"); 25:             do 26:             { 27:                 ccCounter = 0; 28:                 cwCounter = 0; 29:                 letterGuess = Console.ReadLine().ToUpper(); 30:                  // Determine how many positions of the guess contains a 31:                  // correct letter in a correct position (CC's) 32:                 if(letterGuess[0] == letterCode[0]) 33:                     ccCounter++; 34:                 if(letterGuess[1] == letterCode[1]) 35:                     ccCounter++; 36:                  // If no CC's were found determine how many positions 37:                  // of the guess contains a correct letter but incorrect position 38:                 if(ccCounter == 0) 39:                 { 40:                     if(letterGuess[0] == letterCode[1]) 41:                         cwCounter++; 42:                     if(letterGuess[1] == letterCode[0]) 43:                         cwCounter++; 44:                 } 45:                 Console.WriteLine("   {0}   {1}  ", ccCounter, cwCounter + "\n"); 46:                 guessCounter++; 47:             } while (letterCode != letterGuess); 48:              // Use conditional operator to provide suitable comment 49:             Console.WriteLine((guessCounter < 8) ? "Well done! " : "Finally! "); 50:             Console.WriteLine("You guessed the code in {0}  guesses", guessCounter); 51:             Console.WriteLine("\nDo you wish to play another game? Y(es) N(o)"); 52:             anotherGame = Console.ReadLine().ToUpper(); 53:         } while (anotherGame == "Y" || anotherGame == "YES"); 54:          Console.WriteLine("Great playing with you. Hope you had fun!"); 55:     } 56: } Choose two of the four letters A, B, C, D CC: Correct letter Correct position CW: Correct letter Wrong position Please enter letter guesses    CC CW AB<enter>    0  0 CD<enter>    1  0 CC<enter>    2  0 Well done! You guessed the code in 3 guesses Do you wish to play another game? Y(es)  N(o) N<enter> Great playing with you. Hope you had fun! 

The overall structure of Listing 9.13 can perhaps best be understood by relating it to the pseudocode, which has been done in Table 9.3.

Table 9.3. The Pseudocode and Its Corresponding C# Line Numbers
Line numbers: Pseudocode Line numbers C# source code
01 13: Outer loop 15 53
04 10: Inner loop 25 47
03: Generate secret combination 18, 19
06: Let the user enter guess 29
07: Compare guess with secret combination 30 44
08: Provide feedback about quality of guess 45
09: Increment guess counter by one 46
11: Print total number of guesses 49 50
12: Determine if user wants to play again 51 52

The important goal of this code is to demonstrate the use of two nested do-while loops. However, there are a few other points worth noticing

  • Randomly generating the secret letter combination Because we are restricted to the four letters A, B, C, and D, the program declares a string type variable called letters made up of these four letters (see line 9). By choosing a number randomly between 0 and 3, through the Randomizer.Next(0, 4) command, and by using this number to select an index of letters as in letters[Randomizer.Next(0,4)] (see lines 18 and 19), we are, in effect, generating a random value of type char that might be any of the four given letters. Because we want to combine this value with another randomly created letter to finally create a string of two letters, we need to turn the value of type char into a value of type string. This is done by applying the built-in ToString() method with the dot operator to form letters[Randomizer.Next(0,4)].ToString(). Finally, the program combines the two randomly created strings with the concatenation operator +. The end result is assigned to letterCode.

    • Comparing letterGuess with letterCode

    • Determining the number of correct letters in correct positions (lines 32 35).

      If the first letter of the letterGuess is a correct letter in a correct position, it must be true that the letter at index 0 of letterGuess is equal to the letter at index 0 of letterCode, or more succinctly letterGuess[0] == letterCode[0]. Thus, if this is true, ccCounter is incremented by one (see line 33). Exactly the same argument holds for the second letter in index 1 (see lines 34 35).

    • Determining the number of correct letters in wrong positions (lines 38 44).

      If the ccCounter is equal to 2 after lines 32 35 have been processed, the guess is obviously correct and the game is over. However, the implications of ccCounter being equal to 1, meaning if just one of the letters in letterGuess is a correct letter in a correct position, is not quite so apparent. In this case, the number of correct letters but wrong position must be zero. Figure 9.12 exemplifies this point.In the first instance, the letterCode is AB and the letterGuess AC. Because there is a perfect match between the two A's, position 0 of letterCode and letterGuess is disregarded in any further analysis. Consequently, we are only left with position 1 in both variables. If the letter in position 1 of letterGuess is the correct letter, it must also be in the correct position. But because ccCounter is only equal to one, it must be an incorrect letter altogether.

      Figure 9.12. When one letter is a correct letter and the correct position.

      What if the second guess is an A, wouldn't this count as a correct letter, wrong position? No. The second part of Figure 9.12 explains why.

Due to the arguments put forth, the cwCounter can only be greater than zero if the ccCounter is zero. This explains the if statement commencing in line 38 and its corresponding Boolean expression, which ensures that ccCounter is equal to zero before beginning the analysis of correct letters but incorrect positions.

Printing appropriate comment at end of game related to total number of guesses.

If the user needs more than seven guesses to find the correct letterCode, the program will write Finally! as an additional comment. Less than 8 guesses are saluted by the more encouraging Well done!.

The guessCounter is incremented by one in line 46 for every new guess. When line 49 is executed, a game has just been finished and guessCounter contains the total number of guesses required. Line 49 utilizes the conditional operator ? as an argument to the WriteLine method to print out Well done! if guessCounter is smaller than eight; otherwise, it will print out Finally!.


C# Primer Plus
C Primer Plus (5th Edition)
ISBN: 0672326965
EAN: 2147483647
Year: 2000
Pages: 286
Authors: Stephen Prata © 2008-2017.
If you may any questions please contact us: