200 lines
5.8 KiB
Java
200 lines
5.8 KiB
Java
/**
|
|
*
|
|
* Matt Jensen
|
|
* CS145 - Lab 6
|
|
* 5/30/19
|
|
*
|
|
*/
|
|
|
|
import java.io.*;
|
|
import java.util.*;
|
|
|
|
public class QuestionTree {
|
|
|
|
private QuestionNode root;
|
|
private UserInterface ui;
|
|
private Stack<QuestionNode> unanswered;
|
|
private int totalGames;
|
|
private int gamesWon;
|
|
private QuestionNode lastQuestion;
|
|
|
|
public QuestionTree(UserInterface ui) {
|
|
this.setUserInterface(ui);
|
|
this.setRoot(null);
|
|
}
|
|
public QuestionTree(UserInterface ui, QuestionNode root) {
|
|
this.setUserInterface(ui);
|
|
this.setRoot(root);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Public Methods.
|
|
*
|
|
*/
|
|
public void replaceYes(QuestionNode newQuestion, QuestionNode parent) {
|
|
parent.addYes(newQuestion);
|
|
}
|
|
|
|
public void save(PrintStream output) {
|
|
this.print(output, this.getRoot());
|
|
//output.print("hello");
|
|
}
|
|
private void print(PrintStream output, QuestionNode current) {
|
|
if(current == null) {
|
|
return;
|
|
} else {
|
|
output.print(current.toString(true));
|
|
if(current.hasYes()){
|
|
output.println();
|
|
this.print(output, current.getYes());
|
|
}
|
|
if(current.hasNo()){
|
|
output.println();
|
|
this.print(output, current.getNo());
|
|
}
|
|
}
|
|
return;
|
|
|
|
}
|
|
public void play() {
|
|
this.lastQuestion = null;
|
|
if( this.getRoot() == null ) {
|
|
this.ui.print("First question?");
|
|
this.setRoot(new QuestionNode(this.ui.nextLine(), true));
|
|
this.ui.print("If yes?");
|
|
this.getRoot().addYes(new QuestionNode(this.ui.nextLine()));
|
|
this.ui.print("If no?");
|
|
this.getRoot().addNo(new QuestionNode(this.ui.nextLine()));
|
|
}
|
|
QuestionNode guess = this.guess(this.getRoot());
|
|
this.ui.print("Would your object happen to be " + guess.toString() + "?");
|
|
boolean correctGuess = this.ui.nextBoolean();
|
|
if( correctGuess ) {
|
|
this.ui.println("I win!");
|
|
gamesWon++;
|
|
} else {
|
|
this.ui.print("I lose.");
|
|
this.addDistinction(guess);
|
|
}
|
|
totalGames++;
|
|
}
|
|
private QuestionNode getActual(QuestionNode guess) {
|
|
this.ui.print("What is your object?");
|
|
QuestionNode actual = new QuestionNode(this.ui.nextLine(), false);
|
|
return actual;
|
|
}
|
|
private QuestionNode getNewQuestion(QuestionNode guess) {
|
|
this.ui.println("Type a yes/no question to distinguish your item from " + guess.toString() + ":");
|
|
QuestionNode newQuestion = new QuestionNode(this.ui.nextLine(), true);
|
|
return newQuestion;
|
|
}
|
|
private boolean getReplaceYes(QuestionNode guess, QuestionNode newQuestion) {
|
|
this.ui.println("And what is the answer for " + newQuestion + "?");
|
|
boolean replaceYes = this.ui.nextBoolean();
|
|
return replaceYes;
|
|
}
|
|
private void addDistinction(QuestionNode guess) {
|
|
QuestionNode actual = this.getActual(guess);
|
|
QuestionNode newQuestion = this.getNewQuestion(guess);
|
|
boolean replaceYes = this.getReplaceYes(guess, newQuestion);
|
|
if( replaceYes ) {
|
|
newQuestion.addYes(actual);
|
|
newQuestion.addNo(guess);
|
|
} else {
|
|
newQuestion.addNo(actual);
|
|
newQuestion.addYes(guess);
|
|
}
|
|
this.replaceYes(newQuestion, this.lastQuestion);
|
|
}
|
|
|
|
private QuestionNode guess(QuestionNode current) {
|
|
if( current == null || current.isAnswer() ) {
|
|
return current;
|
|
} else {
|
|
this.ui.print(current.toString());
|
|
this.lastQuestion = current;
|
|
if( this.ui.nextBoolean() ) {
|
|
return this.guess(current.getYes());
|
|
} else {
|
|
return this.guess(current.getNo());
|
|
}
|
|
}
|
|
}
|
|
public int totalGames() {
|
|
return this.totalGames;
|
|
}
|
|
public int gamesWon() {
|
|
return this.gamesWon;
|
|
}
|
|
public QuestionNode getRoot() {
|
|
return this.root;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Private Methods.
|
|
*
|
|
*/
|
|
|
|
private void setRoot(QuestionNode root) {
|
|
this.root = root;
|
|
}
|
|
|
|
// pre: ui not null
|
|
private void setUserInterface(UserInterface ui) {
|
|
if( ui == null) {
|
|
throw new IllegalArgumentException();
|
|
}
|
|
this.ui = ui;
|
|
}
|
|
|
|
// pre: coming from a file.
|
|
private boolean containsQuestion(String line) {
|
|
return line.charAt(0) == 'Q';
|
|
}
|
|
|
|
public void load(Scanner input) {
|
|
// base case
|
|
if( ! input.hasNextLine() ) {
|
|
return;
|
|
}
|
|
Stack<QuestionNode> remaining = new Stack<QuestionNode>();
|
|
this.build(input, remaining);
|
|
return;
|
|
}
|
|
private void build(Stack<QuestionNode> remaining, QuestionNode root) {
|
|
|
|
}
|
|
private void build(Scanner input, Stack<QuestionNode> remaining) {
|
|
// base case
|
|
if( ! input.hasNextLine() ) {
|
|
if( ! remaining.empty() ) {
|
|
throw new IllegalArgumentException("question unanswered");
|
|
}
|
|
return;
|
|
} else {
|
|
String line = input.nextLine();
|
|
QuestionNode current = new QuestionNode(line, containsQuestion(line));
|
|
if( remaining.empty() ) {
|
|
if( this.getRoot() == null ) {
|
|
this.setRoot(current);
|
|
} else {
|
|
throw new IllegalArgumentException("bad root element");
|
|
}
|
|
} else {
|
|
QuestionNode last = remaining.pop();
|
|
last.addAnswer(current);
|
|
if(last.needsAnswer() ) {
|
|
remaining.add(last);
|
|
}
|
|
}
|
|
if( ! current.isAnswer() ) {
|
|
remaining.add(current);
|
|
}
|
|
this.build(input, remaining);
|
|
}
|
|
return;
|
|
}
|
|
}
|