The Doctor Program

A patient engages in a "conversation" with the doctor program by typing sentences into the input field of the Doctor.html applet. These sentences are echoed in the text area of the applet, along with the doctor's replies. Below is a sample conversation that could take place in the program. For readability, the doctor's replies have been italicized, though in the actual program all sentences are in the same font.

Doctor: What is your name?
Patient: Chandler
Doctor: Hello, Chandler. What seems to be the trouble?
Chandler: Joey moved out
Doctor: Why do you say Joey moved out
Chandler: He moved to another apartment
Doctor: You seem to think he moved to another apartment
Chandler: Yes, he moved out last week
Doctor: Please continue.
Chandler: I miss him
Doctor: Many people have the same sorts of feelings.
Chandler: Well I guess I can still see him
Doctor: Earlier you said that he moved to another apartment
Chandler: Yeah, but he doesn't live too far away
Doctor: Please continue
Chandler: And then there's the business with Janice
Doctor: Why do you say and then there's the business with Janice
Chandler: Goodbye

Doctor: Goodbye, Chandler. See you next week!

The doctor program uses three simple strategies to respond to a patient:

  1. Use a hedge statement like "Please continue" or "Many people have the same sorts of feelings".
  2. Attach a qualifier like "You seem to think" or "Why do you say" to the patient's most recent statement.
  3. Attach a qualifier like "Earlier you said that" or "Before you mentioned" to one of the patient's previous statements.

These strategies are embodied in the reply() method of the Doctor class, which takes the patients most recent statement and a list of all the patient's previous statements. Here is the code for reply(), along with a number of helper methods.

NOTE: these methods are given to you! You do NOT need to write them.

   public String reply (String message, ObjectList history) {
// Returns a reply to patient's message.
// Message is what the patient just said.
// history is the list of patient sentences,
// from most recent to least recent.
		if (Randomizer.Chances(1,3)) {
			return hedge();
		} else if (Randomizer.Chances(1,2) && (length(history) >= 3)) {
		     return pastQualify(history);
		} else {
		     return qualify(message);
		}
	}
public String hedge() {
	return (String) (pickRandom(hedges));
	}
	
	public String qualify(String message) {
		return pickRandom(qualifiers) + " " 
		        + process((String) message);
	}
	
	public String pastQualify(ObjectList sentences) {
		return pickRandom(pastQualifiers) + " " 
			   + process((String) pickRandom(sentences)) + ".";
	}
	
	
	public String process (String sentence) {
		return decapitalize(sentence);
	}
 
	public static String decapitalize (String s) {
 
	// Returns a string the same as s except the first character is lower case.
 
	  ObjectList exceptions = prepend("I ", 
                                prepend("I'm", 
                                 prepend("I'll", 
                                  empty())));
	  if (beginsWithOneOf(exceptions, s)) {
	  	// Special case: don't decapitalize sentences beginning with "I ..."
	  	return s;
	  } else if (s.length() > 1) {
			return Character.toLowerCase(s.charAt(0)) + s.substring(1);
	  } else if (s.length() == 1) {
			return Character.toLowerCase(s.charAt(0)) + "";
	  } else {// s is empty
			return s;
	  }
	}
	
	public static boolean beginsWithOneOf (ObjectList prefixes, String str) {
	
     // Returns true if str begins with one of the strings in prefixes.
 
		if (isEmpty(prefixes)) {
			return false;
		} else if (isPrefix((String) head(prefixes), str)) {
			return true;
		} else {
			return beginsWithOneOf(tail(prefixes), str);
		}
	}
	
	public static boolean isPrefix (String pre, String str) {
 
	// Returns true if pre is a prefix of str
 
		return (pre.length() <= str.length())
		        && (pre.equals(str.substring(0,pre.length())));
	}

Here are a few notes on the above methods: