Exercise Sheet F

Exercise

Instructions

The Task

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.

Part 1: Blackjack

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.

Part 2: The GUI and the Controller

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.

Challenge Exercise

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: