missing gdi2 "project 3" added

This commit is contained in:
Ulf Gebhardt 2013-12-19 22:27:00 +01:00
parent 59a2df79c9
commit 0a8075974c
13 changed files with 1396 additions and 0 deletions

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>Project3</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,26 @@
import java.util.List;
/**
* A simple generic interface for binary trees to be used by the Quiz class.
*
* @param <A> The type of the data held in nodes of the tree.
*/
public interface BinaryTree<A> {
/**
* 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<A> binaryTreeSearch();
/**
* Produces a pre-order traversal sequence for this tree.
*
* @return A list of data objects in pre-order.
*/
public List<A> preorder();
}

View File

@ -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 <A> The type of the data held in nodes of the tree.
*/
public interface BinaryTreeSearch<A> {
/**
* 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);
}

View File

@ -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 <A> The type of the data held in nodes of the tree.
*/
public class LinkedBinaryTree<A> implements BinaryTree<A> {
/**
* NodeClass
*
* @param <Datatype>
*/
private class LinkedNode<Datatype> {
/**
* Data of the Node
*/
private Datatype m_data = null;
/**
* Left Child; another node or null
*/
private LinkedNode<Datatype> m_leftchild = null;
/**
* Right Child; another node or null
*/
private LinkedNode<Datatype> 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<Datatype> leftchild, LinkedNode<Datatype> 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<Datatype> getLeftChild() {
return m_leftchild;
}
/**
* Sets Left Child
*
* @param leftchild Data
*/
public void setLeftChild(LinkedNode<Datatype> leftchild) {
m_leftchild = leftchild;
}
/**
* @return Right Child (can be null)
*/
public LinkedNode<Datatype> getRightChild() {
return m_rightchild;
}
/**
* Sets Right Child
*
* @param rightchild Data
*/
public void setRightChild(LinkedNode<Datatype> rightchild) {
m_rightchild = rightchild;
}
}
/**
* Rootnode
*/
private LinkedNode<A> 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 <String> 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<String> createFromPreorder(List<String> preorder) {
//Clone of preorder
List<String> preordercopy = new ArrayList<String>();
//Clone preorder
for(int i=0;i<preorder.size();i++)
{
preordercopy.add((String) cloneSerializable(preorder.get(i)));
}
//Construct LinkedBinaryTree
LinkedBinaryTree<String> result = new LinkedBinaryTree<String>();
//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<A> recursiv_createFromPreorder(List<A> preorder)
{
//check if there is data to parse
if( preorder.size() < 1){
return null;
}
//create new node for data
LinkedNode<A> node = new LinkedNode<A>(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<A> preorder() {
return recursiv_preorder(root);
}
/**
* Creates preorder from Tree, recursiv!
*
* @param node Node to start from
* @return preorderlist
*/
private List<A> recursiv_preorder(LinkedNode<A> node){
//resultlist
List<A> result = new ArrayList<A>();
//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<A> getRoot() {
return this.root;
}
/**
* Sets root node
*
* @param root New Rootnode
*/
private void setRoot(LinkedNode<A> root) {
this.root = root;
}
/**
* @return Retrurns a BinaryTreeSearch<A> Object
*/
@Override
public BinaryTreeSearch<A> binaryTreeSearch() {
// Create anonymous class implementing BinaryTreeSearch
return new BinaryTreeSearch<A>() {
/**
* Current Node is initialized with root
*/
private LinkedNode<A> 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<A> left = new LinkedNode<A>(leftData);
LinkedNode<A> right = new LinkedNode<A>(rightData);
//is root null? if yes create new node
if(currentNode == null)
{
root = new LinkedNode<A>(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;
}
};
}
}

View File

@ -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<String> 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<String> load(String filename) {
List<String> preorder;
try {
BufferedReader reader = new BufferedReader(new FileReader(filename));
preorder = new LinkedList<String>();
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<String> tree) {
List<String> 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<String> 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<String> 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<String> 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;
}
}
}

View File

@ -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);
}

View File

@ -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 <A> The type of the data held in nodes of the tree.
*/
public class SequentialBinaryTree<A> implements BinaryTree<A> {
/**
* Vector with data.
* Position zero is also used, but index is starting with 1 not with 0
*/
@SuppressWarnings("UseOfObsoleteCollectionType")
private Vector<A> nodes = new Vector<A>();
/**
* 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 <String> 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<String> createFromPreorder(List<String> preorder) {
List<String> preordercopy = new ArrayList<String>();
for(int i=0;i<preorder.size();i++)
{
preordercopy.add((String) cloneSerializable(preorder.get(i)));
}
SequentialBinaryTree<String> result = new SequentialBinaryTree<String>();
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<A> 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<A> preorder() {
return recursiv_preorder(1); //root
}
/**
* Creates preorder from Tree, recursiv!
*
* @param index Current Position in Array
* @return preorderlist
*/
private List<A> recursiv_preorder(int index){
//result list
List<A> result = new ArrayList<A>();
//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<A> Object
*/
@Override
public BinaryTreeSearch<A> binaryTreeSearch() {
// Create anonymous class implementing BinaryTreeSearch
return new BinaryTreeSearch<A>() {
/**
* 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);
}
};
}
}

View File

@ -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);
}
}

View File

@ -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<String> constructFromPreorder(boolean linkedTree, List<String> 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<String> preorder = Arrays.asList("Is it a mammal?", "Is it bigger than a tiger?", "Elephant",
"Mouse", "Does it live underwater?", "Trout", "Robin");
BinaryTree<String> tree = constructFromPreorder(linkedTree, preorder);
BinaryTreeSearch<String> 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<String> tree = linkedTree ? new LinkedBinaryTree<String>() : new SequentialBinaryTree<String>();
BinaryTreeSearch<String> 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<String> 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<String> preorder = Arrays.asList("Is it a mammal?", "Is it bigger than a tiger?", "Elephant",
"Mouse", "Does it live underwater?", "Trout", "Robin");
BinaryTree<String> tree = constructFromPreorder(linkedTree, preorder);
assertEquals(preorder, tree.preorder());
}
public void testBinaryTreeSearch(boolean linkedTree) {
BinaryTree<Integer> tree = linkedTree ? new LinkedBinaryTree<Integer>() : new SequentialBinaryTree<Integer>();
BinaryTreeSearch<Integer> 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<String> 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<String> 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();
}
}

View File

@ -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<String> answerStrings;
private Deque<Boolean> answerBools;
private Deque<String> questions;
public UnitTestIoAdapter() {
answerStrings = new LinkedList<String>();
answerBools = new LinkedList<Boolean>();
questions = new LinkedList<String>();
}
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);
}
}