Notes on the Card Game Assignment David Matuszek

Example of a game

This is an example of the way this game is played. The purpose of the example is to clarify the rules of the game. The output below is based on actual output, but I have added quite a bit to help explain what is going on.

Dealer: Don
Players: Alice, Bob, and Carol

The deal:
Don gives Alice a 5 (hidden) and a 4 (visible).
Don gives Bob a 6 (hidden) and a 1 (visible).
Don gives Carol an 8 (hidden) and a 9 (visible).
(Visible totals are now: Alice, 4; Bob, 1; Carol, 9)

The play:
Don tells Alice that it's her turn to play.
Alice asks Don for a card.
Don gives Alice a 4 (visible).
(Alice's visible cards now total 8.)
Don tells Bob that it's his turn to play.
Bob asks Don for a card.
Don gives Bob a 4 (visible).
(Bob's visible cards now total 5.)
Don tells Carol that it's her turn to play.
Carol passes.
Don tells Alice that it's her turn to play.
Alice asks Don for a card.
Don gives Alice a 10 (visible).
(Alice's visible cards now total 18.)
Don tells Bob that it's his turn to play.
Bob asks Don for a card.
Don gives Bob a 1 (visible).
(Bob's visible cards now total 6.)
Don tells Alice that it's her turn to play.
Alice passes.
Don tells Bob that it's his turn to play.
Bob asks Don for a card.
Don gives Bob a 1 (visible).
(Bob's visible cards now total 7.)
Don tells Bob that it's his turn to play.
Bob asks Don for a card.
Don gives Bob a 5 (visible).
(Bob's visible cards now total 12.)
Don tells Bob that it's his turn to play.
Bob passes.
Don notices that everyone has passed.

The scoring:
Don asks Alice for her total, gets told 23.
Don asks Bob for his total, gets told 18.
Don asks Carol for her total, gets told 17.
Don decides that Bob has won.

Common Misconceptions

A number of students seem to think that inheritance matters here. There is no inheritance. None of my classes is a subclass of any other of my classes. A `Dealer` is not a kind of `Player`, a `Player` is not a kind of `Game`, etc. (OK, all the classes inherit stuff from `Object`, at least in theory, but none of that stuff is used.) This program simply makes no use of inheritance. The dotted arrows in the BlueJ diagram indicate that objects in one class use objects in another class; turn the `Uses` and `Inheritance` checkboxes on and off to see what I mean.

The program does not ask for keyboard input. You start the program, it runs and produces output, it stops. You, the student, are not one of the `Player`s. We haven't talked yet about how the program can read in anything from the keyboard. It's not easy. It's not wanted. Don't do it.

Dumb Things in the Game

No program is perfect. I got the program working, I did a number of things to simplify it and make it cleaner and more elegant. I missed some things. Any program can be improved, and this one is no exception.

Dumb thing #1. (Caution: you probably won't understand this unless you already thoroughly understand the concepts of object-oriented programming.) I was thinking of a `game` as an object referring to a `Dealer` and three `Player`s. With this view, you have to tell the players what `game` object they are using. Then I made the variables `dealer`, `player1`, `player2`, `player3` into static variables (associated with the `Game` class, not with any particular `game` instance). Doing this makes it impossible to have more than one game, but it simplifies the program. Once I made these variables static, there was no longer any reason to create a `game` object, or to require it as a parameter to the `Player` constructor. (If you understand this, feel free to change the program accordingly.)

This also means that when a player needs to send a `nextCard() `message to the dealer, he or she can do so by saying` Game.dealer.nextCard()`, rather than `game.dealer.nextCard()`.

Dumb thing #2. When you have a complex problem to solve, you should break it down into simpler problems. Figuring out who won the game is a fairly complex problem. I created a "helper" method, `playerWins(int, int, int)`. This is fine for my own code, but it is apparently hard to explain what this method is for. I should have left you to struggle with the original problem of determining who won the card game, rather than "help" you in this way. Sorry. Feel free to ignore this method.

More Code Explanations

In the extensive comments, I tried to tell you exactly what each method should do, and give you some good ideas on how to do it. This part is intended to supplement, not replace, those comments.

Game:

`main(String)`
Construct the game, three players, and the dealer, then tell the dealer to `runGame(`).

Dealer:

`runGame()`
To deal the cards, call `deal()`. (This is an example of the Dealer talking to himself.)
To give each player a chance to play, call `allowPlay()`. (Ditto.)
To determine the winner, call` scoreGame()`. (Ditto.)
`nextCard()`
Returns a random number between 1 and 10, inclusive. I've already created a `Random` object, named `random`, for you. If you look at the Java API (as I suggested), you will find the `Random` class in `java.util`, and you will find that it responds to the message `nextInt(`int`)`.
Note that a Player can ask a Dealer for a` nextCard()`.
`deal()`
Hand out two cards to each player, one hidden, one not. You give a card to a player by telling the player to `takeCard(...)`, along with extra information about which card to take (use `nextCard()` to get this), and whether the card is hidden or visible.
`allowPlay()`
This method is a little tricky to write. It should tell each player in turn to` play()`, unless that player has already passed (look at the player's passed variable) and it should frequently check whether all players have passed. When all players have passed, the method is finished.
`playerWins(`score1`, `score2```, ```score3`)`
Determines whether score1 is the highest score not exceeding 21. This method is not necessary, but I found it convenient when writing``` scoreGame()```. You can ignore this method if you want to.
`scoreGame()`
Asks each player in turn for their total score (by telling the `getScore()`), decides who has the highest score not exceeding 21, and announces the winner. (In the event of ties, no one wins).

Player:

`takeCard()`
This method is used by the dealer, at the beginning. The dealer gets a card (by using `nextCard()`), and tells a player to `takeCard(`card`, `hidden`)`. The parameters are extra information given to the player: which card it is, and whether it should be hidden or visible. Since the dealer has to deal six cards, he sends the `takeCard(...)` message six times, twice to each player.
That's who uses the method. What the player does when she gets the message is to save the card in one of her instance variables, `hiddenCard` or `sumOfVisibleCards`, depending on what the hidden parameter tells her to do with it.
`play()`
The player uses this method to decide whether or not to take a card. The decision process can be as simple or as complicated as you want to make it. In the end, though, the player's choices are (1) to ask the dealer for another card, and add it to her `sumOfVisibleCards`, or (2) to assign her variable `passed` the value `true`.
(Note: The way I did things, the player doesn't know who the dealer is, so asking for another card is a bit complicated. I'll just tell you how to do it: `int card = game.dealer.nextCard();`)
`getScore()`
Just add `hiddenCard` and `sumOfVisibleCards` and return the result.