Making decisions with if and else
The C++ if
and else
keywords are what enable us to make decisions. Actually, we have already seen if
in action in the previous chapter when we detected, in each frame, whether the player had pressed the Esc key:
if (Keyboard::isKeyPressed(Keyboard::Escape)) { window.close(); }
So far we have seen how we can use arithmetic and assignment operators to create expressions. Now we can see some new operators.
Logical operators
Logical operators are going to help us make decisions by building expressions that can be tested for a value of either true or false. At first this might seem like quite a narrow choice and insufficient for the kind of choices that might be needed in an advanced PC game. Once we dig a little deeper, we will see that we can actually make all the required decisions we will need, with just a few logical operators.
Here is a table of the most useful logical operators. Take a look at them and their associated examples, and then we will see how to put them to use.
Let's meet the C++ if
and else
keywords which will enable us to put all these logical operators to good use.
C++ if and else
Let's make the previous examples less abstract. Meet the C++ if
keyword. We will use if
and a few operators along with a small story to demonstrate their use. Next follows a made-up military situation that will hopefully be less abstract than the previous examples.
If they come over the bridge, shoot them!
The captain is dying and, knowing that his remaining subordinates are not very experienced, he decides to write a C++ program to convey his last orders for after he has died. The troops must hold one side of a bridge while awaiting reinforcements.
The first command the captain wants to make sure his troops understand is this:
"If they come over the bridge, shoot them!"
So, how do we simulate this situation in C++? We need a bool
variable: isComingOverBridge
. The next bit of code assumes that the isComingOverBridge
variable has been declared and initialized to either true
or false
.
We can then use if
like this:
if(isComingOverBridge) { // Shoot them }
If the isComingOverBridge
variable is equal to true
, the code inside the opening and closing curly braces {...}
will run. If not, the program continues after the if
block and without running the code within it.
Or do this instead
The captain also wants to tell his troops to stay put, if the enemy is not coming over the bridge.
Now we can introduce another C++ keyword, else
. When we want to explicitly do something when the if
does not evaluate to true
, we can use else
.
For example, to tell the troops to stay put if the enemy is not coming over the bridge, we could write this code:
if(isComingOverBridge) { // Shoot them } else { // Hold position }
The captain then realized that the problem wasn't as simple as he first thought. What if the enemy comes over the bridge, but has too many troops? His squad would be overrun and slaughtered. So, he came up with this code (we'll use some variables as well this time.):
bool isComingOverBridge; int enemyTroops; int friendlyTroops; // Initialize the previous variables, one way or another // Now the if if(isComingOverBridge && friendlyTroops > enemyTroops) { // shoot them } else if(isComingOverBridge && friendlyTroops < enemyTroops) { // blow the bridge } else { // Hold position }
The above code has three possible paths of execution. The first one is if the enemy is coming over the bridge, and the friendly troops are greater in number:
if(isComingOverBridge && friendlyTroops > enemyTroops)
The second is if the enemy troops are coming over the bridge but outnumber the friendly troops:
else if(isComingOveBridge && friendlyTroops < enemyTroops)
Then the third and final possible outcome, which will execute if neither of the others is true
, is captured by the final else
, without an if
condition.
Reader challenge
Can you spot a flaw with the preceding code? One that might leave a bunch of inexperienced troops in complete disarray? The possibility of the enemy troops and friendly troops being exactly equal in number has not been handled explicitly, and would therefore be handled by the final else
. The final else
is meant for when there are no enemy troops. I guess any self-respecting captain would expect his troops to fight in this situation. He could change the first if
statement to accommodate this possibility:
if(isComingOverBridge && friendlyTroops >= enemyTroops)
And finally, the captain's last concern was that, if the enemy came over the bridge waving the white flag of surrender and were promptly slaughtered, then his men would end up as war criminals. The C++ code needed was obvious. Using the wavingWhiteFlag
Boolean variable he wrote this test:
if (wavingWhiteFlag) { // Take prisoners }
But the issue of where to put this code was less clear. In the end, the captain opted for the following nested solution and for changing the test for wavingWhiteFlag
to logical NOT, like this:
if (!wavingWhiteFlag) { // not surrendering so check everything else if(isComingOverTheBridge && friendlyTroops >= enemyTroops) { // shoot them } else if(isComingOverTheBridge && friendlyTroops < enemyTroops) { // blow the bridge } } else { // this is the else for our first if // Take prisoners { // Holding position
This demonstrates that we can nest if
and else
statements inside one another to create quite deep and detailed decisions.
We could go on making more and more complicated decisions with if
and else
but what we have seen is more than sufficient as an introduction. It is probably worth pointing out that, very often there is more than one way to arrive at a solution to a problem. The right way will usually be the way that solves the problem in the clearest and simplest manner.
We are getting closer to having all the C++ knowledge we need to be able to animate our clouds and bee. We have one final animation issue to discuss and then we can get back to the game.