CS 51 Homework Laboratory # 11
Send Your Drawing Merrily down the Stream
Objective: To gain experience with Streams.
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."
Our implementation comprises four classes:
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.
Once your program has been written, you will begin by running two versions of the program by just selecting "run" twice. 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.
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 name of another Mac in the lab, pull down the Apple menu (the menu with the apple icon) and select Control Panels. From there select TCP/IP. Look in the field labelled IP Address. Copy this number down exactly as it appears. Replace localhost with this number, keeping the quotation marks around the number.
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 AllocationsValue | 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 |
Your program is due on Friday at 4 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 and the phrase "Lab 11." 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 Math & Computer Science
Pomona College