Activity 3.7.1.
Run the code below. Try taking 1, 2, and -1 sticks by changing the code in main.
takeSticks()
method of OneRowNim
. We noted earlier that our current definition allows \(4\) or more sticks to be removed from nSticks
even though the rules of One Row Nim indicate that a player must take one, two, or three sticks on a turn. We can use if-else
statements to make certain that no more than \(3\) sticks get removed.takeSticks()
is called with an argument that does not represent a legal number of sticks to remove? In this case, it would probably make sense to remove no sticks at all and to keep the value of player
the same so that the player whose turn it is does not change. In addition, it would be nice if the method could signal that an illegal move has been attempted. This can be accomplished if we redefine takeSticks()
to return a boolean
value. Let’s have a return value of true
represent the case that a valid number of sticks have been removed and the player to play next has been changed. A return of false
will indicate that an illegal move has been attempted. Making these changes to the takeSticks()
method will yield a method definition that looks like:public boolean takeSticks(int num)
{ if (num < 1) {
return false; // Error
} else if ( num > 3) {
return false; // Error
} else {
nSticks = nSticks - num;
player = 3 - player;
return true;
} //else
} //takeSticks
takeSticks()
method has a boolean return type. Also notice that the if/else
multiway structure is used to handle the three cases of the parameter num
being less than one, more than three, or a valid number. Try the code below to see it running.OneRowNim
class. Let’s define a method called getWinner()
that will return the number of the winning player if the game is over. Recall that the player who takes the last stick loses, so after that last play, the player whose turn it is to play next is the winner. However, we should be concerned about what value to return if the game is not over when the method is called. A common strategy is to have a method return a special value to indicate that it is in a state in which it cannot return the value requested. Returning a \(0\) value is a good way to indicate that the game is not over so a winner cannot be identified. With this information, the if/else
statement can be used in the definition of getWinner()
.public int getWinner()
{ if (nSticks < 1)
return player;
else
return 0;
} // getWinner()
OneRowNim
class whose implementation is given in Figure 3.7.1. We have turned a very simple class into one that contains quite a few elements. Compared to our first version (in Chapter 1), this Chapter’s version of OneRowNim
presents an interface (to other objects) that is easy and convenient to use. The constructor methods with parameters provide an easy way to create a OneRowNim
instance with any number of sticks. The use of private
instance variables and a single, carefully designed mutator method, takeSticks()
, prevents other objects from tampering with the state of a OneRowNim
object’s state. The other methods provide a flexible way to find out the state of a OneRowNim
object. The complete implementation of this OneRowNim
is shown in Figure 3.7.1.Choose the initial number of sticks for the game
while the game is not over {
Report the state of the game
Process the next move
}
Report the state of the game
Report who the winner is
Scanner
class introduced in the previous chapter to allow the game to be played with keyboard input for each player.takeSticks()
method is ignored in this test program. We will make use of the return value in test programs in the next chapter when better user interfaces are developed for OneRowNim
. Note, however, that taken together, the public methods for OneRowNim
provide other objects with an interface that they can use to communicate with individual OneRowNim
objects.