scg/ch11/Question

From FANG

Jump to: navigation, search

001 package scg.ch11;
002 
003 import java.io.PrintWriter;
004 import java.util.Scanner;
005 
006 /**
007  * A {@link Question} is a type of {@link AdventurePage}, a page with
008  * two different "following" pages: a yes page and a no page. Because it
009  * isa {@link AdventurePage}, a {@link Question} also has a parent (the
010  * page which led us here), text (the question), and a reference to the
011  * book in which this page appears.
012  */
013 public class Question
014   extends AdventurePage {
015   /** reference to the no tree */
016   private int noNdx;
017 
018   /** reference to the yes tree */
019   private int yesNdx;
020 
021   /**
022    * Construct a new {@link Question} from values read from the file to
023    * which the given {@link Scanner} is attached.
024    *
025    @param  book     the {@link AdventureBook} to which this page
026    *                  belongs
027    @param  scanner  input {@link Scanner} attached to an {@link
028    *                  AdventureBook} file; must be positioned just after
029    *                  the type identification line in a {@link Question}
030    *                  entry.
031    */
032   public Question(AdventureBook book, Scanner scanner{
033     this(book, scanner.nextLine(), scanner.nextInt(), scanner.nextInt(),
034       scanner.nextInt());
035     scanner.skip(".*\n");// skip to the end of the line
036   }
037 
038   /**
039    * The primary constructor for a {@link Question}. Takes the book in
040    * which the question appears, the text of the question, and the
041    * indexes of the parent, yes, and no pages for this question.
042    *
043    @param  book       the {@link AdventureBook} containing this
044    *                    question
045    @param  text       the text content of this page
046    @param  parentNdx  index (page number) of the page leading to this
047    *                    page; NO_SUCH_PAGE if there is no parent or
048    *                    parent is unknown.
049    @param  yesNdx     index (page number) of the page following on a
050    *                    yes answer. NO_SUCH_PAGE if there is no yespage
051    *                    or yes page is unknown; should always be known!
052    @param  noNdx      index (page number) of the page following on a
053    *                    no answer. NO_SUCH_PAGE if there is no no page
054    *                    or no page is unknown; should always be known!
055    */
056   public Question(AdventureBook book, String text, int parentNdx,
057     int yesNdx, int noNdx{
058     super(book, text, parentNdx);
059     setYesNdx(yesNdx);
060     setNoNdx(noNdx);
061   }
062 
063   /**
064    * Play the game by asking this question. Based on user's response to
065    * the question, continue play by "turning" to the yes page or the no
066    * page.
067    */
068   @Override
069   public boolean play() {
070     int nextPageNdx = NO_SUCH_PAGE;
071     if (TwentyQuestions.answersYes(getText())) {
072       nextPageNdx = getYesNdx();
073     } else {
074       nextPageNdx = getNoNdx();
075     }
076     AdventurePage nextPage = getBook().get(nextPageNdx);
077     return nextPage.play();
078   }
079 
080   /**
081    * Convert this question to a string. The processing puts Q: in front
082    * of the question's text and follows it with the yes and no decision
083    * trees, each indented two spaces.
084    *
085    @return  string representation (with indentation) of the
086    *          DecisionTree
087    */
088   @Override
089   public String toString() {
090     String yesString = getYes().toString();
091     String noString = getNo().toString();
092     return "Q: " + getText() + "\n  " +
093       yesString.replaceAll("\n""\n  "+ "\n  " +
094       noString.replaceAll("\n""\n  ");
095   }
096 
097   /**
098    * Extend the decision tree with a new item. Given the wrong answer
099    * (already stored in the {@link AdventureBook}), prompt the user for
100    * the right answer and enough information to tell the right from the
101    * wrong in future games. Then build a new {@link Question} and {@link
102    * Answer} structure (a question with the right and wrong answers as
103    * children) and replace the wrong answer in the {@link AdventureBook}
104    * with the new question.<br />
105    *
106    @param  wrongAnswer  reference to an Answer in the tree, the answer
107    *                      which was guessed incorrectly
108    */
109   public void userProvidesNewAnswer(Answer wrongAnswer{
110     // Get the name of the correct object
111     String correctAnswerText = TwentyQuestions.getLine(
112         "What were you thinking of?");
113 
114     // And a question to differentiate right from wrong
115     String differentiatingQuestionText = TwentyQuestions.getLine(
116         "What question could differentiate between a \"" +
117         wrongAnswer.getText() + "\" and a \"" + correctAnswerText +
118         "\"?");
119 
120     // And whether "yes" means the new object or not
121     boolean newAnswerIsYes = TwentyQuestions.answersYes(
122         "Which answer means \"" + correctAnswerText +
123         "\" is the right answer?");
124 
125     // Make a new answer and a new question. Attach the two answers,
126     // right and wrong, to the yes/no or no/yes positions of the new
127     // question (according to what the player told us)
128     Answer correctAnswer = new Answer(getBook(), correctAnswerText,
129         NO_SUCH_PAGE);
130 
131     Answer newYes = null;
132     Answer newNo = null;
133     if (newAnswerIsYes{
134       newYes = correctAnswer;
135       newNo = wrongAnswer;
136     } else {
137       newYes = wrongAnswer;
138       newNo = correctAnswer;
139     }
140 
141     Question differentiatingQuestion = new Question(getBook(),
142         differentiatingQuestionText, getNdx(), newYes.getNdx(),
143         newNo.getNdx());
144 
145     // Fix up the last question so instead of guessing wrongAnswer, we
146     // ask differentiatingQuestion. Need to know whether the wrongAnswer
147     // came from the yes or the no branch of the last question
148     if (isYesChild(wrongAnswer.getNdx())) {
149       setYesNdx(differentiatingQuestion.getNdx());
150     } else {
151       setNoNdx(differentiatingQuestion.getNdx());
152     }
153   }
154 
155   /**
156    * Get a reference to the no page.
157    *
158    @return  the actual page following this one on answer of no.
159    */
160   private AdventurePage getNo() {
161     return getBook().get(getNoNdx());
162   }
163 
164   /**
165    * Get the index (page number) of the page following this one on an
166    * answer of "no".
167    *
168    @return  index of the page following this one (in the book) if the
169    *          answer is "no"
170    */
171   private int getNoNdx() {
172     return noNdx;
173   }
174 
175   /**
176    * Get a reference to the yes page.
177    *
178    @return  the actual page following this one on answer of yes.
179    */
180   private AdventurePage getYes() {
181     return getBook().get(getYesNdx());
182   }
183 
184   /**
185    * Get the index (page number) of the page following this one on an
186    * answer of "yes".
187    *
188    @return  index of the page following this one (in the book) if the
189    *          answer is "yes"
190    */
191   private int getYesNdx() {
192     return yesNdx;
193   }
194 
195   /**
196    * Does queryYesNdx refer to (index) the same {@link AdventurePage} as
197    * the yesNdx field of this {@link Question}?
198    *
199    @param   queryYesNdx  index of the page to check against yesNdx
200    *
201    @return  true if yesNdx and queryYesNdx are identically the same;
202    *          false otherwise
203    */
204   private boolean isYesChild(int queryYesNdx{
205     return (getYesNdx() == queryYesNdx);
206   }
207 
208   /**
209    Set the index of the no page to the given value. If the value is
210    * valid (already in the book), make sure to update the no page's
211    * parent to be the current page.
212    *
213    @param  noNdx  index of page following this one on an answer of
214    *                "no"
215    */
216   private void setNoNdx(int noNdx{
217     this.noNdx = noNdx;
218     if ((noNdx != NO_SUCH_PAGE&& (noNdx < getBook().size())) {
219       getBook().get(noNdx).setParentNdx(getNdx());
220     }
221   }
222 
223   /**
224    Set the index of the yes page to the given value. If the value is
225    * valid (already in the book), make sure to update the yes page's
226    * parent to be the current page.
227    *
228    @param  yesNdx  index of page following this one on an answer of
229    *                 "yes"
230    */
231   private void setYesNdx(int yesNdx{
232     this.yesNdx = yesNdx;
233     if ((yesNdx != NO_SUCH_PAGE&& (yesNdx < getBook().size())) {
234       getBook().get(yesNdx).setParentNdx(getNdx());
235     }
236   }
237 
238   /**
239    * Save this {@link Question} to the given {@link PrintWriter}. Uses
240    {@link AdventurePage} save method for first part of the record;
241    * after that prints the indexes for yes and no pages on separate
242    * lines.
243    *
244    @param  out  open text file with write pointer at the end, just
245    *              where this question should be included.
246    */
247   @Override
248   protected void save(PrintWriter out{
249     super.save(out);
250     out.println(getYesNdx());
251     out.println(getNoNdx());
252   }
253 }
254 
255 //Uploaded on Mon Mar 29 21:41:03 EDT 2010


Download/View scg/ch11/Question.java





Views
Personal tools
Add to 
del.icio.usAdd to 
diggAdd to 
FacebookAdd to 
favoritesAdd to 
GoogleAdd to 
MySpaceAdd to 
PrintAdd to 
SlashdotAdd to 
StumbleUponAdd to 
Twitter

Games
Games