Before the round begins, each player is dealt two cards from
the deck to start his hand.
On his subsequent play, he may either request more
cards from the deck, called a “hit”, or stick with his current hand, called a
“stay”.
Without his hand, the Player could not play – ergo, the
Player would not exist. Fittingly, the Player’s most important member variables
are his unique identifier, his hand, and a reference to the game deck from
which he populates his hand.
The Player’s constructor method is responsible for
initializing these member variables.
It passes in a String for his uid_ identifier and his reference to the game’s Deck.
Then it creates an empty hand as a Stack of Cards, and starts it with
two Card objects dealt from the top of that game Deck.
Once a Player has been instantiated and initialized, his only purpose is to play.
Just like real-life, each Player plays his entire game in
one loop. With each iteration of this loop, he assesses his current hand, and
decides to either Hit (pull another card from the deck) or Stay (stick with his
current hand).
The next block of code represents this central decision as a
switch statement between his potential Call choices. A
switch is like an extended if-then choice, except that it is based upon the
value of one variable. In this case, that variable is the player’s Call,
represented as an enum. If the player hits the keyboard character
‘H’ (upper or lower case), then he is making a Hit. Otherwise, he is making a
Stay.
Note the variable c above. In the ASCII world, that
one-character keyboard datum c would be an integer retrieved with a system call.
However, this simple logic requires more code than you would expect. This is
because it requires you to handle the exception.
What is an exception? An exception is a condition which
steps outside the normal boundaries of the environment. In other words, it is
exceptional. A better term for this, IMHO, would be “error”. Truth is, the
Exception class is Java’s way of letting you recover gracefully from your own
boneheaded mistakes.
By contrast, other programming languages let you proceed
willy-nilly with no regard to your personal safety. You can divide by zero,
read the 11th element of a 10-element array, allocate all the memory on your
network, and even flush your entire masterpiece into /dev/null. There are
literally no safeguards against your carelessness.
Java is different. Because it assumes your program will be
running on all sorts of unknown computers scattered all over the world, it
imposes its own safeguards. The primary safeguard is the Exception class. It is
its own discrete class in the Java language, and its subclasses will pop up
again and again. In fact, you can define your own Exception, so long as you
subclass it properly from the base class Exception.
When an exceptional condition is met in run-time, the
computer will throw an Exception object. You must program to catch this object.
You can create as elaborate a catch statement as you wish, coding for every
type of Exception to be thrown, even including a finally block to execute
at the end. However, you have to know which classes and methods will throw
which Exceptions, and you have to wrap all these potentially lethal calls in a
try block.
In the snippet below, the code to retrieve one character from the keyboard will be
“System.in.read()”. It is called twice, once for the
character key, and again for the Enter key. If there is a problem with either,
it will throw an IOException object which you have to catch.
Note how the try block is wrapped inside the while loop. (More on while loops later.)
Because it tests at the top for a true condition, it replays itself forever. If
the System.in.read() method throws an IOException, then the “continue”
statement in the catch block takes you back to the top. If not, then the
“break” statement gets you out. Bottom line: you keep trying until it works.
To summarize, the makeCall() method uses a System.in.read()
method to read a keystroke from the keyboard, which causes the method to return
either a Hit or Stay, which sends the flow of control back to the beginning or
out to the end.
The flowchart below demonstrates this. As you study it, make
note: This encapsulates the Player’s only purpose in the span of this program.