import ecs100.*;
import java.util.*;
import java.io.*;
import java.nio.file.*;
import java.awt.Color;
public class DecisionTree {
public DTNode theTree; // root of the decision tree;
/**
* Setup the GUI and make a sample tree
*/
public static void main(String[] args){
DecisionTree dt = new DecisionTree();
dt.setupGUI();
dt.loadTree("sample-animal-tree.txt");
}
/**
* Set up the interface
*/
public void setupGUI(){
UI.addButton("Load Tree", ()->{loadTree(UIFileChooser.open("File with a Decision Tree"));});
UI.addButton("Print Tree", this::printTree);
UI.addButton("Run Tree", this::runTree);
UI.addButton("Grow Tree", this::growTree);
// UI.addButton("Save Tree", this::saveTree); // for completion
// UI.addButton("Draw Tree", this::drawTree); // for challenge
UI.addButton("Reset", ()->{loadTree("sample-animal-tree.txt");});
UI.addButton("Quit", UI::quit);
UI.setDivider(0.5);
}
/**
* Print out the contents of the decision tree in the text pane.
* The root node should be at the top, followed by its "yes" subtree, and then
* its "no" subtree.
* Each node should be indented by how deep it is in the tree.
* Needs a recursive "helper method" which is passed a node and an indentation string.
* (The indentation string will be a string of space characters)
*/
public void printTree(){
UI.clearText();
/*# YOUR CODE HERE */
}
/**
* Run the tree by starting at the top (of theTree), and working
* down the tree until it gets to a leaf node (a node with no children)
* If the node is a leaf it prints the answer in the node
* If the node is not a leaf node, then it asks the question in the node,
* and depending on the answer, goes to the "yes" child or the "no" child.
*/
public void runTree() {
/*# YOUR CODE HERE */
}
/**
* Grow the tree by allowing the user to extend the tree.
* Like runTree, it starts at the top (of theTree), and works its way down the tree
* until it finally gets to a leaf node.
* If the current node has a question, then it asks the question in the node,
* and depending on the answer, goes to the "yes" child or the "no" child.
* If the current node is a leaf it prints the decision, and asks if it is right.
* If it was wrong, it
* - asks the user what the decision should have been,
* - asks for a question to distinguish the right decision from the wrong one
* - changes the text in the node to be the question
* - adds two new children (leaf nodes) to the node with the two decisions.
*/
public void growTree () {
/*# YOUR CODE HERE */
}
// You will need to define methods for the Completion and Challenge parts.
// Written for you
/**
* Loads a decision tree from a file.
* Each line starts with either "Question:" or "Answer:" and is followed by the text
* Calls a recursive method to load the tree and return the root node,
* and assigns this node to theTree.
*/
public void loadTree (String filename) {
if (!Files.exists(Path.of(filename))){
UI.println("No such file: "+filename);
return;
}
try{theTree = loadSubTree(new ArrayDeque<String>(Files.readAllLines(Path.of(filename))));}
catch(IOException e){UI.println("File reading failed: " + e);}
}
/**
* Loads a tree (or subtree) from a Scanner and returns the root.
* The first line has the text for the root node of the tree (or subtree)
* It should make the node, and
* if the first line starts with "Question:", it loads two subtrees (yes, and no)
* from the scanner and add them as the children of the node,
* Finally, it should return the node.
*/
public DTNode loadSubTree(Queue<String> lines){
Scanner line = new Scanner(lines.poll());
String type = line.next();
String text = line.nextLine().trim();
DTNode node = new DTNode(text);
if (type.equals("Question:")){
DTNode yesCh = loadSubTree(lines);
DTNode noCh = loadSubTree(lines);
node.setChildren(yesCh, noCh);
}
return node;
}
}