6.096 Fall 1997
Introduction to Interactive Programming

Laboratory 6:Communicating Applications

Overview

This lab will introduce you to the idea of applications which communicate with each other via a network. You will be writing a very simple two-player video game.

This assignment must be donewith a partner. Part of the assignment is to be done jointly with your partner. Other parts of the assignment are to be done individually. If you do not have a partner to work with, please let the course staff know immediately.

This lab focuses on the following ideas:

You should read through this entire assignment and complete the Lab preparation section before you come to lab. Some portions of the Post Lab write-up also require your thinking about them before and during the laboratory portion of the assignment. Note that this week's lab is to be designed and implemented with a partner. It is important that you plan your complete design and divide up coding responsibilities before coming to lab.

Please include the names of anyone with whom you collaborate, in any way, on this assignment. This includes your partner. (As always, you are welcome to discuss the assignment with other students in the class as well.) You should also indicate the nature of any collaborations. [Failure to include this information is a violation of the collaboration policy.]

This assignment is due at the beginning of class on 10 November, 1997.


Contents


Introduction

The game that you will be creating in this lab is called Cat and Mouse. (In other languages, we've been told, it might be more appropriate to call it Dog and Cat. If you have other creative suggestions, please let us know and we may change its name if we get a good enough suggestion; however, in this description of the problem set, we'll use Cat and Mouse.)

A quick definitional note: In this lab the term Mouse (capital M) is used to describe the Mouse portion of the problem set (as opposed to the Cat portion) which the term mouse (lower case m) is used to describe the pointing devise.

In this program one player (at one computer) is the Cat while another player at a different computer is the Mouse. The Cat player clicks his mouse whenever he thinks the Cat (the big black dot) and the mouse (the little yellow dot) overlap. It they did in fact overlap then both players will recieve a message saying that a hit occured, otherwise both players will recieve a message saying that a miss occured.

Running the Demo

It is highly recommended that you run the demo before you attempt this lab; it will make the instructions a lot easier to understand.

In order to run the demo, you need to start up two separate programs on two separate computers. One is the Cat, and one the Mouse. When you start up each of these applications, you will be asked for some information. You will need to know the name (or the IP address) of the computer that the Mouse is running on. The way that we have set up the demo, the Mouse must supply the requested information first.

You can demo the program on Athena by first typing

java CatAndMouse.MouseDemo

on one machine, and then:

java CatAndMouse.CatDemo

on another machine. On the lab machines, you will need to set up a project, etc., and then run the same two programs.

You will be asked for a port (and, for the Cat, hostname).

In order to run the demonstration in Lab, you and your partner will need to log in to two seperate machines. One of you will need to add the project file CatDemo, and the other will need to add the project file MouseDemo. You can add these projects to your portfolio in the normal way; they are in the root directory of S:\ (where all of the other project files have been). When you add a project, Java Workshop will ask you what directory you want to copy the project file to. You should type in u:\ in the box. You will probably notice that the main window where you type in your code is full of gibberish; this is expected.

Once you and your partner have loaded the appropriate project files, one of you will need to start the MouseDemo program. Once the MouseDemo program is running, you should start the CatDemo program. Supply the appropriate information in the CatDemo dialog box (Note that you will have to change both fields of the dialog box, the default hostname that appears is the name of your computer; you want to change this to the name of the computer running the MouseDemo program. You also want to change the port number to read 4321.)

Pre-Lab

In addition to working on the finger exercises, for this week you should think through the assignment and come to lab with a plan that includes at least a partial solution to the problem set and a development plan for how you intend to implement your solution.

A. Finger Exercise

In answering these questions, you may find it useful to refer to the Java Applications Programmer Interface (API) documentation, especially portions of the java.awt and java.awt.event packages.

1. Design a data repository class that keeps track of an x and a y coordinate and has an additional field of type int. Make sure that your class provides transaction-safe access to its fields. It should be possible to change the coordinates (both together), but not the additional type field. It should also be possible to hand off (return, give another object) the x and y coordinates safely.

2. Design a class that extends java.awt.Panel and keeps track of a location in screen coordinates. (It can, for example, just have two ints as fields.) The paint method of this class should draw a filled oval centered at the specified point.

3. Design a class that extends java.awt.Panel and keeps track of the mouse position. That is, it should have a getMouse() method that can be called by other objects and returns an object corresponding to the mouse's current location. You may, of course, define auxilliary objects to help handle the relevant events.

Questions to think about:

