CS 51 Homework Laboratory # 12
Send Your Drawing Merrily down the Stream

Objective: To gain experience with Streams.

Networked Pictionary

This week's assignment will give you the opportunity to practice working with Streams in the context of a networked Pictionary program. Pictionary is very much like the game of Charades. One player selects a word or phrase to act out, and another player must guess what the word or phrase is. Unlike Charades where the "acting out" is physical, in Pictionary the acting is done by drawing. That is, one player draws a picture representing a word or phrase, while the other player tries to guess it.

Our networked Pictionary program allows two players to play the game. One is the Drawer; the other is the Guesser. When the program starts up, a window with two buttons appears. The buttons are labeled "Drawer" and "Guesser" to allow the player to select which they will be.

If the player selects Drawer, he or she is asked to select a file from which a card is picked. The card tells the player what to draw. The Drawer's window contains a drawing canvas, the card display, and another label for the Guesser's guess. The Drawer draws with the mouse. Guesses appear in the drawer's window when made by the guesser (with a return at the end). When the Guesser makes the right guess, the Drawer clicks on the Right button to notify the Guesser and to end the game.

The Guesser's window shows a drawing canvas as well as a text field into which the player can type his or her guess. The Guesser cannot draw on the canvas. Instead, the Drawer's drawing appears in this canvas. The Guesser types a guess in the text field. When the Guesser hits the return key, the guess is sent to the Drawer and appears on the Drawer's screen.

Below are shapshots of a game in progress. The first display shows a Drawer's window. The Drawer is attempting to draw "graduation."

The next display shows a Guesser's window. The Guesser thinks that the drawing looks like a woman with a nest on her head.

Organization

Our implementation comprises four classes:

  1. Pictionary, which is a WindowController.

  2. Cards, which handles the reading of the cards from file.

  3. Guesser, which represents the guesser in the game.

  4. Drawer, which represents the drawer in the game.

We have completely implemented the Pictionary and Guesser classes, and most of Cards and Drawer. We have placed comments in the Cards and Drawer classes indicating where you should add code and what that code should do.

How to Run the Program

Once your program has been written, you will begin by running two versions of the program by just selecting "run" twice. (We suggest making the windows 400 pixels wide and 450 tall.) When both versions are open, move the top-most window so that you can see both windows. You will need to make one of these the Drawer and the other the Guesser. Since the Drawer is the server, you must start the Drawer first. You can do this by selecting the "Drawer" button in one of the windows. (If you mistakenly start the Guesser first, the System console will display the error message "Could not connect to server".) The Drawer will ask you to find the cards.txt file. It can be found inside your starter directory. Now select the "Guesser" button on the other window. You should now be ready to play. The game ends when the Drawer clicks the "Right" button.

How to Write the Program

Begin by filling in the details of the Card class. We have implemented everything except the part of the constructor which reads the card information from the cardFile and loads each line into an element of the cards array. You will need to create a BufferedReader from cardFile (which is itself created in our code by calling method getDeckFile()), and then read each successive line into a new element of the array cards. You will be done when you either run out of stuff to read (readLine() returns null) or you've filled the array. When you are done, the variable numCards should contain the total number of cards. Make sure this is accurate as it will be used by shuffle. [Yes, we know, we don't really need to shuffle since we only ever pull one card from the deck. We just wanted you to see how it could be done!]

The Drawer acts as a Server in a Client/Server relationship. Its constructor sets up a ServerSocket, drawingServer, and then waits to accept a connection from the client. Once this has happened, the Drawer will create an input stream, guessStream, and an output stream, out, in order to communicate with the Guesser. The writeLine method should send along the output stream the Line segments that should be drawn on the Guesser's canvas. (Method writeLine is called from the onMouseDrag method of Pictionary.java.) From the input stream it will accept guesses.

We have implemented everything but the run() and writeLine methods. The writeLine method's only job is to write its Line parameter to the network output stream so that Guesser can pick it up and write it to its canvas. If anything goes wrong, just call the close() method to close up all open streams.

Because the Lines being sent to the Guesser are Objects, it is appropriate to send them through the ObjectOutputStream, out, created in the constructor. Unlike the examples in class, you should not use a BufferedOutputStream because we want the Lines to appear as soon as they are produced, not being passed a handful at a time as a BufferedOutputStream would do.

Guesses are Strings. We made guessStream a BufferedReader, as that will handle Strings appropriately.

Read through the Card and Drawer classes, noting the lines that ask you to add code. Those are the only places where you will need to make changes to the files. You may also find it useful to refer to the networked Drawing Panel example from class and also look at the Guesser class to see exactly what it is expecting to receive and send on its end of the streams.

The starter code is set up to allow both the Drawer and Guesser to be on the same computer. While it is beyond the requirements of the assignment, you might enjoy actually getting them to play on different computers. To do that, go into the Guesser class and change the Socket constructor call. Replace "localhost" with the Internet address of another machine.

To find the address of another computer in the lab, pull down the apple menu in the upper left corner of your screen and select "System Preferences...". When a new window opens, click on the network icon in the third row.

In the resulting pane you should see a green dot with "Ethernet connected" next to it. Click on that entry to make sure it is selected. In the panel to the right, there will be an entry with the labs "IP Address". The text to the right of it will contain the IP address of your computer. It will be something like "134.173.66.98". This number should replace "localhost" in your code. Be sure to place quotation marks around the number so it is treated as a string. For example on my computer I would replace "localhost" by "134.173.66.98". This is the computer that will be the "Drawer". Once the "Drawer" has been started on that computer (including selecting the file "cards.txt"), start up another copy of your applet on any other computer (no matter where in the world!) and set it to be a "Guesser". You can now have players on the two different computers playing a game together.

Please be sure, though, that the code you turn in uses "localhost". If you pass a string that is not a valid computer name, when you start the Guesser, you will get the message "Unknown host". Remember that the "Drawer" must start first since it is the server.

Grading Point Allocations

Value

Feature
Syntax Style (4 pts total)
1 pt. Descriptive comments
1 pt. Good names
1 pt. Good use of constants
1 pt. Appropriate formatting
Semantic style (3 pts total)
1 pt. conditionals and loops
1 pt. General correctness/design/efficiency issues
1 pts. Parameters, variables, and scoping
Correctness (3 pts total)
1 pt. sending Lines
1 pt. receiving guesses
1/2 pt. reading in data to cards array
1/2 pt. closing up socket and streams

Working Together

You are encouraged, but not required, to work together with another student on this program. You may do all of the design and coding together. Only turn in one copy of the program, but make sure both names are on the folder and at the top of each class.

Submitting Your Work

Your program is due as usual on Monday evening at 11 p.m. When your work is complete you should deposit in the dropoff folder your entire Pictionary folder. Before you do this, make sure the folder name includes your name(s) and the phrase "Lab 12." Also make sure that the Drawer.java and Card.java files include a comment containing your name.

Before turning in your work, be sure to double check both its logical organization and your style of presentation. Make your code as clear as possible and include appropriate comments.


Computer Science 051
Department of Computer Science
Pomona College