Answering the first question in a game where the user is thinking of a chicken. | So it has feathers and lives in a barnyard, what's next? | |
| ||
Wow, the computer guessed my animal! | The computer wins! (by guessing your animal) | |
Answering the second question in a game where the user is thinking of a lion (and already said "no" to having feathers). | So it is a mammal, but doesn't have stripes | |
| ||
No stripes, and now it doesn't hop | Nope, not an elephant. | |
| ||
Now the GUI/View is called by the model to prompt the user to enter what information was being thought of (it was lion, not elephant, the user tells the computer this is the case.) Note that the model has displayed the path from the beginning by calling the view appropriately -- the model must keep the path to make this possible. The user then enters the new information, in this case that the user was thinking of a lion.
The model calls the view's getNewInfoLeaf method to display the dialog labeled New Information Needed which can be dragged/moved so that the user can see the responses in the main game window. This method in the view will get information from the user then call the model's addNewQuestion method which you will write.
Now the user is prompted (the model calls the appropriate method in the GUi/View) to enter a question differentiating a lion from an elephant to grow the tree of knowledge used in the game. The model calls the view's getDifferentiator method which, after getting a differentiating question from the user will call the model's addNewKnowledge method.
Again, the user can drag/move the New Question Needed dialog to make the main game window more visible.
At this point if we play a new game the question "Does it have
tusks" will be incorporated into the tree -- it is the
differentiator leading to the leaves elephant and lion. The user can
play more, and ultimately decide to save the game/tree to a file for
playing again. Saving a file is a menu-option which the view relays to
the model's method write
which takes a
FileWriter
parameter and writes a tree to this file so that
the game can be played again by reading from the file. The user chooses
to save a game from the File menu as shown below.
As shown in the screen shots above, the user selects
a file
in which the tree/game will be saved. The default dialog
box for choosing a filename specifies the name of the file
the user originally entered, but in the run above a different name is
used. It's a good idea to use a different name for the file until you
know your program works.
The Model for the Twenty Questions Game
Model communicates with View
To display messages to the user the model can call
myView.showMessage
to display one string or
myView.update
to display all the strings in
an ArrayList of strings (or, in general, all the objects
in some collection). The model's method addNewQuestion
, which
has been started for you, shows some of this in action.
The AnimalGameModel Class
Your model class will need to implement IAnimalModel
to play the
game, in particular you should start with the AnimalGameModel
class
given to you and add/modify it as needed.
Recall that in the MVC architecture we used previously communication
from the View came to the model via the process
method. In
this program, however, the view communicates with the model using three
methods. Some of the calls are started by the user, e.g., loading a new
file or playing a new game. Other calls are started by the model itself,
e.g., the model calls appropriate methods in the view which in turn call
a method in the model, e.g., when adding new information and questions
to a game.
See the javadoc for details but the idea is you'll write these methods:
processYesNo
will change model state and display
information to the user/view for another yes/no response.
This will call either the view's update
method to ask
a new yes/no question.
or the view's
getNewInfoLeaf
method if the computer has to give up (in
the latter case the update
method will likely be called too
to display a prompt to the user.)
addNewQuestion
when the client indicates the computer
didn't guess properly and the client was thinking of "is it a lion" as
shown above.
This will call the view's update
method and the view's
getDifferentiator
method.
addNewKnowledge
when the client says "does it have
tusks" to differentiate between the yes/no last question the computer
got wrong.
This should update state and call newGame
newGame
will call the view's update
method just as was done from processYesNo
in asking a
yes/no question, but will start at the root.
The model class communicates back-and-forth with the view to update the state of the game, e.g., to move down the tree and then restart from the root of the tree for a new game. The model should maintain as an object invariant a reference/pointer to the current node in the tree whose question the user answers using the view. For example, this current node is initially the root. Depending on the user's response to the first question (and to subsequent questions) the current node is updated to be the left- or right-child according to the user anwering 'yes' or 'no'.
You'll need a myCurrentNode
and a myRoot
to
help traverse the tree.
In the process of playing a game, myCurrent
will eventually
reach a leaf node. Then you'll need to call the appropriate
view methods to start the process of adding new information to a tree/game.
You'll want to implement
private helper methods in your
AnimalGameModel
class to help with the methods you must
implement as part of the interface.
You'll need to implement a method to write information to a file.
To write the file you'll need
to read the API for java.io.FileWriter
, in particular
you'll
only need to use the the write
method that accepts
a String parameter -- be sure to terminate each string with
a newline character, e.g., something like the following:
The newline character, "\n", writes a "new line" and is read as 'slash-n' or 'backslash-n'.
For the run above, the sample file animal.txt
is reproduced below.
The tree that corresponds to this file is shown below. You'll need to
construct a tree like this in the program you write. Note that yes
answers in the tree are shown as left/blue arrows, no answers are
right/red arrows. The leaf nodes are shown only with the animal
information rather than the entire question, e.g., Is it an
elephant
Input/Output, Preorder Traversals
#Q:Does it have feathers
#Q:Does it live in a barnyard
Is it a chicken
#Q:is it wise
Is it an owl
#Q:does it gobble
Is it a turkey
#Q:does it say "Nevermore!"
Is it a raven
Is it an eagle
#Q:Is it a mammal
#Q:does it have stripes
Is it a tiger
#Q:does it hop
Is it a kangaroo
Is it an elephant
Is it a gila monster