4. Now design a class that combines all of these behaviors. Your new class should extend java.awt.Panel and keep track of (hint: field) the last location where the mouse was depressed, i.e., the last place where a mousePressed occurred. The paint method of this class should draw a filled oval centered at the specified point.

  1. (Bonus) Modify your class so that it keeps track of the current mouse position instead.
  2. (Extra Bonus) Add a getMouse() method to your class. This method should be callable by other objects and should return an object corresponding to the mouse's current location.
  3. Questions to think about:

B. Lab Preparation

For this assignment, you are going to build a pair of networked applications. We will supply you with the networking code and some of the GUI infrastructure, but you will have to divide up the functionality and to implement most of the two applications. Because there is a lot of code to write, you and your partner should design things so that each of you can write some of the code.

The next stage of this project involves building a pair of networked applications. We have supplied you with the networking code, but there is still a lot to be done. You and your partners should try to design things so that each of you can write some of the code.

About the Applications

The two applications that you will write will run on two different computers and will each interact with the user as well as with the other application. One of these two applications is the Cat, and the other is the Mouse. The Mouse is a GUI application that moves a dot around its window under mouse control. The Cat also moves under the control of its own mouse, but in addition, it can see the position of the Mouse. If the user of the Cat application clicks her mouse on the Mouse's location, a "hit" should appear on both application's displays.

Setting Up a Panel

Much of the code for these two applications is the same. In particular, both Cat and Mouse will need:

  1. have a constructor that takes a Component as an argument.
  2. have an init method that adds the Component and handles sizing, showing.
  3. handle Event.WINDOW_DESTROY by calling this.dispose() to free up any system resources and System.exit(0) to complete execution.

Each of your two applications -- Cat or Mouse -- should do the following.

  1. Create an instance of the appropriate Wire. It doesn't matter which one you use for Cat and which for Mouse, but each of them should have a Wire, one generated by new ClientWire() and the other by new ServerWire(). You do not need to understand the particular wire classes, but you should understand the CatAndMouse.Wire interface. Note that these classes can send any type of Object across the network.
  2. Set up an animated while(true) loop that reads data off the Wire.
  3. The mouse handling code you designed earlier should output data to the Wire. (At first, send something simple like the location of the last mouseDown.)
  4. Paint both points on your Panel (perhaps in different colors?) Think about which object should be responsbile for repainting the Panel, and in what sorts of situations.

You should divide up responsibility for actually implementing these pieces of code (other than the ones we've written), but you should both be involved in their design (or at least look over each other's work).

Protocol for Communication

The differences between the Cat and Mouse code come in the ways that they handle mouse motion, what data they communicate over the network, and how (and what) they display. The second part of your assignment is to outline both the Cat's and the Mouse's answers to these issues. E.g., for the Cat:

  1. What data does the Cat object need to keep track of?
  2. What data does the Cat object get from its GUI?
  3. How does the Cat access this data?
  4. What does the Cat do with this data?
  5. What data does the Cat send to the Mouse?
  6. What data does the Cat receive from the Mouse?
  7. How does the Cat access this data?
  8. What does the Cat do with this data?

The same questions can obviously be applied to the Mouse. The two sets of answers should be consistent (which they will be if you are doing this part as a team!)

This amounts to designing an interaction protocol for the two classes. When you believe that you have a working design, you might want to try acting it out. Really! It will help visualize what is happening. Remember that you need (to simulate) one participant per thread. Agree on what things each application needs to do, and write this down for reference.

Individual Differences

