Beginning C++ Game Programming
上QQ阅读APP看书,第一时间看更新

Making decisions with if and else

The C++ if and else keywords are what allow us to make decisions. We have already seen if in action in the previous chapter when we detected whether the player had pressed the Esc key each frame:

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 will look at some new operators.

Logical operators

Logical operators are going to help us to 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 make all of the required decisions we will need with just a few of the logical operators.

Here is a table of the most useful logical operators. Look at them and the associated examples, and then we will see how we can put them to use:

Let's take a look at the C++ if and else keywords, which will allow us to put all of 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 waiting for 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 following 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.

Shoot them … or else 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 the following 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 the following 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 preceding code has three possible paths of execution. First, if the enemy is coming over the bridge and the friendly troops are greater in number:

if(isComingOverBridge && friendlyTroops > enemyTroops)

The second occurs 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, like so:

if(isComingOverBridge && friendlyTroops >=  enemyTroops)

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 that was needed was obvious. Using the wavingWhiteFlag Boolean variable, he wrote this test:

if (wavingWhiteFlag)

{

    // Take prisoners

}

But where to put this code was less clear. In the end, the captain opted for the following nested solution and changed 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 enough as an introduction. It is probably worth pointing out, that 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 of 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.