//Omar Khan //CSE 143 Section AA import java.util.*; import java.io.*; //This program builds a tree for a game similar to 20 questions using QuestionNodes //and displays it using the passed UserInterface object. It also keeps track of the total //games played and won for an instance of play. public class QuestionTree{ private UserInterface ui; private QuestionNode root; private int played; private int won; //Passes in the UserInterface and starts the tree with a single QuestionNode that contains the answer "Computer". //Throws an IllegalArgumentException if UserInterface is null public QuestionTree(UserInterface ui){ //Checks if passed in ui is null and throws an exception accordingly if(ui == null){ throw new IllegalArgumentException(); } this.ui = ui; this.played = 0; this.won = 0; root = new QuestionNode("computer"); } //This method is used to play a game, it builds the question tree as the game progresses. public void play(){ played++; root = play(root); } //Helper method to play the game, returns a //QuestionNode and requires a QuestionNode be passed in. private QuestionNode play(QuestionNode otherRoot){ if(otherRoot.isAnswer()){ ui.print("Would your object happen to be " + otherRoot.data + "?"); if(ui.nextBoolean()){ won++; ui.println("I win!"); return otherRoot; }else{ ui.print("I lose. What is your object?"); String answer = ui.nextLine(); ui.print("Type a yes/no question to distinguish your item from " + otherRoot.data + ":"); String question = ui.nextLine(); ui.print("And what is the answer for your object?"); otherRoot = add(otherRoot, question, answer, ui.nextBoolean()); return otherRoot; } }else{ ui.print(otherRoot.data); if(ui.nextBoolean()){ otherRoot.yes = play(otherRoot.yes); }else{ otherRoot.no = play(otherRoot.no); } } return otherRoot; } //Helper method to add a new question and answer, used to expand the tree. private QuestionNode add(QuestionNode otherRoot,String question, String answer, boolean y){ QuestionNode currQuestion = new QuestionNode(question); if(y){ currQuestion.yes = new QuestionNode(answer); currQuestion.no = otherRoot; }else{ currQuestion.yes = otherRoot; currQuestion.no = new QuestionNode(answer); } return currQuestion; } //This method saves the contents of the tree in an appropriate //format to the passed in PrintStream object. //Throws an IllegalArgumentException if passed PrintStream is null public void save(PrintStream output){ if(output == null){ throw new IllegalArgumentException(); } save(output, root); } //Helper method for save which takes in a PrintStream object and a QuestionNode. private void save(PrintStream output, QuestionNode otherRoot){ if(otherRoot.isAnswer()){ output.println("A:" + otherRoot.data); }else{ output.println("Q:" + otherRoot.data); save(output, otherRoot.yes); save(output, otherRoot.no); } } //This method builds a new tree using the contents of a passed in Scanner object. //Throws an IllegalArgumentException if passed Scanner is null. public void load(Scanner input){ if(input == null){ throw new IllegalArgumentException(); } root = load(input, root); } //Helper method that takes in a Scanner object //and a QustionNode, also returns a QuestionNode. private QuestionNode load(Scanner input, QuestionNode otherRoot){ if(!input.hasNextLine()){ return otherRoot; }else{ String data = input.nextLine(); otherRoot = new QuestionNode(data.substring(2)); if(data.startsWith("Q:")){ otherRoot.yes = load(input, otherRoot.yes); otherRoot.no = load(input, otherRoot.no); } } return otherRoot; } //Returns the total games won. public int gamesWon(){ return won; } //Returns total games played. public int totalGames(){ return played; } }