Next, you should work on the implementation of Cat or Mouse (whichever one you're doing) to meet this specification. This portion of the pre-lab should ideally be done individually, though it may be a good idea to have your partner look over your design/code draft. In lab, you will actually divide coding responsibility this way. Among the questions that you should answer are the ones above as well as these:

  1. What methods does the Cat need to have to handle the data above?
  2. What data structures does it need?
  3. What (if any) subordinate objects does the Cat keep track of/use to handle any of its needs? Which methods/data/services do these objects provide?
  4. What threads can be (simultaneously) running in the Cat?
  5. Which methods does each thread (potentially) run?
  6. What data is shared across threads?
  7. Where is synchronization necessary in order to ensure that your code is transaction safe? Remember that a synchronized method obtains a lock (ready-to-run license) on its containing object.

Again, the same questions apply to the Mouse.

Development Plan

The final stage of pre-lab preparation is to write up a step-by-step description of your incremental development plan. This is a collaborative activity, and you should feel free to discuss it with (or actually do it with) your partner.

The way you divide up the problems with your team members and combine your solutions will have a tremendous impact on the complexities that you encounter on the way. This is especially true of heavy-duty applications in the real world. In particular, think about the following:

  1. What is the minimum self-contained (i.e., testable) functionality that you can implement?
  2. How will you test it?
  3. What can you add to make a slightly more complex and still fully testable version?
  4. How would you test this?

Continue listing added features and tests until you scale up to your complete design. This technique, incremental refinement, is an extremely useful and practical way to write code. You may want to read through the suggestions in the In the Lab section, below.

You probably want to test (at least parts of ) your applications standalone before getting them to talk to one another. You may also want to test the network communication somewhat independently from the GUI, or at least with a relatively static or simple GUI. Your tests do not need to be symmetric, i.e., you can test a really simple Cat with a vaguely interesting Mouse, or vice versa.

Notes:

Using our DefaultFrame

To test your code, you may want to use our cs101.util.DefaultFrame.java class. DefaultFrame's constructor takes a Component as an argument and displays that Component inside itself. (Your extended Panel should do just fine.) DefaultFrame's init() method is responsible for adding the Component, sizing, and showing it.

You will also need to write a main file that does the following:

  1. create a new instance of your panel.
  2. create a new instance of cs101.util.DefaultFrame, passing your panel as an argument to DefaultFrame's constructor.
  3. calls the DefaultFrame's init() method.

Note: You probably want to include the following code to your extended panel class:

 public Dimension getMinimumSize() {
    return new Dimension(200,200);
  }
 public Dimension getPreferredSize() {
    return new Dimension(400,400);
  }

This defines a size for the Panel; otherwise it will not report any size and may not be displayed.

Making Connections with Wires

You will also need a way to establish network communication and send various types of points back and forth. We've provided two versions of this code, both of which implement the CatAndMouse.Wire interface. One is called ClientWire, and the other is ServerWire.

The CatAndMouse.Wire interface contains two methods:

You can actually test the Wires without your GUI at all. For example, you can write a program that sits on one side (on one computer) and calls putObject with a String (or even a String that includes an int that changes....use + to put a String and an int together....). The object on the other side needs to getObject() from the Wire and, e.g., System.out.println() it.

Laboratory

What to Bring to Lab

You should bring your answers to the finger exercises as well as your design and implementation plan for this lab. In addition, you should have thought out answers to all of the questions in the laboratory preparation section and should be prepared to begin writing code immediately upon entering lab. When you arrive at lab, you should have answers to the questions in the lab preparation a copy of your code design and development plan (on-line or on paper) ready so that we can check you into lab.

Getting Started

In lab, you should write and test the code that you designed.

As always, you should implement your code in simple, testable stages, building on your code only as each stage works robustly. In this case, it should be as simple as following your development plan.

A few notes:

You probably want to test (at least parts of) your applications standalone before getting them to talk to one another. You may also want to test the network communication somewhat independently from the GUI, or at least with a relatively static or simple GUI. Your tests do not need to be symmetric, i.e., you can test a really dumb Cat with a vaguely interesting Mouse, or vice versa.

Try to work through the code that you and your partner developed before lab. Remember to test small sections of your code rather than trying to type all of it in at once and then debug it. It is especially important that you become proficient at using the Wires and creating your GUI components before you try to write the full application.

Some simple things you might want to try are listed below:

You will, of course, want to make use of your answers to the finger exercises.

Compiling Your Code

In lab

Since you are writing most of this application yourselves, you will need to create your own project and add all of your files to it. You can do this by:

On Athena

If you want to run your code on Athena, you should be able to compile and run your code normally, using the javac command to compile your main class and java to run it.

Before you leave

Before you leave lab, you will need to have your work checked off by a course staff member.

At a minimum, you should expect to demonstrate two applications running on different workstations and visibly communicating somehow.

You should be prepared to answer questions about who implemented what, and about how well these implementations adhere to the previously agreed-upon specifications.

If your code does not behave as expected, you should be prepared to explain why or to describe what you have done to try to figure out why.

If your code has more than this minimal functionality, you should be able to describe and demonstrate what it does as well as how you were able to achieve this behavior.

It is always more important that you write clean, modular, well-documented and easy-to-understand code than that you go on to advanced features.

Post-Lab, AKA What To Turn In

Your completed assignment should include:

You should do your writeup individually, though of course it will be describing shared work. You may also include (pointers to) code developed by your partner, but it should be clearly marked.

Lab assignments are due on Mondays at the beginning of class. They may, of course, be turned in earlier.


This course is a part of Lynn Andrea Stein's Rethinking CS101 project at the MIT AI Lab and the Department of Electrical Engineering and Computer Science at the Massachusetts Institute of Technology.

Questions or comments:
<cs101-webmaster@ai.mit.edu>

Last modified: Thu Jul 10 13:01:20 1997