- Learning Java by Building Android Games
- John Horton
- 488字
- 2021-07-23 19:02:27
If they come over the bridge shoot them
As we saw in the previous chapter, operators are used in determining whether and how often a loop should execute the code in its body.
We can now take things a step further. Let's look at putting the most common operator ==
to use with the Java if
and else
keywords then we can start to see the powerful yet fine control that they offer us.
We will use if
and a few conditional operators along with a small story to demonstrate their use. Next follows a made up military situation that is kind of game-like in its nature.
The captain is dying and, knowing that his remaining subordinates are not very experienced, he decides to write a Java program to convey his last orders 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 Java? We need a Boolean 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
Boolean is 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.
Else do this instead
The captain also wants to tell his troops what to do (stay put) if the enemy is not coming over the bridge.
Now we introduce another Java 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 come over the bridge, but has too many troops? His squad would be overrun. So, he came up with this code (we'll use some variables as well this time.):
boolean isComingOverBridge; int enemyTroops; int friendlyTroops; // Code that initializes the above 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. First, if the enemy is coming over the bridge and the friendly troops are greater in number.
if(isComingOverBridge && friendlyTroops > enemyTroops)
Second, if the enemy troops are coming over the bridge and 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.
Tip
Reader challenge
Can you spot a flaw in the above 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
which is meant for when there are no enemy troops. I guess any self-respecting captain would expect his troops to fight in this situation and he could have changed 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 was promptly slaughtered, then his men would end up as war criminals. The Java code 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 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 of 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.
Let's look at some other ways to make decisions in Java and then we can put them all together in an app.
Switching to make decisions
We have seen the vast and virtually limitless possibilities of combining the Java operators with if
and else
statements. But sometimes a decision in Java can be better made in other ways.
When we must decide based on a clear list of possibilities that don't involve complex combinations, then the switch is usually the way to go.
We start a switch
decision like this.
switch(argument){
}
In the previous example, an argument could be an expression or a variable. Within the curly braces {}
we can make decisions based on the argument with case
and break
elements.
case x: // code to for case x break; case y: // code for case y break;
You can see in the previous example each case
states a possible result and each break
denotes the end of that case
and the point at which no further case
statements will be evaluated.
The first break
encountered breaks out of the switch
block to proceed with the next line of code after the closing brace }
of the entire switch
block.
We can also use default
without a value to run some code in case none of the case
statements evaluate to true. Like this:
default:// Look no value // Do something here if no other case statements are true break;
Let's look at a complete example of a switch
in action.
Switch example
Let's pretend we are writing an old-fashioned text adventure game, the kind of game where the player types commands like "Go East", "Go West" and "Take Sword", etc. In this case, switch
could handle that situation like this example code and we could use default
to handle the player typing a command which is not specifically handled.
// get input from user in a String variable called command String command = "go east"; switch(command){ case "go east": Log.d("Player: ", "Moves to the east" ); break; case "go west": Log.d("Player: ", "Moves to the East" ); break; case "go north": Log.d("Player: ", "Moves to the North" ); break; case "go south": Log.d("Player: ", "Moves to the South" ); break; case "take sword": Log.d("Player: ", "Takes the silver sword" ); break; // more possible cases default: Log.d("Message: ", "Sorry I don't speak Elvish" ); break; }
Depending upon the initialization of command
it might be specifically handled by one of the case
statements. Otherwise, we get the default Sorry I don't speak Elvish.
If we had a lot of code to execute for a particular case,
we could contain it all in a method. Perhaps, like this next piece of code, I have highlighted the new line.
default:
goWest();
break;
Of course, we would then need to write the new goWest
method. Then, when the command
variable was initialized to "go west",
the goWest
method would be executed and execution would return to the break
statement which would cause the code to continue after the switch
block.