As you’ve learned, loops are mighty, and they are not trivial. That is why all the remaining chapters of the book are dedicated to understanding loops better. Let’s proceed to some more difficult exercises.
Choosing Text
First, you will return to the exercise with text repetition from the previous chapter and improve on it.
Task
In the section “Choosing the Number of Repetitions,” the user was allowed to vary the number of repetitions of a given sentence. Now you will allow the user to vary the sentence itself (see Figure 21-1).
Figure 21-1 Varying a sentence
Solution
Here’s the code:
static void Main(string[] args)
{
// Inputs
Console.Write("Enter text to repeat: ");
string textToRepeat = Console.ReadLine();
Console.Write("Enter number of repetitions: ");
string input = Console.ReadLine();
int howManyTimes = Convert.ToInt32(input);
// Output
for (int count = 0; count < howManyTimes; count++)
{
Console.WriteLine(textToRepeat);
}
// Waiting for Enter
Console.ReadLine();
}
Alternating Loop
Quite frequently, you need to repeat a couple of activities. You do the first thing, then the second one, and the first one again, and so on. It is interesting to look at such a task in code. I will show you three ways of how to solve this.
Task
You will write a program that alternates between two tasks in a to-do list (see Figure 21-2).
Figure 21-2 Alternating between two tasks
First Solution
The first solution is based on distinguishing whether the loop’s control variable, which is running from 1 to 10, is odd or even. When it is odd, you display “Learning.” When it is even, you display “Dating.”
An odd/even test will be performed by checking the remainder after integer division by 2. Just to remind you, the remainder is calculated using the percent sign (%) operator in C#.
static void Main(string[] args)
{
// Output
Console.WriteLine("My main to-do list:");
for (int taskNumber = 1; taskNumber <= 10; taskNumber++)
{
string taskText = taskNumber % 2 != 0 ? "Learning" : "Dating";
Console.WriteLine(taskNumber.ToString() + ". " + taskText);
}
// Waiting for Enter
Console.ReadLine();
}
Note
You incorporate the odd/even test into a conditional (ternary) operator (?:). You could have also used an ordinary if-else.
Second Solution
The second solution toggles a Boolean value back and forth.
You have a bool-typed variable that you toggle from true to false, and vice versa, in every turn of a loop. When the variable equals to true, you display the first text. When it is false, you display the second one.
static void Main(string[] args)
{
// Preparations
Console.WriteLine("My main to-do list:");
bool learning = true;
for (int taskNumber = 1; taskNumber <= 10; taskNumber++)
{
// Output
string taskText = learning ? "Learning" : "Dating";
Console.WriteLine(taskNumber.ToString() + ". " + taskText);
// Toggling of the flag
learning = !learning;
}
// Waiting for Enter
Console.ReadLine();
}
Notes
Note the following:
The condition does not have to be entered as learning == true. The learning variable is already bool-typed, which means you can use it directly as a condition. When it is true, the condition holds.
You need to set the initial value of the variable before entering the loop. The initial value is used during the first turn of the loop. In this case, you set it to true.
Toggling from true to false, and vice versa, is performed using the negation operator (!).
Third Solution
The third approach to the solution is to repeat the loop five times rather than ten times and to perform both “odd activity” and “even activity” in a single turn of the loop.
Here’s the code:
static void Main(string[] args)
{
// Preparations
Console.WriteLine("My main to-do list:");
int taskNumber = 1;
for (int coupleCount = 0; coupleCount < 5; coupleCount++)
{
// Couple output and adjusting task number
Console.WriteLine(taskNumber.ToString() + ". Learning");
taskNumber++;
Console.WriteLine(taskNumber.ToString() + ". Dating");
taskNumber++;
}
// Waiting for Enter
Console.ReadLine();
}
Rock-Scissors-Paper
In the next exercise, you will see the for loop with many statements inside its body. The looping will represent individual rounds of a game.
Task
You will write a program that plays a specified number of rounds of the rock-scissors-paper game with the user (see Figure 21-3).
Figure 21-3 The game
Scoring will be similar to chess: one point for a victory and half a point for a tie.
Solution
Here’s the code:
static void Main(string[] args)
{
// Preparations
Random randomNumbers = new Random();
double playerPoints = 0;
double computerPoints = 0;
int rock = 1, scissors = 2, paper = 3;
// Inputs
Console.Write("Enter your name: ");
string playerName = Console.ReadLine();
Console.Write("Enter number of game rounds: ");
string input = Console.ReadLine();
int totalRounds = Convert.ToInt32(input);
Console.WriteLine();
// Individual rounds
for (int roundNumber = 0; roundNumber < totalRounds; roundNumber++)
{
// Computer chooses
int computerChoice = randomNumbers.Next(1, 3 + 1);
// Player chooses
Console.Write("Enter R or S or P: ");
string playerInput = Console.ReadLine();
string playerInputUppercase = playerInput.ToUpper();
int playerChoice = playerInputUppercase == "R" ?
rock : (playerInputUppercase == "S" ? scissors : paper);
// Round evaluation
string message = "";
if (computerChoice == rock && playerChoice == scissors ||
computerChoice == scissors && playerChoice == paper ||
computerChoice == paper && playerChoice == rock)
{
// Computer won
computerPoints += 1;
message = "I won";
}
else
{
// Tie or player won
if (computerChoice == playerChoice)
{
// Tie
computerPoints += 0.5;
playerPoints += 0.5;
message = "Tie";
}
else
{
// Player won
playerPoints += 1;
message = "You won";
}
}
// Round output
string playerChoiceInText = playerChoice == rock ?
"Rock" : (playerChoice == scissors ? "Scissors" : "Paper");
string computerChoiceInText = computerChoice == rock ?
"Rock" : (computerChoice == scissors ? "Scissors" : "Paper");
Console.WriteLine(playerName + ":Computer - " +
playerChoiceInText + ":" + computerChoiceInText);
Console.WriteLine(message);
Console.WriteLine();
} // End of loop for game round
// Game evaluation
Console.WriteLine("GAME OVER - OVERALL RESULT");
Console.WriteLine(playerName + ":Computer - " +
playerPoints.ToString() + ":" + computerPoints.ToString());
// Waiting for Enter
Console.ReadLine();
}
Discussion
Note the following:
The computer “chooses” using random numbers: 1 for rock, 2 for scissors, and 3 for paper.
For the sake of simplicity, when the user enters something other than R, S, or P, you take it as “paper.”
You do not distinguish between lowercase and uppercase in user input.
In several places, threefold branching is solved using two nested conditional (ternary) operators rather than using two nested if-elses. Note carefully how noValue of the first conditional operator is specified using another conditional operator, which is enclosed in parentheses.
If you do not like the conditional (ternary) operator, simply do not use it. It is just a shortcut of a special if-else case. I personally like it very much, so I use it frequently.
Summary
In this chapter, you continued your study of the loops. The first exercise was basically a reminder of what you learned in the previous chapter. You modified one of the previous tasks.
Next you were exposed to several ways of solving alternating loops, i.e., loops repeating similar pairs of activities. Specifically, you studied the following solutions:
Alternating output based on whether the control variable is odd or even
Toggling a bool variable indicating whether you want the first output or not
Performing both activities of the pair in a single turn of the loop
The final example of the rock-scissors-paper game was actually not centered on looping. The loop was just the means to repeat the game rounds. One game round was an example of a real, more complex procedure that you could make with what you have learned in this book so far.