import AgentWorld.*;

// The root of the "object hierarchy" for Decision Trees.
// (Notice this is an ABSTRACT CLASS, which means instances
// of it are never created. Instead, you make instances of
// of its subclasses.)
//
// Here's a partial sketch of the hierarchy I used:
//
//    abstract class DecisionTree
//       abstract class InteriorNode
//                  class ObjectType_InteriorNode
//                  <... you should add some more here>
//                class  LeafNode

abstract class DecisionTree
{ boolean debugging = false; // When true, print out useful debugging info.

  // The constructor.
  DecisionTree()
  {
  }

  // One way to draw a tree in plain text is to use indentation.
  void indentTree(int indent)
  {
    for(int i = 1; i <= indent; i++)
    { // Use some bars to help visual alignment of sibling nodes.
      if (i % 3 == 0) System.out.print("|");
      else System.out.print(" ");
    }
  }

  void printTree(int maxDepth)
  { 
    printTree(1, maxDepth); // Start counting at depth 1.
  }

  // All of your subclasses must implement the following functions
  // (your java compiler should complain if you don't).

  // Print a subtree that is at this depth (also depth is used
  // to choose the number of spaces to indent).
  // Don't print beyond max depth (instead just print "...");
  // 
  abstract void printTree(int currentDepth, int maxDepth);

  // Given these sensor readings, does this subtree
  // think its direction is a good one in which to move?
  // (Ie, if a leaf node, return true or false.
  // if an interior node, recursively follow the outgoing
  // arc that matches these sensors.)
  abstract boolean makeDecision(Sensors sensors);

  // Count the number of interior nodes in this subtree.
  abstract int countInteriorNodes();
  // Count the number of leaves in this subtree.
  abstract int countLeaves();
}
