public class StateOfTurle { private float x; private float y; private float angle; public StateOfTurtle(float x, float y, float angle) { x = this.x; y = this.y; angle = this.angle; setX(x); setY(y); setAngle(angle); } public void setX(float x2) { x = x2; } public float getX() { return x; } public void setY(float y2) { y = y2; } public float getY() { return y; } public void setAngle(float angle2) { angle = angle2; ] public float getAngle() { return angle; } }
public class TurtleCommands { private StateOfTurtle sot; private float x; private float y; private float angle; private MyStack<StateOfTurtle> stack; public TurtleCommands(float x, float y, float angle) { stack = new MyStack<StateOfTurtle>(); x = this.x; y = this.y; angle = this.angle; sot = new StateOfTurtle(x,y,angle); } public void turn(float angle) { sot.setAngle(sot.getAngle() + angle); } }
import java.util.*; import java.io.*; public class MyStack <T> { private DoublyLinkedList<T> dLL; public MyStack() { dLL = new DoublyLinkedList<T>(); } public void pop { dLL.remove(0); } public void push() { dLL.addFirst(); } public T top() { return dLL.get(0); } }
import java.util.*; import java.io.*; public class MyQueue<T> { private DoublyLinkedList<T> dLL; public MyQueue() { dLL = new DoublyLinkedList<T>(); } public void push() { dLL.addLast(); } public void pop() { dLL.remove(0); } public T front() { return dLL.get(0); } public T back() { return dLL.get(dLL.Size() -1) } public boolean empty() { if (dLL.Size() == 0) return true; else return false; } }
package Assignment4; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JOptionPane; import java.util.*; import java.io.*; //Paul Adcock // Assignment 4 // Lasted Worked On: 10/12/2010 // this class is the Doubly Linked list class. It has a Node that holds a reference to some date of type T and has a reference // to the next Node and to the previous Node. public class DoublyLinkedList<T> { private class Node<T> { private T data; private Node<T> next; private Node<T> previous; public Node(T data,Node<T> next, Node<T> previous) { this.data = data; this.next = next; this.previous=previous; } public T getData() { return data; } public Node<T> getNext() { return next; } public Node<T> getPrevious() { return previous; } public void setNext(Node<T> next) { this.next = next; } public void setPrevious(Node<T> previous) { this.previous = previous; } } private Node<T> head;//head of the linked list private Node<T> tail; // tail of linked list private int size; private ImageIcon icon; private Icon icon2; public DoublyLinkedList() { head = null; tail = null; size = 0; icon = new ImageIcon("doh3.jpg"); } // returns a String of all the items in the linked list. public String toString() { String str = "["; Node<T> curr; for (curr=head;curr!=null;curr = curr.getNext()) { str = str + curr.getData(); if (curr.getNext()!=null) str = str + " "; } str = str + "]"; return str; } // adds the data as the first element. If the list size is 0, makes first element tail. If head is not null, it puts the old // tail as the second element and the new element as the new head. public void addFirst(T data) { /* Since this is the first Object, previous should be null */ Node<T> newNode = new Node<T>(data,head,null); //We know that if head is null, the list is empty if (head==null) { //If the list is empty, tail will be newNode tail = newNode; } if(head!=null) head.setPrevious(newNode); //We want to set head to be newNode // if the list was empty before, both head and tail will be set to newNode; head = newNode; //Increment Size size++; } public void removeFirst() { if (size == 0) { JOptionPane pane = new JOptionPane(); pane.setIcon(icon); pane.showMessageDialog(null, "Cannot remove from an empty list!", "Invalid removal", JOptionPane.ERROR_MESSAGE); pane.setMessageType(JOptionPane.ERROR_MESSAGE); return; } Node<T> current = head; // creates a Node called current and sets it to head. head = head.getNext(); //move head to the next element current.setNext(null); size--; } public void addLast(T data) { //If there are no elements, use the addFirst method if (tail == null) { addFirst(data); return; } /* Create the new Node from the data. Set next to null * because this will be the last element and will not * have a next. Set previous to tail because tail has * not been changed yet and is currently referencing * that element that will be directly before this element */ Node<T> newNode = new Node(data,null,tail); /* Since the tail variable still references the element * directly before the new element, we can set that node's * next to our new element. */ tail.setNext(newNode); //Set tail to our new Node tail = newNode; //Increment size size++; } public int Size() { return(size); } public void add(int index,T data) { int i; if (index == 0) { addFirst(data); return; } if (index>size) { JOptionPane.showMessageDialog(null, "Cannot add out of bounds!", "Invalid command", JOptionPane.ERROR_MESSAGE); return; } if (index < 0) { JOptionPane.showMessageDialog(null, "Cannot add out of bounds!", "Invalid command", JOptionPane.ERROR_MESSAGE); return; } if (head==null) { addFirst(data); return; } if (index == size) { addLast(data); return; } //step 1 Node<T> current; current = head; for (i=0;i<index-1;i++) { current = current.getNext(); } //current now refers to object immediately before new node //step 2 Node<T> newnode = new Node<T>(data,current.getNext(), current.getPrevious()); //step 3 current.setNext(newnode); size++; } public void remove(int index) { if ((index<0) || (index>=size)) { JOptionPane.showMessageDialog(null, "You cannot remove an out-of-bounds value!", "Invalid removal", JOptionPane.ERROR_MESSAGE); return; } Node<T> current,previous2; Node<T> NodeToRemove = head; current = head; // makes current equal to head previous2 = null; for (int v = 0; v < index; v++) { NodeToRemove = NodeToRemove.getNext(); } Node<T> previous3 = NodeToRemove.getPrevious(); for (int i=0;i<index;i++) { previous2 = current; current = current.getNext(); } // for remove(3) // for i = 0; // previous2 = head; // current = head + 1; // for i = 0; // previous2 = head + 1; // current = head + 2; // for i = 1; // previous2 = head + 2; // current = head + 3; // for i = 2 // previous2 = head + 3; // current = head + 4; // previous2.next = head + 5; Node<T> node3 = previous2; if (index!=0) { if (index == Size()-1) { previous2.setNext(null); previous2.setPrevious(previous3); } else { previous2.setNext(current.getNext()); previous2.setPrevious(previous3); } } else { head = head.getNext(); head.setPrevious(null); } size--; } public T get(int i) { if (i < 0 || i >= size) return null; if (i ==0) { Node<T> thisNode = head; return(head.getData()); } if (i == size - 1) { Node<T> thisNode = tail; return(tail.getData()); } Node<T> specialNode = head; for (int x = 1; x < i + 1; x++) { specialNode = specialNode.getNext(); } return(specialNode.getData()); // How do I get it to return the data at i? } // calls get method of first index public T front() { if (head == null) return null; return(get(0)); } // calls get Method of last index public T back() { if (tail == null) return null; return(get(size - 1)); } public void removeLast() { if (head == null) { JOptionPane.showMessageDialog(null, "Cannot remove from an empty list!", "Invalid removal", JOptionPane.ERROR_MESSAGE); return; } remove(Size() -1 ); } // gets a String for the first bracket. Then stores each set of first and last, 2nd and 2nd to last, etc, in a String array; // it then sets the third string to the concatination of all of the Strings in the array. It thens puts these together and adds // the last set of brackets and returns the final string. public String printAlternate() { /* This method returns a string that has the data in the following fashion (assume for this example that the list stores String objects) If the list is currently [amit is now here], it will return a string �[amit here is now]� If the list is currently [amit is now currently here], it will return a string �[amit here is currently now]� */ String str = "["; String [] str2 = new String[size]; for (int v = 0; v < size; v++) { str2[v] = this.get(v) + " " + this.get(size - (v+1) ); } String str3 = ""; for (int x = 0; x < size - 2; x++) { str3 = str2[x].concat(str2[x+1]); } String str4 = str + " " + str3 + " " + "]"; return(str4); } }
This is the assignment:
The important part is to figure out how to get the code to work.
Assignment 6: Turtles Out: 21st October 2010 Type: Large Due: 3rd November 2010 at 11:59pm Note: You must complete this assignment on Unix. You are not allowed to use Eclipse for any part of this assignment. You must use the command prompt to compile and run all your programs. How to approach this assignment: Read the assignment carefully and the helpful hints at the end. In this assignment you will implement 2 separate programs. A program that draws graphical primitives has been provided to you. You have to concentrate on generating the commands for this program. The idea behind this program is called “Turtle graphics”. Turtle graphics is based on the notion of a turtle moving on screen, drawing as it moves. At any given time, the turtle’s “state” is described by a position (x,y) and a direction in which it is pointing, in the form of an angle Ѳ with the +X axis, as shown below. The turtle can walk only in the direction that it is pointing (i.e. along a straight line), and can draw only as it walks. Through standard commands, you can make the turtle simply walk, walk and draw, and change its direction. Basically the turtle draws only straight lines. Part 1: Trying out the provided program A jar file called “TurtleGraphics.jar” has been provided to you. This program first takes the minimum and maximum values of x and y as integers within which all the lines will lie, in the order xmin xmax ymin ymax. It then takes floating-point numbers from the keyboard, four at a time. Each set of four numbers (x1,y1,x2,y2) draws a line from the point (x1,y1) to (x2,y2). Two sample input files “simple-lines.txt” and “gandhi-lines.txt” have been provided to you. In Unix, copy the jar file and these text files to the same directory, and run the program as follows: java –jar TurtleGraphics.jar < simple-lines.txt You can run the second file similarly. You should see the following pictures: simple-lines.txt gandhi-lines.txt If you see these pictures, you’re done with part 1. Part 2: Converting turtle commands to lines In this program you must write a program that converts standard turtle commands into lines. Your program must produce the output in the same format that the program in part 1 is accepting its input in. That is, the output of your program of part 2 should start with xmin, xmax, ymin, ymax and then four numbers per line to be drawn. The turtle commands are as follows: 1. turn a: This command turns the turtle by the specified angle ‘a’ in degrees without changing its position. 2. move r: This command moves the turtle by the specified distance ‘r’ along the current angle of the turtle, without drawing. If the current state of the turtle is (x,y,Ѳ), then the turtle will move to (x+r*cosѲ,y+r*sinѲ). The cosine and sine methods can be found in the Math class. Remember that the angle Ѳ is in degrees, while the cosine and sine methods accept angles in radians. The Math class has a method to do the necessary conversion. 3. trace r: This command moves the turtle by the specified distance ‘r’ along the current angle of the turtle, drawing a line between its old and new positions. Thus, the new state of the turtle will be (x+r*cosѲ,y+r*sinѲ,Ѳ) and a line will be drawn from (x,y) to (x+r*cosѲ,y+r*sinѲ). 4. push: This command pushes a copy of the current state of the turtle onto a stack. 5. pop: This command makes the state of the turtle to whatever is on top of the stack, and then pops from it. What to do: 1. Write a class to represent the state of a turtle in terms of its position (x,y) and the angle Ѳ. All are floats. 2. Write a class MyStack that behaves like a stack. You must use your own DoublyLinkedList class to write this stack. You are not allowed to use ArrayList or java’s Stack class for this purpose! 3. Write a program that accepts input from the keyboard in the following order: a. xmin, xmax, ymin, ymax as four integers. b. A sequence of the above turtle commands. You can assume that the input will always be correct. That is, if you read “move” you can expect to read a single floating point number after it. Your program should continue reading until there is nothing more to be read. 4. Your program must then take the necessary action as explained above for each turtle command. As soon as you read xmin, xmax, ymin, ymax, print them out. When you encounter the command “trace”, you must print out the four numbers corresponding to the line to be drawn using System.out.println. How to test your program: 1. Reproduce the same pictures you got in Step 1. All the provided .tur files are text files, you can open them in any text editor. a. Run this program by redirecting input from the provided file “simple.tur” and output to the file “generated-simple-lines.txt” as follows: java program2-main < simple.tur >generated-simple-lines.txt b. Now run the program in step 1 using generated-simple-lines.txt as input. You should see the same screen shot as “simple-lines.txt” created before. Thus, simple.tur stores the turtle commands to draw the shape seen in the screen shot. The file “tree.tur” contains the most complete set of turtle commands, so make sure you test for that! The pictures are provided below: simple.tur levy.tur gandhi.tur tree.tur 2. Pipe the two programs together using the other turtle commands files provided. If the turtle file you are using is “tree.tur”, run the two programs together as follows to get the same picture above: java program2-main < tree.tur | java –jar TurtleGraphics.jar Thus your program of part 2 is printing the numbers for the lines that the program of part 1 is accepting as input. This will work only if the output of one program exactly matches what the other program is expecting from its input. If “generated-simple-lines.txt” has everything in the same order as “simple-lines.txt”, piping should work successfully. Try the other files! Part 3: Generating Turtle Commands Many of the above files for turtle commands have been generated algorithmically. This is done by using “productions”. A production is like a Math equation, with a left side and a right side. An example of a production is: F = F+F-F where ‘F’, ‘+’, ‘-‘ are simply symbols (you are not performing any addition or subtraction). No two productions have the same symbol on their left side. A starting sequence of symbols is provided to you, say “++F--”. One can expand this sequence by substituting for every “F” the right side of the above production. Thus after one iteration, the sequence “++F--” becomes “++F+F-F--“. In the second iteration, one can again expand the result of the previous iteration, thus making the resulting sequence longer and longer with every iteration. When a set number of iterations is reached, the resulting sequence is converted into turtle commands. Keep in mind that there may be many productions, each with a different symbol on its left side. The starting sequence may also contain many symbols. Symbols in the sequence that are not on the left side of any production are left untouched (for example, the symbols ‘+’ and ‘-‘ above). Some of the above pictures have been generated this way. In part 3, you have to write a program that reads productions and symbols from the keyboard, iterates over a given sequence, and convert the resulting sequence into turtle commands. What to do: 1. Write a class MyQueue that behaves like a queue. You must use your own DoublyLinkedList class to write this queue. You are not allowed to use ArrayList or java’s LinkedList class for this purpose! 2. Write a program that reads input from the keyboard in the following order (follow along using one of the .pro files provided for this part): a. Read in four integers xmin, xmax, ymin, ymax. b. Read a single float number which is the “step size” of the trace command. c. Read a single float number which is the angle you turn by using the turn command. d. Read the number of productions (an integer). e. Read each production as follows: i. A single character that is the left side of the production. ii. A string that is the right side of the production. f. Read the starting sequence as a string of characters. g. Read the number of iterations, which is an integer. 3. Create two queue objects, and put the starting sequence in the first one, one character at a time. This is the “from” queue, and the other is the “to” queue. 4. For each iteration: a. For each character that you remove from the “from” queue: i. If it is the left side of any production, add the right side of that production to the “to” queue. Otherwise, add the character you read from the “from” queue to the “to” queue. b. Swap “from” and “to”. 5. Print the four integers xmin xmax ymin ymax. 6. For whichever queue has the final sequence, interpret the characters and print out the corresponding results using System.out.println: a. “F”: This corresponds to the “trace” command. Print “trace” followed by the step size from 2(b) above. b. “+”: This is a counter-clockwise “turn”. Print “turn” followed by the angle from 2(c) above. c. “-“: This is a clock-wise “turn”. Print “turn” followed by the negative of the angle from 2(c) above. d. “[“: This is a “push”. Print “push”. e. “]”: This is a “pop”. Print “pop”. How to test your program: 2. If your program 3 works correctly it will output the turtle commands in exactly the same order that program 2 is expecting as input. All the provided .pro files are text files, you can open them in any text editor. a. Run your program 3 by redirecting input and output as follows: java program3-main < generator-koch-smallest.pro >koch-smallest.tur b. Now run program 2 using “koch-smallest.tur” that you created in step 1. Try this for all the files provided for part 3. 3. Pipe all three programs together! For example, to see the picture for the tree (assuming all your .class files, the TurtleGraphics.jar file and the input files are in the same folder), run them as follows: java program3-main < generator-levy.pro | java program2-main | java –jar TurtleGraphics.jar In this case, your program3-main is generating turtle commands from productions that your program 2 is reading and creating lines, which the TurtleGraphics.jar is drawing. The results for generator-levy.pro should be the same as levy.txt above, and that for generator-tree.pro should be the same as tree.txt above. The other results are: generator-koch-smallest.pro generator-koch-smaller.pro generator-koch.pro Note: If you look at the above three files, they have the same productions and starting sequence, just different number of iterations. They should help you debug your program. Helpful Hints 1. Start early and pace yourself. You will not be able to complete this assignment in 2 days, so don’t expect to! 2. Take it one part at a time. Part 1 does not require you to write any code, just verify that you can run your program and see the correct picture. 3. For parts 2 and 3: if you are not confident about your DoublyLinkedList class, start by using the java classes Stack and LinkedList. Once you have the entire assignment done, replace them with your own implementations. Do not waste time in the beginning in debugging your DoublyLinkedList class. 4. At every step you will know if your program is working correctly by looking at the correct picture. Use this as a debugging tool! Expectations from a perfect program: 1. Part 2 works correctly on all input files. It uses your own Stack implementation. 2. Part 3 works correctly on all input files. It uses your own Queue implementation. 3. All the parts can be piped together and work correctly. 4. The source code should be suitably commented. a. Inside every class should be a short explanation of what the class represents and what it is used for. b. Just before every method signature, there should be information about what the method does, what every parameter means and what the method returns, if anything. c. Just inside every method there should be information about what exactly the method does (in steps).
He's saved the text files in .tur format for some reason. Windows has a hard time opening those, but UNIX can. Assume that the queue is first in, first out. The queue is not double-ended, i.e. you can't add or remove from either end, just one. For the queue, it behaves like a line of people. When the first person at the front is seated, that person exits or is removed. When someone joins the line, they join at the end, no cutting!, and gradually move up as more people are added and removed till they reach the front. The stack you can add or remove only to the top. The stack either changes the head to the element being pushed and pushes all the other ones down or it is popped, removing it and making the element that was below it the new head, or top.
Also, he said that, sorry about the formatting, but I've copied this part from an email.
Part 3: Generating Turtle Commands Many of the above files for turtle commands have been generated algorithmically. This is done by using "productions". A production is like [Show Quoted Text - 64 lines][Hide Quoted Text] a Math equation, with a left side and a right side. An example of a production is: F = F+F-F where 'F', '+', '-' are simply symbols (you are not performing any addition or subtraction). So the equation F = F + F - F is a production. In a single file, there cannot be two such productions whose left side has the same symbol. That is, there can be no two productions whose left side has the symbol "F". You can expand a start sequence using a production. For example, if the starting sequence is "++F--", you can expand the "F" in it to "F+F-F" according to the above production. Thus after one iteration of expansion, the starting sequence "++F--" and the production "F=F+F-F" have PRODUCED "++F+F-F--". In part 3 you're essentially supposed to read in the details from the keyboard, carry out this expansion, and convert the resulting sequence into turtle commands.
. All of them. They are all example input files. 2. Part 2 you have to do on your own. There is no "it". 3. Your program should read in everything from the keyboard. When you run the program, you will redirect input from one of the .tur files instead of typing them using the keyboard. 4. Part 2 is doing turtle commands --> lines. Part 3 will do productions --> turtle commands, so that when piped together, they will all do productions -->turtle commands --> lines.
Note, the jar file is doing the actual drawing.
The .tur file is not a Java file, so drawLine command will not make any sense there. The .tur file is simply a text file that has some turtle commands. Your part 2 program should read in this file, read in every command. It will maintain a turtle state consisting of its position and angle. In response to every command that is read, it will update the turtle state. When moving, it will move the turtle position. when tracing, in addition to moving, it will print out the resulting line exactly how TurtleGraphics.jar is expecting it. In the entire assignment I do not expect you to do any graphics yourself. TurtleGraphics.jar is supposed to do ALL the drawing. You have to worry only about giving it the correct coordinates.
How do I fix the errors in my remove(int index) method in my DoublyLinkedList<T> class? That class is used for the MyQueue and MyStack classes, which means I really need to fix that error. Yes, this is the same DoublyLinkedList<T> from the program 4 that I did earlier. Are my MyQueue and MyStack classes doing what they're supposed to, i.e., how I described them earlier?
UNIX is redirecting the input from the keyboard to instead be taken from the files. No FileInputStream needed. A Scanner is needed and I'm told that I'm supposed to have, for some part,
static Scanner console = new Scanner(System.in): // not sure about System.in but I think that's right.
while (console.hasNext())
{
..... read in data
}