* @author Derek Bridge 666 d.bridge@cs.ucc.ie * @author Sir Hugh Jeegoh 999 h.jeegoh@cs.ucc.ie
cs2000
directory called sheetF
.
If you are working in a pair, you should store your program in
only one team member's directory. I do not want to find myself
collecting in two versions of (supposedly) the same program.
sheetF
directory contains only the files you want me to mark. Do not leave
old versions of the program or versions of other programs in the directory.
We will mark all .java
files.
In this exercise, you will write a Java program with a GUI. Your program, like the shop till program covered in lectures, must have a three-layer architecture (i.e. application layer + presentation layer + translation layer, or, in alternative terminology, model + view + controller).
The exercise is to build a program that allows a user to play Blackjack against the computer.
You are going to implement a highly simplified version of Blackjack. (If the simplifications seem unsatisfactory, then see the Challenge Exercise.)
Our simple version of Blackjack is played with a single deck of cards. To speed your progress, I have written two class definitions for you: Card.java and Deck.java. Make copies of these, and take a look at them.
Observe that each card has a value. Ace counts 11. Jack, Queen and King count 10. Other cards count their face value (e.g. the 2 of Clubs counts 2). (Some of you will note a simplification here. In real Blackjack, Ace can count 1 or 11. Again, if you wish to be more faithful to the real game, see the Challenge Exercise.)
In Blackjack, a player (the user) plays against the house (the casino). This is how the game proceeds.
The cards are shuffled. Two cards are dealt to the user, and two to the house. The user cannot see the house's cards. (Again, this is a simplification: see the Challenge Exercise.) The user plays her/his hand first.
If the value of the user's two cards is 21, this is Blackjack. An unbeatable hand, no matter what the house has in its hand. (Yes, even if the house has Blackjack.) The user wins, and the game is over.
Otherwise, the user can choose between Hit or Stand. Hit means that s/he is given another card from the deck. S/he can keep choosing Hit (and thereby receiving additional cards) until s/he decides to Stand or until s/he is bust.
Bust means that the value of her/his hand exceeds 21. If the user goes bust, s/he loses (irrespective of what is in the houses' hand), and the game is over.
Obviously, ideally, s/he will keep choosing Hit until her/his hand is quite close to 21, but not over 21, and then s/he will choose Stand.
After the user chooses Stand, it is now the turn of the House. The House has no choice about its moves. For as long as the value of its hand is less than 17, it must choose Hit.
If the value goes over 21, it is bust, the user wins, and the game is over.
If the value is greater than or equal to 17 but less than or equal to 21, it must choose Stand. Now the values of the two hands are compared. Whoever has the higher value wins. If the values are the same, the game is drawn (which, in Blackjack, is referred to as Push).
In your three-layer architecture for this program, the application layer will
include my Card and Deck classes. And it will include some more classes.
For example, you will need a class or classes to represent the players.
(A quick inspection of Deck.java
will reveal that I
am expecting you to write a Player
class, and this class
must include a receive
method. Without this class and this method,
my Deck
class will not compile.)
And you will need a class for administering the game.
All these classes will have absolutely no GUI code in them.
When I wrote my version of this program, I
included a test-driver at this point. The test-driver
plays the
game without using a GUI.
At points where the user had to choose between Hit and Stand,
I simply used a random number to make the choice. I printed
lots of information to the screen (using System.out.println
)
so that I could check that all the code was working correctly.
This was my way of
checking that I'd included all the functionality that I needed.
It's up to you whether you do the same.
Now write the presentation layer (GUI/view) and the translation layer (listener/controller).
Here are some screenshots from my own Blackjack program. Your GUI doesn't have to be identical.
First, here's what my GUI looks like at the start of the game.
At the bottom of the screen are 3 buttons. Only the leftmost is enabled. Clicking the leftmost button begins a new game. So the deck is shuffled and the cards get dealt, and the user gets to see her/his cards (but not the house's cards). The other two buttons are also enabled at this point:
When the user presses Hit, s/he is given a new card.
S/he could press Hit again, but in the above s/he would be likely to go bust and lose the game immediately. So, let's suppose s/he presses Stand. At this point, the two rightmost buttons are disabled. And the house plays its hand in the way described earlier (i.e. standing when it reaches at least 17). At the end of playing the house's hand, the house's hand is displayed on the screen, along with the outcome.
For example, in the screenshot below, the house had been dealt an Ace and a Five. Their value (16) is less than 17, so the house was obliged to Hit. It received a Nine. Now it has gone bust. So it informs us that the user has won:
Since this is the end of the game, note how two of the buttons have again been disabled.
Remember Challenge Exercises are always optional and are not worth
any marks. If you wish to tackle this Challenge Exercise, copy
your completed program to
sheetF/challenge
.
The challenge is to make your program more realistic. Here are several ideas:
Allowing Aces to count 11 or 1 also complicates the decision about when the House chooses to Stand. Different casinos operate different rules (and maybe you'd like to write multiple subclasses to handle the different situations). In some casinos, the rule is 'stand on all 17s'. This means that the house chooses Stand as soon as its hand contains cards whose value is 17 or more for at least one way of counting the Aces. In other casinos, the rule is 'hit soft 17s'. This means that if the value of its cards is 17 or more only by treating an Ace as 11, then it will choose Hit. (Whichever rule is played, the house, like the user, is only bust if there is no way of counting its cards to sum to 21 or less.)
Before dealing, the user would place a bet. After the hand is played, the user might be awarded some winnings, or might lose her/his stake.