Lab 6

advertisement
Lab 6
This lab can be done with one partner or it may be done alone. It is due in two weeks (Tuesday, May
13)
Problem 1: Interfaces: ( 10 pts)
I’m giving you an addObjects interface that has a total of one method signature:
public interface addObjects {
int addIt(int x);
}
Your job: Create 2 new classes: one for an OnLineBook, that implements the addObjects interface. This
method has two fields: a price and a title. I made the price be an int because I was lazy. The title should
be a string. The constructor takes as input the name of the book (a String) and an int representing the
price. The method addIt adds the price of the book to the input parameter and retuns that number.The
other method in the class definition is a method called printbook that takes no input and returns a string
representing the book’s title and its cost (you make it look nice).
The second class is for an ElectricBill. This class also implements the addObjects interface. The fields
for an ElectricBill are (I made everything an int-again-just laziness) watts (or number of watts used),
costperwatt, and then bill, which is calculated as watts * costperwatt. The constructor takes 2 input
parameters – the watts and the costperwatts, and sets all three fields. The addIt method adds the input
parameter to the bill field and returns that. This method also has a PrintBill() method that returns a string
representing the bill (you format to make it look nice.
Now write a main method that creates two new objects:
addObjects k = new OnLineBook(32,"Java Programming");
addObjects l = new ElectricBill(300, 2);
In your main method create a totalMonthlyBill variable (an int) initialized to 0. Use OnLineBook’s addIt method to
add the cost of the book to the totalMonthlyBill. Use the ElectricBill’s addIt method to add the bill to the
totalMonthlyBill.
Now you want to print out each individual item, and then the totalMonthlyBill. Use the following:
System.out.println(((OnLineBook)k).printbook());
System.out.println(((ElectricBill)l).PrintBill());
System.out.println("Total monthly bills: " + totalMonthlyBill);
Notice what I did to be able to access the methods belonging to the OnLineBook class and the EectricBill class.
Problem 2: TreeSets Modified: (15 pts)
TreeSets are type of set that infer from the collection interface. As you know, a TreeSet is
ordered in the sense that the nodes are placed in the tree in order of least to greatest (as opposed
to ArrayList ordering, which is based on indices in the array). TreeSets allow us to add, remove,
and check for inclusion (contains) relatively quickly.
TreeSets work by incorporating nodes into a tree-like structure. The node class has 3 fields: the
data field (this can be any type of object or simple type), the left child, which is of type node, and
the right child, which is also of type node. In each tree, there is a head node. New nodes are
inserted into the tree as follows: the new node is compared to the head node. If the new node’s
data is less than the head node’s data, the new node is compared to the head node’s left child. If
the new node’s data is greater than the head node’s data, the new node is then compared to the
head node’s right child. The new node is then compared to the child node’s left node or right
node, depending on whether the new node is greater than or less than the child node. This
continues until a child node is null. The new node is inserted there in the tree. (We discussed
this in class).
I have included code for a Node class and a simple TreeSet class, with add, find, and print
already defined for you. Try running the code as it stands now and see how it works.
Your job is to change both classes so that we now allow for duplicates. We will allow for
duplicates by adding a clone field to the node class, which will link to a Node with duplicate data
as the original Node. You will then need to modify the addNode method so that if the node is
already in the tree, we add the new node as a clone child of the node in the tree (Note: there can
be more than one duplicate). You will also need to modify the findNode method so that if a
node with matching data is found in the Tree, you will print out all of the duplicate nodes.
So given this main:
public static void main(String[] args) {
Tree theTree = new Tree();
theTree.addNode(50);
theTree.addNode(30);
theTree.addNode(25);
theTree.addNode(15);
theTree.addNode(30);
theTree.addNode(75);
theTree.addNode(85);
theTree.addNode(30);
theTree.addNode(50);
theTree.addNode(25);
theTree.addNode(25);
theTree.PrintTree(theTree.root);
// Find the Node2 with key 75
System.out.println("\nNode with the key 75");
System.out.println(theTree.findNode(75));
System.out.println("\nNode with the key 30");
System.out.println(theTree.findNode(30));
System.out.println("\nNode with the key 15");
System.out.println(theTree.findNode(15));
System.out.println("\nNode with the key 12");
System.out.println(theTree.findNode(12));
System.out.println("\nNode with the key 82");
System.out.println(theTree.findNode(82));
}
You should get this output from the original code I’ve included below:
30
30
50
25
25
15
is
is
is
is
is
25
already
already
already
already
already
30
in
in
in
in
in
50
the
the
the
the
the
75
tree.
tree.
tree.
tree.
tree.
85
Node with the key 75
Found! 75
75
Node with the key 30
Found! 30
30
Node with the key 15
Found! 15
15
Node with the key 12
12 not in tree
null
Node with the key 82
82 not in tree
Null
And you should get this from your modified code:
30
30
50
25
25
15
is
is
is
is
is
25
already
already
already
already
already
25
25
in
in
in
in
in
the
the
the
the
the
30
Tree2.
Tree2.
Tree2.
Tree2.
Tree2.
30
Node2 with the key 75
Found! 75
75
Node2 with the key 30
Found! 30
Found! 30
Found! 30
30
50
50
75
85
30
Node2 with the key 15
Found! 15
15
Node2 with the key 12
12 not in Tree2
null
Node2 with the key 82
82 not in Tree2
Null
Note: In order to include duplicates, the total number of lines of code you need to add to the original
code is 10 lines (and you could probably get away with less).
Note2: I am including the PrintTree2 method for your new code.
It requires that you name the new
field in your new node class clone. Use the PrintTree2 method in place of the PrintTree method after you
have modified the TreeSet code to include duplicates.
Here is the code:
public class Tree {
Node root;
public void addNode(int key) {
// Create a new Node and initialize it
Node newNode = new Node(key);
// If there is no root this becomes root
if (root == null) {
root = newNode;
} else {
// Set root as the Node we will start with as we traverse
the tree
Node focusNode = root;
// Future parent for our new Node
Node parent;
while (true) {
// root is the top parent so we start there
parent = focusNode;
// Check if the new node should go on the left side
of the parent node
if (key < focusNode.key) {
// Switch focus to the left child
focusNode = focusNode.leftChild;
// If the left child has no children
if (focusNode == null) {
// then place the new node on the left of
it
parent.leftChild = newNode;
return; // All Done
}
}
else if (key > focusNode.key){
// If we get here put the node on the right
focusNode = focusNode.rightChild;
// If the right child has no children
if (focusNode == null) {
// then place the new node on the right of it
parent.rightChild = newNode;
return; // All Done
}
}
else { //already in tree
System.out.println(key + " is already in the
tree.");
return;
}
}
}
}
//All nodes are visited in ascending order. Recursion is used to go to
// one node and then go to its child nodes and so forth
public void PrintTree(Node focusNode) {
if (focusNode != null) {
// Traverse the left node
PrintTree(focusNode.leftChild);
// Visit the currently focused on node
System.out.print(focusNode + " ");
// Traverse the right node
PrintTree(focusNode.rightChild);
}
}
public Node findNode(int key) {
// Start at the top of the tree
Node focusNode = root;
// While we haven't found the Node keep looking
while (focusNode.key != key) {
// If we should search to the left
if (key < focusNode.key) {
// Shift the focus Node to the left child
focusNode = focusNode.leftChild;
} else {
// Shift the focus Node to the right child
focusNode = focusNode.rightChild;
}
// The node wasn't found
if (focusNode == null) {
System.out.println(key + " not in tree");
return null;
}
}
System.out.println("Found! "+ focusNode);
return focusNode;
}
public static void main(String[] args) {
Tree theTree = new Tree();
theTree.addNode(50);
theTree.addNode(30);
theTree.addNode(25);
theTree.addNode(15);
theTree.addNode(30);
theTree.addNode(75);
theTree.addNode(85);
theTree.addNode(30);
theTree.addNode(50);
theTree.addNode(25);
theTree.addNode(25);
theTree.PrintTree(theTree.root);
// Find the Node2 with key 75
System.out.println("\nNode with the key 75");
System.out.println(theTree.findNode(75));
System.out.println("\nNode with the key 30");
System.out.println(theTree.findNode(30));
System.out.println("\nNode with the key 15");
System.out.println(theTree.findNode(15));
System.out.println("\nNode with the key 12");
System.out.println(theTree.findNode(12));
System.out.println("\nNode with the key 82");
System.out.println(theTree.findNode(82));
}
}
Here’s the node class:
public class Node {
int key;
Node leftChild;
Node rightChild;
public Node(int key) {
this.key = key;
}
public String toString() {
String str = "";
str += key + " ";
return str;
}
}
Here is the new PrintTree2 method:
public void PrintTree2(Node focusNode) {
if (focusNode != null) {
// Traverse the left Node
PrintTree2(focusNode.leftChild);
// Visit the currently focused on Node2
System.out.print(focusNode + " ");
Node tempnode = focusNode;
while (tempnode.clone != null) {
System.out.print(tempnode.clone + " ");
tempnode = tempnode.clone;
}
// Traverse the right Node2
PrintTree2(focusNode.rightChild);
}
}
Problem 3: HashMaps (25 pts)
We’re starting to write programs that write code (or write essays, or speak) automatically. In order to do
this, we need to teach the system rules for what can legally follow what. The computer can learn this (at
least in part) through observation of what has already been written (or spoken). So, for example, if a
computer wants to learn legal rules for what words can follow other words, it might read in a number of
documents and keep track of which words follow which words. With a large enough set of documents, it
should have a pretty good idea of at the very least what is unlikely to follow other words. For instance,
the word “I” may have as a set of words that follow it that include “want”, “am”, “like”, “could”, “will”,
“have”, etc. The set of words would most likely not include words like, “house”, “purple”, “cat”, etc.
We can do the same with computer programs. For this problem you will use a map. The key will be an
individual string read in from a program (e.g., in a program that starts out,
public class Tree {
Node root;
public void addNode(int key) {
...
Keys would be: public, class, Tree, {, Node, root;, void, addNode(int, key)
The values will be an ArrayList of strings. The list will include every string in the file that follows the
key word. So, for instance, the key public would have a value arraylist of [‘class’,’void’]. The value is
the set of valid options that can follow the key in a program. (If we really wanted to do this right, we’d
make the values be an ArrayList of objects, and the objects would have two fields, a string and a count.
The count would keep track of how often a particular string followed the key. This would allow us to
eliminate strings that only occurred once as anomalies).
So your job is to read in the TreeSet.java file and place the strings in the file into a hashmap. Note that
each string you read in is both a value (of the previous string) and a key. The last string in the
TreeSet.java file should have a null value as a value in its arraylist.
When you are done, print out the hashmap and look at the map. Does it look like it’s learning properly or
do we still need to add more rules?
Part 2:
Use the hashmap to generate a random program. Start with the key word, “public”and print that string to
a new file. Choose a random string from the list of values that follow “public”. Print that string into your
file. That string now becomes your key. Choose randomly from the list of values following the new key
and print that. That value now becomes the key. Continue for, oh, say, 500 key/value pairs, or until you
get the null value. Does this look anything like viable code?
**************************************************
Game Learning (Project 2a, 50 pts):
(Note: The game description is long, but the actual code is fairly straightforward to write)
In the game of sticks there is a heap of sticks on a board. On their turn, each player picks up 1 to
3 sticks. The one who has to pick the final stick will be the loser.
Sample game
The following is an example of the game of sticks.











The game starts with 20 sticks on the board.
Marvin takes 3 sticks, there are 17 sticks remaining.
Hal takes 2 sticks, there are 15 sticks remaining.
Marvin takes 1 stick, there are 14 sticks remaining.
Hal takes 3 sticks, there are 11 sticks remaining.
Marvin takes 2 sticks, there are 9 sticks remaining.
Hal takes 2 sticks, there are 7 sticks remaining.
Marvin takes 3 sticks, there are 4 sticks remaining.
Hal takes 1 stick, there are 3 sticks remaining.
Marvin takes 2 sticks, there is 1 stick remaining.
Hal has to take the final stick and loses.
This assignment is split into three parts:
1. Implementing the game as a two-player game.
2. Adding an AI that can be played against.
3. Adding an option for training the AI against another AI.
Part one: Human vs. Human
First, create a game where two players can play against each other. The two examples below
demonstrate how the game should behave.
Example 1
Welcome to the game of sticks!
How many sticks are there on the table initially (10-100)? 10
There are 10 sticks on the board.
Player 1: How many sticks do you take (1-3)? 3
There are 7 sticks on the board.
Player 2: How many sticks do you take (1-3)? 3
There are 4 sticks on the board.
Player 1: How many sticks do you take (1-3)? 3
There is 1 stick on the board.
Player 2: How many sticks do you take (1-3)? 1
Player 2, you lose.
Example 2
Welcome to the game of sticks!
How many sticks are there on the
Please enter a number between 10
How many sticks are there on the
Please enter a number between 10
How many sticks are there on the
table initially (10-100)? 500
and 100
table initially (10-100)? 3
and 100
table initially (10-100)? 50
There are 50 sticks on the board.
Player 1: How many sticks do you take (1-3)? 3
There are 47 sticks on the board.
Player 2: How many sticks do you take (1-3)? 55
Please enter a number between 1 and 3
Player 2: How many sticks do you take (1-3)? 3
There are 44 sticks on the board.
Player 1: How many sticks do you take (1-3)? 3
...
There is 1 stick on the board.
Player 1: How many sticks do you take (1-3)? 1
Player 1, you lose.
Implement a game with the functionality described above.
Part two: Human vs. AI
Playing against your friends is nice, but you're studying computer science for a reason. We can
learn to do some pretty cool stuff. So can the computers -- when taught. Let's create an AI for our
game.
One way to create an AI for the game of sticks is to mathematically analyze the game and craft
an AI based on the analysis. However, we now do the opposite. We create a learning AI that is
able to learn a good strategy for the game of sticks by playing the game against us. After this, the
mathematical analysis is easier to do because we already know how to play the game optimally.
Consider the functionality of the AI using the following description:



An AI has a number of hats, one hat for each possible amount of sticks on the table.
Initially, each hat contains three balls that are numbered from 1 to 3. If there are 10
sticks, there are 10 hats, each with 3 balls.
At every step of the game that the AI plays, the AI takes a random ball out of the hat that
matches the amount of sticks currently on the board. (So if the first player took 2 sticks,
there are 8 sticks on the board. The AI takes a random ball (ball 1, 2, or 3), places it next
to hat 8, and then reduces the number of sticks on the board by that random ball’s
amount.
If the AI wins the game, it puts two balls of the type to each hat that has a ball next to it.
Both balls have the same number. If the AI loses, it will throw away the balls that are

next to the hats (note: A hat must always have at least one ball of each number, hence the
last ball of a specific number cannot be thrown away and must be put back to the hat).
As more and more games are played, there will be more balls that indicate a good number
of sticks to take. This means that as balls are taken at random, it becomes more likely that
the AI is able to play well.
Example
Here’s an example where there are 10 sticks at the beginning. The hat contents for the AI are as
follows:
hat
1
2
3
4
5
6
7
8
9
10
content 1,2,3 1,2,3 1,2,3 1,2,3 1,2,3 1,2,3 1,2,3 1,2,3 1,2,3 1,2,3
The game may proceed as follows:
1. Player takes 3 sticks, there are 7 sticks remaining.
2. AI randomly picks up ball 2 from the hat 7. This means that the AI takes 2 sticks, and
there are 5 sticks remaining.
3. Player takes 1 stick, there are 4 sticks remaining.
4. AI randomly picks up ball 3 from hat 4. This means that AI takes 3 sticks, and there is 1
stick remaining.
5. Player has to take the final stick and loses.
Now, the situation with the AI is as follows:
hat
1
2
3
4 5
6
7 8
9
10
content 1,2,3 1,2,3 1,2,3 1,2 1,2,3 1,2,3 1,3 1,2,3 1,2,3 1,2,3
beside
3
2
As the AI wins the game, it will put the balls that are next to the hats back to the hats with extra
balls. The situation is now as follows:
hat
1
2
3
4
5
6
7
8
9
10
content 1,2,3 1,2,3 1,2,3 1,2,3,3 1,2,3 1,2,3 1,2,2,3 1,2,3 1,2,3 1,2,3
Note: for the content of the hat, you should have some form of collection. The collection must
allow doubles, and it must easily expand and contract in size. You will either be adding to the
end of the collection, or removing from somewhere in the collection. Which collection most
likely makes the most sense?
Now the AI will more likely take 3 sticks in the case of four sticks remaining on the board, and 2
sticks in case there are 7 sticks remaining on the board.
Your task is to modify the human vs. human version of the game so that the player can choose to
play against an AI that works as described above. After each game, the AI will update the
contents of its hats. The AI will play relatively randomly at first, but you will notice that it will
start to learn a strategy as you play against it.
The following example displays how the program should behave after you have finished this
step.
Welcome to the game of sticks!
How many sticks are there on the table initially (10-100)? 10
Options:
Play against a friend (1)
Play against the computer (2)
Which option do you take (1-2)? 2
There are 10 sticks on the board.
Player 1: How many sticks do you take (1-3)? 3
There are 7 sticks on the board.
AI selects 2
There are 5 sticks on the board.
Player 1: How many sticks do you take (1-3)? 3
There are 2 sticks on the board.
AI selects 2
AI loses.
Play again (1 = yes, 0 = no)? 1
There are 10 sticks on the board.
Player 1: How many sticks do you take (1-3)? 1
There are 9 sticks on the board.
AI selects 1
There are 8 sticks on the board.
Player 1: How many sticks do you take (1-3)? 3
There are 5 sticks on the board.
AI selects 3
There are 2 sticks on the board.
Player 1: How many sticks do you take (1-3)? 2
You lose.
Play again (1 = yes, 0 = no)? 1
There are 10 sticks on the board.
Player 1: How many sticks do you take (1-3)? 3
There are 7 sticks on the board.
AI selects 2
There are 5 sticks on the board.
Player 1: How many sticks do you take (1-3)? 3
There are 2 sticks on the board.
AI selects 2
AI loses.
Play again (1 = yes, 0 = no)? 0
Part three: AI vs. AI
In the previous part we created an AI that is able to learn from playing against the player. As we
play against it, we notice that it takes a considerable amount of time before the AI is able to
perform against a human player. In this assignment, you need to modify the program so that the
player can choose to play either against a naive AI or a pre-trained AI.
In order to pre-train an AI, you need to create a program that allows two AIs to battle against
each others -- say a hundred thousand times (after the training is working, try out different
numbers as well!) -- and after that the player will be set to play against the AI that is ready to
battle the player.
The following example shows how the game would work with the trained AI option.
Welcome to the game of sticks!
How many sticks are there on the table initially (10-100)? 10
Options:
Play against a friend (1)
Play against the computer (2)
Play against the trained computer (3)
Which option do you take (1-3)? 3
Training AI, please wait...
There are 10 sticks on the board.
Player 1: How many sticks do you take (1-3)? 3
There are 7 sticks on the board.
AI selects 2
There are 5 sticks on the board.
Player 1: How many sticks do you take (1-3)? 1
There are 4 sticks on the board.
AI selects 3
There is 1 stick on the board.
Player 1: How many sticks do you take (1-3)? 1
You lose.
Play again (1 = yes, 0 = no)? 1
There are 10 sticks on the board.
Player 1: How many sticks do you take (1-3)? 2
There are 8 sticks on the board.
AI selects 3
There are 5 sticks on the board.
Player 1: How many sticks do you take (1-3)? 2
There are 3 sticks on the board.
AI selects 2
There is 1 stick on the board.
Player 1: How many sticks do you take (1-3)? 1
You lose.
Play again (1 = yes, 0 = no)? 0
Congratulations! You’ve just taught the computer to learn.
Download