diff --git a/ss2010/gdi2/java/Project3/.classpath b/ss2010/gdi2/java/Project3/.classpath
new file mode 100644
index 00000000..b10b8d9b
--- /dev/null
+++ b/ss2010/gdi2/java/Project3/.classpath
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/ss2010/gdi2/java/Project3/.project b/ss2010/gdi2/java/Project3/.project
new file mode 100644
index 00000000..b2ee4de7
--- /dev/null
+++ b/ss2010/gdi2/java/Project3/.project
@@ -0,0 +1,17 @@
+
+
+ Project3
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/ss2010/gdi2/java/Project3/.settings/org.eclipse.jdt.core.prefs b/ss2010/gdi2/java/Project3/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 00000000..9aeceb46
--- /dev/null
+++ b/ss2010/gdi2/java/Project3/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,12 @@
+#Sat Jun 05 18:13:09 CEST 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.6
diff --git a/ss2010/gdi2/java/Project3/quizdb.txt b/ss2010/gdi2/java/Project3/quizdb.txt
new file mode 100644
index 00000000..8ac0ba66
--- /dev/null
+++ b/ss2010/gdi2/java/Project3/quizdb.txt
@@ -0,0 +1,9 @@
+Is it a mammal?
+Is it bigger than a tiger?
+Does it have stripes?
+Zevra
+elephant
+mouse
+Does it live underwater?
+trout
+robin
diff --git a/ss2010/gdi2/java/Project3/src/BinaryTree.java b/ss2010/gdi2/java/Project3/src/BinaryTree.java
new file mode 100644
index 00000000..392722d2
--- /dev/null
+++ b/ss2010/gdi2/java/Project3/src/BinaryTree.java
@@ -0,0 +1,26 @@
+import java.util.List;
+
+/**
+ * A simple generic interface for binary trees to be used by the Quiz class.
+ *
+ * @param The type of the data held in nodes of the tree.
+ */
+public interface BinaryTree {
+
+ /**
+ * Initiates a new search from the root of this binary tree. This method
+ * can be implemented by creating an anonymous class of type BinaryTreeSearch,
+ * similar to many Iterator implementations.
+ *
+ * @return A new object of type BinaryTreeSearch.
+ */
+ public BinaryTreeSearch binaryTreeSearch();
+
+ /**
+ * Produces a pre-order traversal sequence for this tree.
+ *
+ * @return A list of data objects in pre-order.
+ */
+ public List preorder();
+
+}
diff --git a/ss2010/gdi2/java/Project3/src/BinaryTreeSearch.java b/ss2010/gdi2/java/Project3/src/BinaryTreeSearch.java
new file mode 100644
index 00000000..2c57d495
--- /dev/null
+++ b/ss2010/gdi2/java/Project3/src/BinaryTreeSearch.java
@@ -0,0 +1,67 @@
+/**
+ * Interface for a generic search in a binary tree. A binary tree search is
+ * initiated at the root of a tree and maintains the information which node
+ * is the current node.
+ *
+ * The tree is searched by moving down from the current node to its left or
+ * right child. The tree can be modified at the current node by setting the
+ * data or adding new children with new data.
+ *
+ * @param The type of the data held in nodes of the tree.
+ */
+public interface BinaryTreeSearch {
+
+ /**
+ * The data stored at the current node.
+ *
+ * @return The data at the current node.
+ */
+ public A getData();
+
+ /**
+ * Checks whether the current node is a leaf node.
+ *
+ * @return True if the search arrived at a leaf node.
+ */
+ public boolean isLeaf();
+
+ /**
+ * Checks whether the current node has a left child.
+ *
+ * @return True if the current node has a left child.
+ */
+ public boolean hasLeftChild();
+
+ /**
+ * Checks whether the current node has a right child.
+ *
+ * @return True if the current node has a right child.
+ */
+ public boolean hasRightChild();
+
+ /**
+ * Moves down to the left child.
+ *
+ * @throws NoSuchElementException if the current node has no left child.
+ */
+ public void nextLeftChild();
+
+ /**
+ * Moves down to the right child.
+ *
+ * @throws NoSuchElementException if the current node has no right child.
+ */
+ public void nextRightChild();
+
+ /**
+ * Replaces the current node and creates new children initialized to hold the
+ * provided data. If the data for a child is null, does not create the
+ * corresponding child.
+ *
+ * @param data The data for the current node.
+ * @param leftData The data for the new left child.
+ * @param rightData The data for the new right child.
+ */
+ public void setNode(A data, A leftData, A rightData);
+
+}
diff --git a/ss2010/gdi2/java/Project3/src/LinkedBinaryTree.java b/ss2010/gdi2/java/Project3/src/LinkedBinaryTree.java
new file mode 100644
index 00000000..582571d1
--- /dev/null
+++ b/ss2010/gdi2/java/Project3/src/LinkedBinaryTree.java
@@ -0,0 +1,405 @@
+import java.io.Serializable;
+import java.util.*;
+
+/**
+ * A binary tree in linked representation. Tree nodes are stored as objects consisting of
+ * pointers to their left and right child and to their associated data.
+ *
+ * @param The type of the data held in nodes of the tree.
+ */
+public class LinkedBinaryTree implements BinaryTree {
+
+ /**
+ * NodeClass
+ *
+ * @param
+ */
+ private class LinkedNode {
+
+ /**
+ * Data of the Node
+ */
+ private Datatype m_data = null;
+
+ /**
+ * Left Child; another node or null
+ */
+ private LinkedNode m_leftchild = null;
+
+ /**
+ * Right Child; another node or null
+ */
+ private LinkedNode m_rightchild = null;
+
+ /**
+ * Constructor for a Leaf
+ * @param data Data of the Leaf
+ */
+ public LinkedNode(Datatype data)
+ {
+ this.m_data = data;
+ }
+
+ /**
+ * Constructor of a node with childs
+ *
+ * @param data Data of the Node
+ * @param leftchild Data of left child
+ * @param rightchild Data of right child
+ */
+ public LinkedNode(Datatype data, LinkedNode leftchild, LinkedNode rightchild)
+ {
+ this.m_data = data;
+ this.m_leftchild = leftchild;
+ this.m_rightchild = rightchild;
+ }
+
+ /**
+ * @return stored Data
+ */
+ public Datatype getData() {
+ return m_data;
+ }
+
+ /**
+ * Set Data of the Node
+ *
+ * @param data
+ */
+ public void setData(Datatype data) {
+ m_data = data;
+ }
+
+ /**
+ * @return Left Child (can be null)
+ */
+ public LinkedNode getLeftChild() {
+ return m_leftchild;
+ }
+
+ /**
+ * Sets Left Child
+ *
+ * @param leftchild Data
+ */
+ public void setLeftChild(LinkedNode leftchild) {
+ m_leftchild = leftchild;
+ }
+
+ /**
+ * @return Right Child (can be null)
+ */
+ public LinkedNode getRightChild() {
+ return m_rightchild;
+ }
+
+ /**
+ * Sets Right Child
+ *
+ * @param rightchild Data
+ */
+ public void setRightChild(LinkedNode rightchild) {
+ m_rightchild = rightchild;
+ }
+ }
+
+ /**
+ * Rootnode
+ */
+ private LinkedNode root = null;
+
+ /**
+ * Clones a Serializable Data object
+ * @param src
+ * @return cloned dataobject
+ */
+ public static Serializable cloneSerializable(Serializable src)
+ {
+ try {
+ java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
+ java.io.ObjectOutputStream oos = new java.io.ObjectOutputStream(baos);
+ oos.writeObject(src);
+ oos.flush();
+ oos.close();
+ java.io.ByteArrayInputStream bais = new
+ java.io.ByteArrayInputStream(baos.toByteArray());
+ java.io.ObjectInputStream ois = new java.io.ObjectInputStream(bais);
+ Object dest = ois.readObject();
+ ois.close();
+ return (Serializable)dest;
+ } catch (Throwable th) {
+ return src;
+ }
+ }
+
+ /**
+ * Definition of a Questionmark
+ */
+ public static final String QUESTIONMARK = "?";
+
+ /**
+ * Create a tree from a given animal game preorder.
+ *
+ * param The type of the data held in nodes of the tree.
+ * @param preorder The preorder to build the tree from.
+ * @return A new LinkedBinaryTree corresponding to the provided preorder.
+ */
+ public static LinkedBinaryTree createFromPreorder(List preorder) {
+
+ //Clone of preorder
+ List preordercopy = new ArrayList();
+
+ //Clone preorder
+ for(int i=0;i result = new LinkedBinaryTree();
+
+ //Sets Root, calculated by recursiv_createFormPreorder
+ result.setRoot(result.recursiv_createFromPreorder(preordercopy));
+
+ //Preorder was empty or not valid
+ if(result.getRoot() == null) {
+ throw new UnsupportedOperationException();
+ }
+
+ //Return constructed Tree
+ return result;
+ }
+
+ /**
+ * Create tree from Preorder recursiv nonstatic and with A-Parameter
+ *
+ * A must implement contains-function
+ *
+ * @param preorder
+ * @return Created Node or null
+ */
+ private LinkedNode recursiv_createFromPreorder(List preorder)
+ {
+ //check if there is data to parse
+ if( preorder.size() < 1){
+ return null;
+ }
+
+ //create new node for data
+ LinkedNode node = new LinkedNode(preorder.get(0));
+ preorder.remove(0);
+
+
+ //call recursiv if not an answer but a question
+ if(node.getData().toString().endsWith(QUESTIONMARK)) {
+ node.setLeftChild(recursiv_createFromPreorder(preorder));
+ node.setRightChild(recursiv_createFromPreorder(preorder));
+ }
+
+ //return node created
+ return node;
+ }
+
+ /**
+ * Create a pre-order traversal sequence for this tree.
+ *
+ * @return The pre-order sequence for this tree.
+ */
+ @Override
+ public List preorder() {
+
+ return recursiv_preorder(root);
+ }
+
+ /**
+ * Creates preorder from Tree, recursiv!
+ *
+ * @param node Node to start from
+ * @return preorderlist
+ */
+ private List recursiv_preorder(LinkedNode node){
+
+ //resultlist
+ List result = new ArrayList();
+
+ //still a node left?
+ if(node != null)
+ {
+ //add node data
+ result.add(node.getData());
+ //add all left child data
+ result.addAll(recursiv_preorder(node.getLeftChild()));
+ //add all right child data
+ result.addAll(recursiv_preorder(node.getRightChild()));
+ }
+
+ //return List
+ return result;
+ }
+
+ /**
+ * @return root node or null
+ */
+ private LinkedNode getRoot() {
+ return this.root;
+ }
+
+ /**
+ * Sets root node
+ *
+ * @param root New Rootnode
+ */
+ private void setRoot(LinkedNode root) {
+ this.root = root;
+ }
+
+ /**
+ * @return Retrurns a BinaryTreeSearch Object
+ */
+ @Override
+ public BinaryTreeSearch binaryTreeSearch() {
+ // Create anonymous class implementing BinaryTreeSearch
+ return new BinaryTreeSearch() {
+
+ /**
+ * Current Node is initialized with root
+ */
+ private LinkedNode currentNode = root;
+
+ /**
+ * Return Data of current Node
+ */
+ @Override
+ public A getData() {
+
+ //check if element is ok.
+ if( currentNode == null ||
+ currentNode.getData() == null) {
+ throw new NoSuchElementException();
+ }
+
+ //return data
+ return currentNode.getData();
+ }
+
+ /**
+ * Is CurrentNode a Leaf
+ */
+ @Override
+ public boolean isLeaf() {
+
+ //check if element is ok.
+ if( currentNode == null ||
+ currentNode.getData() == null) {
+ throw new NoSuchElementException();
+ }
+
+ //check if there is left and right data, if not its a leaf
+ if( currentNode.getLeftChild() == null &&
+ currentNode.getRightChild() == null)
+ {
+ return true;
+ }
+
+ //not a leaf
+ return false;
+ }
+
+ /**
+ * Moves CurrentNode Pointer to Left Child
+ */
+ @Override
+ public void nextLeftChild() {
+
+ //check if element is ok.
+ if( currentNode == null ||
+ currentNode.getLeftChild() == null) {
+ throw new NoSuchElementException();
+ }
+
+ //set current node to left child
+ currentNode = currentNode.getLeftChild();
+ }
+
+ /**
+ * Moves CurrentNode Pointer to Right Child
+ */
+ @Override
+ public void nextRightChild() {
+
+ //check if element is ok.
+ if( currentNode == null ||
+ currentNode.getRightChild() == null) {
+ throw new NoSuchElementException();
+ }
+
+ //sets current node to right child
+ currentNode = currentNode.getRightChild();
+ }
+
+ /**
+ * Sets current Node
+ *
+ * @param data Nodedata
+ * @param leftData Left Child data
+ * @param rightData Right child data
+ */
+ @Override
+ public void setNode(A data, A leftData, A rightData) {
+
+ //check datainput
+ if(data == null){
+ throw new UnsupportedOperationException();
+ }
+
+ //subnodes
+ LinkedNode left = new LinkedNode(leftData);
+ LinkedNode right = new LinkedNode(rightData);
+
+ //is root null? if yes create new node
+ if(currentNode == null)
+ {
+ root = new LinkedNode(data,left,right);
+ currentNode = root;
+ } else
+ {
+ //set currentNode to new data
+ currentNode.setData(data);
+ currentNode.setLeftChild(left);
+ currentNode.setRightChild(right);
+ }
+ }
+
+ /**
+ * @return Returns true if there is a left Child
+ */
+ @Override
+ public boolean hasLeftChild() {
+ //check if element is ok.
+ if( currentNode != null &&
+ currentNode.getLeftChild() != null) {
+ return true;
+ }
+
+ //no left child
+ return false;
+ }
+
+ /**
+ * @return Returns true if there is a Right Child
+ */
+ @Override
+ public boolean hasRightChild() {
+ //check if element is ok.
+ if( currentNode != null &&
+ currentNode.getRightChild() != null) {
+ return true;
+ }
+
+ //no right child
+ return false;
+ }
+ };
+ }
+
+}
diff --git a/ss2010/gdi2/java/Project3/src/Quiz.java b/ss2010/gdi2/java/Project3/src/Quiz.java
new file mode 100644
index 00000000..6521881a
--- /dev/null
+++ b/ss2010/gdi2/java/Project3/src/Quiz.java
@@ -0,0 +1,215 @@
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * A simple guessing game, where the user thinks of an animal, and the computer
+ * tries to guess it by asking a series of Yes/No questions. If it fails to guess
+ * it, the user provides new information for the computer to learn. An example round:
+ * Q: Computer, A: User
+ *
+ * Q: "Please think of an animal. I will try to find out what it is by asking you some yes/no questions."
+ * Q: "Is it a mammal? (Y/N)"
+ * A: "Y"
+ * Q: "Is it bigger than a tiger? (Y/N)"
+ * A: "Y"
+ * Q: "You were thinking of an elephant. Am I right? (Y/N)"
+ * A: "N"
+ * Q: "You win. What is the answer?"
+ * A: "whale"
+ * Q: "Please provide a yes/no question that distinguishes a whale from a elephant."
+ * A: "Does it live in the sea?"
+ * Q: "Does a whale live in the sea? (Y/N)"
+ * A: "Y"
+ *
+ * The next time the user thinks of a whale, the computer will guess it correctly:
+ *
+ * Q: "Please think of an animal. I will try to find out what it is by asking you some yes/no questions."
+ * Q: "Is it a mammal? (Y/N)"
+ * A: "Y"
+ * Q: "Is it bigger than a tiger? (Y/N)"
+ * A: "Y"
+ * Q: "Does it live in the sea? (Y/N)"
+ * A: "Y"
+ * Q: "You were thinking of a whale. Am I right? (Y/N)"
+ * A: "Y"
+ * Q: "I knew it!"
+ *
+ */
+public class Quiz {
+
+ /**
+ * The main method for interactive playing. Initializes a tree and starts game rounds
+ * until the user wants to quit. Finally saves learned data if the user agrees.
+ *
+ * @param args Command line arguments not used.
+ */
+ public static void main(String[] args)
+ {
+ // Text file containing a pre-order of old questions/animals
+ String filename = "quizdb.txt";
+
+ // Attempt to load the file. If it does not exist, initializes a default tree.
+ BinaryTree tree = load(filename);
+
+ // Provides user-interactive I/O
+ QuizIoAdapter ioAdapter = new UserIoAdapter();
+
+ // Initiializes a quiz object
+ Quiz quiz = new Quiz(tree, ioAdapter);
+
+ // Run the quiz until the user answers "N" to "Play again?"
+ do {
+ quiz.run();
+ } while (ioAdapter.askYesNo("Play again?"));
+
+ // Should we save the tree?
+ if (ioAdapter.askYesNo("Save any data I learned?")){
+ save(filename, tree);
+ }
+
+ ioAdapter.tell("Goodbye.");
+ }
+
+ /**
+ * Load the pre-order of an old tree from a text database.
+ *
+ * @param filename The name of the text database.
+ * @return A binary tree corresponding to the pre-order in the file or a
+ * default tree if reading the file failed.
+ */
+ public static BinaryTree load(String filename) {
+
+ List preorder;
+
+ try {
+ BufferedReader reader = new BufferedReader(new FileReader(filename));
+ preorder = new LinkedList();
+ while (reader.ready()) {
+ preorder.add(reader.readLine());
+ }
+ reader.close();
+
+ } catch (IOException e) {
+ System.out.println(e.getClass().getSimpleName() + ": " + e.getMessage());
+ System.out.println("Could not read input file " + filename + ", using default tree!");
+
+ // Default preorder
+ preorder = Arrays.asList("Is it a mammal?", "Is it bigger than a tiger?", "elephant",
+ "mouse", "Does it live underwater?", "trout", "robin");
+ }
+
+ // Invoke a methods to construct pre-order conversion for one of the two tree types
+ //return SequentialBinaryTree.createFromPreorder(preorder);
+ return LinkedBinaryTree.createFromPreorder(preorder);
+ }
+
+ /**
+ * Saves the pre-order of a tree to a text database.
+ *
+ * @param filename The name of the text database.
+ * @param tree The tree to save.
+ */
+ @SuppressWarnings("CallToThreadDumpStack")
+ public static void save(String filename, BinaryTree tree) {
+
+ List strings = tree.preorder();
+
+ try {
+ BufferedWriter writer = new BufferedWriter(new FileWriter(filename));
+
+ for (String line : strings) {
+ writer.write(line);
+ writer.newLine();
+ }
+ writer.close();
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ System.out.println("Could not write output file " + filename + "!");
+ }
+ }
+
+ // I/O can be either interactive (UserIoAdapter if run by main) or automatic (UnitTestIoAdapter if run by unit tests)
+ private QuizIoAdapter ioAdapter;
+
+ // The binary tree containing questions and animals
+ private BinaryTree tree;
+
+ /**
+ * Initialize a new quiz.
+ *
+ * @param tree A binary tree of strings containing questions and animals.
+ * @param ioAdapter The I/O adapter for this quiz.
+ */
+ public Quiz(BinaryTree tree, QuizIoAdapter ioAdapter) {
+ this.ioAdapter = ioAdapter;
+ this.tree = tree;
+ }
+
+ /**
+ * The main method running the quiz
+ */
+ public void run()
+ {
+ //Introduction
+ ioAdapter.tell("Please think of an animal. I will try to find out what it is by asking you some yes/no questions.");
+
+ //the treesearch
+ BinaryTreeSearch current = tree.binaryTreeSearch();
+
+ //Ask Question till leaf
+ while (!current.isLeaf()){
+ if(ioAdapter.askYesNo(current.getData())){
+ current.nextLeftChild();
+ } else {
+ current.nextRightChild();
+ }
+ }
+
+ //Is it right answer?
+ if (!ioAdapter.askYesNo("You were thinking of a " + current.getData() + ". Am I right?"))
+ {
+ //Ask for Animal & new question
+ boolean b = true;
+ String newanimal = ioAdapter.askString("You win. What is the answer?");
+ String newquestion = "";
+ String modnewquestion = "";
+
+ //Ask for Question to distinguish newanimal from old.
+ while(b)
+ {
+ newquestion = ioAdapter.askString("Please provide a yes/no question that distinguishes a " + newanimal + " from a " + current.getData() + ".");
+ modnewquestion = newquestion.replace(" it ", " a " + newanimal + " ");
+
+ //Question needs to contain '?' and ' it '
+ if(modnewquestion.equals(newquestion) || !newquestion.contains("?"))
+ {
+ ioAdapter.tell("I could not understand your question. Please make sure it contains an ' it ' and a questionmark '?' !");
+ } else
+ {
+ b = false;
+ }
+ }
+
+ //Ask new question and set Node
+ if(ioAdapter.askYesNo(modnewquestion)) {
+ current.setNode(newquestion, newanimal, current.getData());
+ } else {
+ current.setNode(newquestion, current.getData(), newanimal);
+ }
+ } else
+ {
+ //Guessed right
+ ioAdapter.tell("I won!");
+ return;
+ }
+
+ }
+
+}
diff --git a/ss2010/gdi2/java/Project3/src/QuizIoAdapter.java b/ss2010/gdi2/java/Project3/src/QuizIoAdapter.java
new file mode 100644
index 00000000..59b3b7a6
--- /dev/null
+++ b/ss2010/gdi2/java/Project3/src/QuizIoAdapter.java
@@ -0,0 +1,28 @@
+/**
+ * Interface for providing IO to the quiz game.
+ */
+public interface QuizIoAdapter {
+
+ /**
+ * Ask the user or test system a yes/no question.
+ *
+ * @param question The question to ask.
+ * @return True if the answer was "Y", false if it was "N".
+ */
+ public boolean askYesNo(String question);
+
+ /**
+ * Ask the user a general question.
+ *
+ * @param question The question to ask.
+ * @return The answer given to the question.
+ */
+ public String askString(String question);
+
+ /**
+ * Output a message.
+ *
+ * @param message The message to output.
+ */
+ public void tell(String message);
+}
diff --git a/ss2010/gdi2/java/Project3/src/SequentialBinaryTree.java b/ss2010/gdi2/java/Project3/src/SequentialBinaryTree.java
new file mode 100644
index 00000000..a2125dbc
--- /dev/null
+++ b/ss2010/gdi2/java/Project3/src/SequentialBinaryTree.java
@@ -0,0 +1,306 @@
+import java.io.Serializable;
+import java.util.*;
+
+/**
+ * A binary tree in sequential representation. It is maintained as an array such that
+ * the left child of the node with index i is located at index 2i and the right child
+ * is located at index 2i + 1 (see lecture slide set 7). The root is at index 1.
+ *
+ * @param The type of the data held in nodes of the tree.
+ */
+public class SequentialBinaryTree implements BinaryTree {
+
+ /**
+ * Vector with data.
+ * Position zero is also used, but index is starting with 1 not with 0
+ */
+ @SuppressWarnings("UseOfObsoleteCollectionType")
+ private Vector nodes = new Vector();
+
+ /**
+ * Definition of a Questionmark
+ */
+ public static final String QUESTIONMARK = "?";
+
+ /**
+ * Check if position is a Node
+ *
+ * @param pos Position starting with 1.
+ * @return true if its a node
+ */
+ private boolean isANode(int pos) {
+ if( pos > 0 &&
+ nodes.size() >= pos &&
+ nodes.get(pos-1) != null ){
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Sets a Node
+ *
+ * @param pos Position starting with 1
+ * @param data Data
+ * @return true if successfull
+ */
+ private boolean setANode(int pos, A data) {
+ if(pos <= 0){
+ return false;
+ }
+
+ if(nodes.size() < pos) {
+ nodes.setSize(pos);
+ }
+
+ nodes.set(pos-1,data);
+ return true;
+ }
+
+ /**
+ * Get A Node
+ *
+ * @param pos Position starting with 1
+ * @return Data or null if not existant
+ */
+ private A getANode(int pos) {
+ if( pos <= 0 ||
+ nodes.size() < pos){
+ return null;
+ }
+
+ return nodes.get(pos-1);
+ }
+
+ /**
+ * Insert a Node
+ *
+ * @param pos Position
+ * @param data Data
+ * @return true if successfull
+ */
+ private boolean insertANode(int pos, A data) {
+ if(!isANode(pos)) {
+ return setANode(pos,data);
+ }
+
+ return false;
+ }
+
+ /**
+ * Clones a Serializable Data object
+ * @param src
+ * @return cloned dataobject
+ */
+ public static Serializable cloneSerializable(Serializable src)
+ {
+ try {
+ java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
+ java.io.ObjectOutputStream oos = new java.io.ObjectOutputStream(baos);
+ oos.writeObject(src);
+ oos.flush();
+ oos.close();
+ java.io.ByteArrayInputStream bais = new
+ java.io.ByteArrayInputStream(baos.toByteArray());
+ java.io.ObjectInputStream ois = new java.io.ObjectInputStream(bais);
+ Object dest = ois.readObject();
+ ois.close();
+ return (Serializable)dest;
+ } catch (Throwable th) {
+ return src;
+ }
+ }
+
+ /**
+ * Create a tree from a given animal game preorder.
+ *
+ * param The type of the data held in nodes of the tree.
+ * @param preorder The preorder to build the tree from.
+ * @return A new SequentialBinaryTree corresponding to the provided preorder.
+ */
+ public static SequentialBinaryTree createFromPreorder(List preorder) {
+
+ List preordercopy = new ArrayList();
+
+ for(int i=0;i result = new SequentialBinaryTree();
+
+ result.recursiv_createFromPreorder(preordercopy,1);
+
+ return result;
+ }
+
+ /**
+ * Create tree from Preorder recursiv nonstatic and with A-Parameter
+ *
+ * A must implement contains-function
+ *
+ * @param preorder
+ * @param index Current index in Array
+ */
+ public void recursiv_createFromPreorder(List preorder, int index)
+ {
+ //still data to process?
+ if( preorder.size() < 1){
+ return;
+ }
+
+ //data
+ A s = preorder.get(0);
+
+ //insert node
+ insertANode(index, s);
+
+ //remove added element
+ preorder.remove(0);
+
+ //is a question?
+ if(s.toString().contains(QUESTIONMARK)){
+ recursiv_createFromPreorder(preorder,2*index);
+ recursiv_createFromPreorder(preorder,2*index+1);
+ }
+ }
+
+ /**
+ * Create a pre-order traversal sequence for this tree.
+ *
+ * @return The pre-order sequence for this tree.
+ */
+ @Override
+ public List preorder() {
+ return recursiv_preorder(1); //root
+ }
+
+ /**
+ * Creates preorder from Tree, recursiv!
+ *
+ * @param index Current Position in Array
+ * @return preorderlist
+ */
+ private List recursiv_preorder(int index){
+
+ //result list
+ List result = new ArrayList();
+
+ //check input data
+ if( index > 0 &&
+ index <= nodes.size()&&
+ isANode(index))
+ {
+ //add data
+ result.add(getANode(index));
+ result.addAll(recursiv_preorder(2*index));
+ result.addAll(recursiv_preorder(2*index+1));
+ }
+
+ //return list
+ return result;
+ }
+
+ /**
+ * @return Retrurns a BinaryTreeSearch Object
+ */
+ @Override
+ public BinaryTreeSearch binaryTreeSearch() {
+ // Create anonymous class implementing BinaryTreeSearch
+ return new BinaryTreeSearch() {
+
+ /**
+ * Current Index
+ */
+ private int index = 1; //root
+
+ /**
+ * Return Data of current Node
+ */
+ @Override
+ public A getData() {
+ if(!isANode(index)) {
+ throw new NoSuchElementException();
+ }
+
+ return getANode(index);
+ }
+
+ /**
+ * Is Current Node a Leaf
+ */
+ @Override
+ public boolean isLeaf() {
+
+ if( isANode(index) &&
+ !isANode(2*index) &&
+ !isANode(2*index+1)){
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Move index-pointer to left child of current node
+ */
+ @Override
+ public void nextLeftChild() {
+ if( isANode(index) &&
+ isANode(2*index)) {
+ index *= 2;
+ return;
+ }
+
+ throw new NoSuchElementException();
+ }
+
+ /**
+ * Move index-pointer to right child of current node
+ */
+ @Override
+ public void nextRightChild() {
+ if( isANode(index)&&
+ isANode(2*index +1)){
+ index = 2*index +1;
+ return;
+ }
+
+ throw new NoSuchElementException();
+ }
+
+ /**
+ * Set current Node
+ *
+ * @param data Data of node
+ * @param leftData Data of left Subnode
+ * @param rightData Data of right Subnode
+ */
+ @Override
+ public void setNode(A data, A leftData, A rightData) {
+
+ setANode(index,data);
+ setANode(2*index,leftData);
+ setANode(2*index+1,rightData);
+ }
+
+ /**
+ * Does current Node has a left child?
+ */
+ @Override
+ public boolean hasLeftChild() {
+ return isANode(2*index);
+ }
+
+ /**
+ * Does current Node has a right child?
+ */
+ @Override
+ public boolean hasRightChild() {
+ return isANode(2*index+1);
+ }
+ };
+ }
+
+}
diff --git a/ss2010/gdi2/java/Project3/src/UserIoAdapter.java b/ss2010/gdi2/java/Project3/src/UserIoAdapter.java
new file mode 100644
index 00000000..cd81e879
--- /dev/null
+++ b/ss2010/gdi2/java/Project3/src/UserIoAdapter.java
@@ -0,0 +1,44 @@
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+/**
+ * Interactive I/O for the quiz.
+ */
+public class UserIoAdapter implements QuizIoAdapter {
+
+ private BufferedReader inputReader;
+
+ public UserIoAdapter() {
+ inputReader = new BufferedReader(new InputStreamReader(System.in));
+ }
+
+ @Override
+ public String askString(String question) {
+ tell(question);
+ try {
+ return inputReader.readLine();
+ } catch (IOException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ @Override
+ public boolean askYesNo(String question) {
+ String answer = askString(question + " (Y/N)").toUpperCase();
+
+ while (!answer.startsWith("Y") && !answer.startsWith("N"))
+ {
+ answer = askString("Please answer Y or N: ").toUpperCase( );
+ }
+
+ return answer.startsWith("Y");
+ }
+
+ @Override
+ public void tell(String message) {
+ System.out.println(message);
+ }
+
+}
diff --git a/ss2010/gdi2/java/Project3/tests/QuizTest.java b/ss2010/gdi2/java/Project3/tests/QuizTest.java
new file mode 100644
index 00000000..24fd9281
--- /dev/null
+++ b/ss2010/gdi2/java/Project3/tests/QuizTest.java
@@ -0,0 +1,207 @@
+import static org.junit.Assert.*;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+
+public class QuizTest {
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ private BinaryTree constructFromPreorder(boolean linkedTree, List preorder) {
+ if (linkedTree)
+ return LinkedBinaryTree.createFromPreorder(preorder);
+ else
+ return SequentialBinaryTree.createFromPreorder(preorder);
+ }
+
+ @Test
+ public void linkedTreeTestCreateFromPreorderAndBinarySearch() {
+ testCreateFromPreorderAndBinarySearch(true);
+ }
+
+ @Test
+ public void linkedTreeTestBinarySearchAndConstructPreorder() {
+ testBinarySearchAndConstructPreorder(true);
+ }
+
+ @Test
+ public void linkedTreeCreateFromAndBuildPreorder() {
+ testCreateFromAndBuildPreorder(true);
+ }
+
+ @Test
+ public void linkedTreeBinaryTreeSearch() {
+ testBinaryTreeSearch(true);
+ }
+
+
+ @Test
+ public void sequentialTreeTestCreateFromPreorderAndBinarySearch() {
+ testCreateFromPreorderAndBinarySearch(false);
+ }
+
+ @Test
+ public void sequentialTreeTestBinarySearchAndConstructPreorder() {
+ testBinarySearchAndConstructPreorder(false);
+ }
+
+ @Test
+ public void sequentialTreeCreateFromAndBuildPreorder() {
+ testCreateFromAndBuildPreorder(false);
+ }
+
+ @Test
+ public void sequentialTreeBinaryTreeSearch() {
+ testBinaryTreeSearch(false);
+ }
+
+ public void testCreateFromPreorderAndBinarySearch(boolean linkedTree) {
+ List preorder = Arrays.asList("Is it a mammal?", "Is it bigger than a tiger?", "Elephant",
+ "Mouse", "Does it live underwater?", "Trout", "Robin");
+
+ BinaryTree tree = constructFromPreorder(linkedTree, preorder);
+
+ BinaryTreeSearch search = tree.binaryTreeSearch();
+ assertEquals("Is it a mammal?", search.getData());
+ search.nextRightChild();
+ assertEquals("Does it live underwater?", search.getData());
+ search.nextRightChild();
+ assertEquals("Robin", search.getData());
+ }
+
+ public void testBinarySearchAndConstructPreorder(boolean linkedTree) {
+ BinaryTree tree = linkedTree ? new LinkedBinaryTree() : new SequentialBinaryTree();
+
+ BinaryTreeSearch search = tree.binaryTreeSearch();
+ search.setNode("Is it a mammal?", "d1", "d2");
+ search.nextLeftChild();
+ search.setNode("Is it bigger than a tiger?", "Elephant", "Mouse");
+ search = tree.binaryTreeSearch();
+ search.nextRightChild();
+ search.setNode("Does it live underwater?", "Trout", "Robin");
+
+ List preorder = Arrays.asList("Is it a mammal?", "Is it bigger than a tiger?", "Elephant",
+ "Mouse", "Does it live underwater?", "Trout", "Robin");
+ assertEquals(preorder, tree.preorder());
+ }
+
+ public void testCreateFromAndBuildPreorder(boolean linkedTree) {
+ List preorder = Arrays.asList("Is it a mammal?", "Is it bigger than a tiger?", "Elephant",
+ "Mouse", "Does it live underwater?", "Trout", "Robin");
+ BinaryTree tree = constructFromPreorder(linkedTree, preorder);
+ assertEquals(preorder, tree.preorder());
+ }
+
+ public void testBinaryTreeSearch(boolean linkedTree) {
+ BinaryTree tree = linkedTree ? new LinkedBinaryTree() : new SequentialBinaryTree();
+ BinaryTreeSearch search = tree.binaryTreeSearch();
+ search.setNode(2, 5, 15);
+ search.nextLeftChild();
+ search.setNode(5, -5, -8);
+ search = tree.binaryTreeSearch();
+ search.nextRightChild();
+ search.setNode(15, 2, -5);
+ search.nextLeftChild();
+ search.setNode(2, -20, -10);
+
+ search = tree.binaryTreeSearch();
+ assertEquals(2, search.getData().intValue());
+ search.nextLeftChild();
+ assertEquals(5, search.getData().intValue());
+ search.nextRightChild();
+ assertEquals(-8, search.getData().intValue());
+
+ search = tree.binaryTreeSearch();
+ search.nextLeftChild();
+ search.nextRightChild();
+ try {
+ search.nextLeftChild();
+ assertTrue("Expected NoSuchElementException!", false);
+ } catch (NoSuchElementException e) {
+ }
+ }
+
+
+ @Test
+ public void quizTestLinkedRunSuccess() {
+ testRunSuccess(true);
+ }
+
+ @Test
+ public void quizTestSequentialRunSuccess() {
+ testRunSuccess(false);
+ }
+
+ @Test
+ public void quizTestLinkedRunLearn() {
+ testRunLearn(true);
+ }
+
+ @Test
+ public void quizTestSequentialRunLearn() {
+ testRunLearn(false);
+ }
+
+ public void testRunSuccess(boolean linkedTree) {
+ List preorder = Arrays.asList("Is it a mammal?", "Is it bigger than a tiger?", "elephant",
+ "mouse", "Does it live underwater?", "trout", "robin");
+
+ UnitTestIoAdapter ioAdapter = new UnitTestIoAdapter();
+
+ Quiz quiz = new Quiz(constructFromPreorder(linkedTree, preorder), ioAdapter);
+
+ ioAdapter.queueYesNoQuestion("a mammal");
+ ioAdapter.queueAnswer(true);
+ ioAdapter.queueYesNoQuestion("bigger than a tiger");
+ ioAdapter.queueAnswer(true);
+ ioAdapter.queueYesNoQuestion("elephant");
+ ioAdapter.queueAnswer(true);
+ quiz.run();
+ }
+
+ public void testRunLearn(boolean linkedTree) {
+ List preorder = Arrays.asList("Is it a mammal?", "Is it bigger than a tiger?", "elephant",
+ "mouse", "Does it live underwater?", "trout", "robin");
+
+ UnitTestIoAdapter ioAdapter = new UnitTestIoAdapter();
+
+ Quiz quiz = new Quiz(constructFromPreorder(linkedTree, preorder), ioAdapter);
+
+ ioAdapter.queueYesNoQuestion("a mammal");
+ ioAdapter.queueAnswer(true);
+ ioAdapter.queueYesNoQuestion("bigger than a tiger");
+ ioAdapter.queueAnswer(true);
+ ioAdapter.queueYesNoQuestion("elephant");
+ ioAdapter.queueAnswer(false);
+ ioAdapter.queueAnswer("whale");
+ ioAdapter.queueAnswer("Does it live underwater?");
+ ioAdapter.queueYesNoQuestion("?");
+ ioAdapter.queueAnswer(true);
+
+ quiz.run();
+
+ // Next round
+ ioAdapter.queueYesNoQuestion("a mammal");
+ ioAdapter.queueAnswer(true);
+ ioAdapter.queueYesNoQuestion("bigger than a tiger");
+ ioAdapter.queueAnswer(true);
+ ioAdapter.queueYesNoQuestion("underwater");
+ ioAdapter.queueAnswer(true);
+ ioAdapter.queueYesNoQuestion("whale");
+ ioAdapter.queueAnswer(true);
+
+ quiz.run();
+ }
+}
diff --git a/ss2010/gdi2/java/Project3/tests/UnitTestIoAdapter.java b/ss2010/gdi2/java/Project3/tests/UnitTestIoAdapter.java
new file mode 100644
index 00000000..9c2e679f
--- /dev/null
+++ b/ss2010/gdi2/java/Project3/tests/UnitTestIoAdapter.java
@@ -0,0 +1,53 @@
+import static org.junit.Assert.*;
+import java.util.Deque;
+import java.util.LinkedList;
+
+/**
+ * Pseudo I/O for the unit-testing the quiz.
+ */
+public class UnitTestIoAdapter implements QuizIoAdapter {
+
+ private Deque answerStrings;
+ private Deque answerBools;
+ private Deque questions;
+
+ public UnitTestIoAdapter() {
+ answerStrings = new LinkedList();
+ answerBools = new LinkedList();
+ questions = new LinkedList();
+ }
+
+ public void queueAnswer(String answer) {
+ answerStrings.add(answer);
+ }
+
+ public void queueAnswer(boolean answer) {
+ answerBools.add(answer);
+ }
+
+ public void queueYesNoQuestion(String question) {
+ questions.add(question);
+ }
+
+ @Override
+ public String askString(String question) {
+ System.out.println(question);
+ System.out.println(answerStrings.getFirst());
+ return answerStrings.removeFirst();
+ }
+
+ @Override
+ public boolean askYesNo(String question) {
+ System.out.println(question);
+ assertTrue(question + " should contain " + questions.getFirst(),
+ question.contains(questions.removeFirst()));
+ System.out.println(answerBools.getFirst() ? "Y" : "N");
+ return answerBools.removeFirst();
+ }
+
+ @Override
+ public void tell(String message) {
+ System.out.println(message);
+ }
+
+}