diff --git a/.classpath b/.classpath
new file mode 100644
index 0000000..72c2ba6
--- /dev/null
+++ b/.classpath
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..3a5ba85
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+.DS_Store
+bin
diff --git a/.project b/.project
new file mode 100644
index 0000000..5a47f18
--- /dev/null
+++ b/.project
@@ -0,0 +1,17 @@
+
+
+ ps0
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/src/rules/RulesOf6005.java b/src/rules/RulesOf6005.java
new file mode 100755
index 0000000..a0c7bcf
--- /dev/null
+++ b/src/rules/RulesOf6005.java
@@ -0,0 +1,53 @@
+package rules;
+
+/**
+ * RulesOf6005 represents collaboration policy of 6.005 as described by the
+ * general information on Stellar.
+ *
+ * the Policy is described by the mayUseCodeInAssignment method.
+ *
+ */
+public class RulesOf6005 {
+
+ /**
+ * Judge whether a given piece of code may be used in an assignment (problem
+ * set or team project) or not, according to the 6.005 collaboration policy.
+ *
+ * @param writtenByYourself true if the code in question was written by
+ * yourself or, in the case of a team project, your teammates,
+ * otherwise false.
+ * @param availableToOthers if not writtenByYourself, whether or not the
+ * code in question is available to all other students in the class.
+ * Otherwise ignored.
+ * @param writtenAsCourseWork if not writtenByYourself, whether or not the
+ * code in question was written specifically as part of a solution to
+ * a 6.005 assignment, in the current or past semesters. Otherwise
+ * ignored.
+ * @param citingYourSource if not writtenByYourself, whether or not you
+ * properly cite your source. Otherwise ignored.
+ * @param implementationRequired whether the assignment specifically asks
+ * you to implement the feature in question.
+ * @return Whether or not, based on the information provided in the
+ * arguments, you are likely to be allowed to use the code in
+ * question in your assignment, according to the 6.005 collaboration
+ * policy for the current semester.
+ */
+ public static boolean mayUseCodeInAssignment(boolean writtenByYourself,
+ boolean availableToOthers, boolean writtenAsCourseWork,
+ boolean citingYourSource, boolean implementationRequired) {
+ // TODO: Fill in this method, then remove the exception
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Main method of the class.
+ *
+ * Runs the mayUseCodeInAssignment method.
+ * @param args
+ */
+ public static void main(String[] args){
+ System.out.println("You may certainly use code you wrote yourself: " +
+ RulesOf6005.mayUseCodeInAssignment(true, false, true, true, true));
+ }
+}
+
diff --git a/src/rules/RulesOf6005Test.java b/src/rules/RulesOf6005Test.java
new file mode 100755
index 0000000..ff99d4d
--- /dev/null
+++ b/src/rules/RulesOf6005Test.java
@@ -0,0 +1,18 @@
+package rules;
+
+import static org.junit.Assert.*;
+import org.junit.Test;
+
+/**
+ * JUnit tests for RulesOf6005.
+ */
+public class RulesOf6005Test {
+ /**
+ * Tests the mayUseCodeInAssignment method.
+ */
+ @Test
+ public void testMayUseCodeInAssignment() {
+ assertEquals(false, RulesOf6005.mayUseCodeInAssignment(false, true, false, false, false));
+ assertEquals(true, RulesOf6005.mayUseCodeInAssignment(true, false, true, true, true));
+ }
+}
diff --git a/src/turtle/Action.java b/src/turtle/Action.java
new file mode 100644
index 0000000..e6f7ee4
--- /dev/null
+++ b/src/turtle/Action.java
@@ -0,0 +1,33 @@
+package turtle;
+
+/**
+ * Command list entries
+ */
+enum ActionType {
+ FORWARD, TURN
+}
+
+public class Action {
+ ActionType type;
+ int intParam;
+ double doubleParam;
+ String displayString;
+ LineSegment lineSeg;
+
+ public Action(ActionType type, int intParam, double doubleParam,
+ String displayString, LineSegment lineSeg) {
+ this.type = type;
+ this.intParam = intParam;
+ this.doubleParam = doubleParam;
+ this.displayString = displayString;
+ this.lineSeg = lineSeg;
+ }
+
+ public String toString() {
+ if (displayString == null) {
+ return "";
+ } else {
+ return displayString;
+ }
+ }
+}
diff --git a/src/turtle/DrawableTurtle.java b/src/turtle/DrawableTurtle.java
new file mode 100644
index 0000000..db48c79
--- /dev/null
+++ b/src/turtle/DrawableTurtle.java
@@ -0,0 +1,71 @@
+package turtle;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.lang.Math;
+
+import javax.swing.SwingUtilities;
+
+/**
+ * Turtle for drawing.
+ */
+public class DrawableTurtle implements Turtle {
+
+ List actionList;
+ List lines;
+
+ Point currentPosition;
+ double currentHeading;
+
+ private static final int canvasWidth = 512;
+ private static final int canvasHeight = 512;
+
+ public DrawableTurtle() {
+ this.currentPosition = new Point(0, 0);
+ this.currentHeading = 0.0;
+ this.lines = new ArrayList();
+ this.actionList = new ArrayList();
+ }
+
+ /**
+ * Command to send the turtle forward a number of units.
+ *
+ * @param units number of pixels to go in currentHeading's direction; must be positive.
+ */
+ public void forward(int units) {
+ double newX = this.currentPosition.x + Math.cos(Math.toRadians(90.0 - currentHeading)) * (double)units;
+ double newY = this.currentPosition.y + Math.sin(Math.toRadians(90.0 - currentHeading)) * (double)units;
+
+ LineSegment lineSeg = new LineSegment(this.currentPosition.x, this.currentPosition.y, newX, newY);
+ this.lines.add(lineSeg);
+ this.currentPosition = new Point(newX, newY);
+
+ this.actionList.add(new Action(ActionType.FORWARD, units, 0.0, "forward " + units + " units", lineSeg));
+ }
+
+ /**
+ * Change the heading by some degrees clockwise.
+ *
+ * @param degrees amount of change in angle, in degrees, with positive being clockwise.
+ */
+ public void turn(double degrees) {
+ degrees = (degrees % 360 + 360) % 360;
+ this.currentHeading += degrees;
+ if (this.currentHeading >= 360.0)
+ this.currentHeading -= 360.0;
+ this.actionList.add(new Action(ActionType.TURN, 0, degrees, "turn " + degrees + " degrees", null));
+ }
+
+ /**
+ * Draw to the screen.
+ */
+ public void draw() {
+ SwingUtilities.invokeLater(new Runnable() {
+ public void run() {
+ (new TurtleGUI(actionList, canvasWidth, canvasHeight)).setVisible(true);
+ }
+ });
+ return;
+ }
+
+}
diff --git a/src/turtle/LineSegment.java b/src/turtle/LineSegment.java
new file mode 100644
index 0000000..74b34d6
--- /dev/null
+++ b/src/turtle/LineSegment.java
@@ -0,0 +1,48 @@
+package turtle;
+
+/**
+ * Class for a line segment in pixel space.
+ */
+public class LineSegment {
+ public final Point start;
+ public final Point end;
+
+ /*
+ * Constructor that takes in 4 integers for the coordinates.
+ *
+ * @param startx x-coordinate of start point
+ *
+ * @param starty y-coordinate of start point
+ *
+ * @param endx x-coordinate of end point
+ *
+ * @param endy y-coordinate of end point
+ */
+ public LineSegment(double startx, double starty, double endx, double endy) {
+ this.start = new Point(startx, starty);
+ this.end = new Point(endx, endy);
+ }
+
+ /*
+ * Constructor that takes in the start point and end point.
+ *
+ * @param start one end of the line segment
+ *
+ * @param end the other end of the line segment
+ */
+ public LineSegment(Point start, Point end) {
+ this.start = start;
+ this.end = end;
+ }
+
+ /*
+ * Calculate the length of this segment.
+ *
+ * @return the length of the line segment
+ */
+ public double length() {
+ return Math.sqrt(Math.pow(this.start.x - this.end.x, 2.0)
+ + Math.pow(this.start.y - this.end.y, 2.0));
+ }
+
+}
diff --git a/src/turtle/Point.java b/src/turtle/Point.java
new file mode 100644
index 0000000..63ed12e
--- /dev/null
+++ b/src/turtle/Point.java
@@ -0,0 +1,14 @@
+package turtle;
+
+/**
+ * Class for a point in floating-point pixel space.
+ */
+public class Point {
+ public final double x;
+ public final double y;
+
+ public Point(double x, double y) {
+ this.x = x;
+ this.y = y;
+ }
+}
diff --git a/src/turtle/Turtle.java b/src/turtle/Turtle.java
new file mode 100644
index 0000000..997a382
--- /dev/null
+++ b/src/turtle/Turtle.java
@@ -0,0 +1,21 @@
+package turtle;
+
+/**
+ * Turtle interface
+ *
+ * Defines the interface shared for FakeTurtle (for testing) and the
+ * real turtle (for displaying things on screen). Note that the
+ * standard directions/rotations use 'logo' semantics: initial heading
+ * of zero is 'up', and positive angles rotate the turtle clockwise.
+ *
+ * We implement: forward, turn right, and draw
+ */
+public interface Turtle {
+
+ public void forward(int units);
+
+ public void turn(double angle);
+
+ public void draw();
+
+}
diff --git a/src/turtle/TurtleGUI.java b/src/turtle/TurtleGUI.java
new file mode 100644
index 0000000..d41a46b
--- /dev/null
+++ b/src/turtle/TurtleGUI.java
@@ -0,0 +1,246 @@
+package turtle;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Container;
+import java.awt.Graphics2D;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.image.BufferedImage;
+import java.util.List;
+
+import javax.swing.GroupLayout;
+import javax.swing.GroupLayout.Alignment;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.SwingWorker;
+
+public class TurtleGUI extends JFrame {
+
+ private static final long serialVersionUID = 1L;
+
+ private static final Color canvasBGColor = new Color(255, 255, 255);
+ private static final Color canvasLineColor = new Color(0, 0, 0);
+
+ private static final double LENGTH_OF_A_TURN = 20;
+ private static final long MILLIS_PER_DRAWING = 5000;
+ private static final double ROUGH_FPS = 60;
+
+ private static final long MILLIS_PER_FRAME = (long) (1000.0 / ROUGH_FPS);
+
+ private int canvasWidth;
+ private int canvasHeight;
+ private int actionListSize;
+
+ private boolean isRunning;
+ private AnimationThread currAnimationThread;
+
+ private JButton runButton;
+ private JLabel currentActionLabel;
+ private JLabel currentAction;
+ private BufferedImage canvas;
+ private Graphics2D graphics;
+ private JLabel drawLabel;
+
+ private List actionList;
+
+ private int originX;
+ private int originY;
+
+ public TurtleGUI(List actionList, int canvasWidth, int canvasHeight) {
+ super("TurtleGUI");
+
+ this.canvasWidth = canvasWidth;
+ this.canvasHeight = canvasHeight;
+ this.actionListSize = actionList.size();
+ this.originX = (canvasWidth - 1) / 2;
+ this.originY = (canvasHeight - 1) / 2;
+
+ setDefaultCloseOperation(EXIT_ON_CLOSE);
+ Container cp = getContentPane();
+ GroupLayout layout = new GroupLayout(cp);
+ cp.setLayout(layout);
+ layout.setAutoCreateGaps(true);
+ layout.setAutoCreateContainerGaps(true);
+
+ runButton = new JButton();
+ runButton.setName("runButton");
+ runButton.setText("Run!");
+
+ isRunning = false;
+
+ currentActionLabel = new JLabel();
+ currentActionLabel.setName("currentActionLabel");
+ currentActionLabel.setText("Currently performing: ");
+
+ currentAction = new JLabel();
+ currentAction.setName("currentAction");
+ currentAction.setText("STOPPED");
+
+ canvas = new BufferedImage(canvasWidth, canvasHeight, BufferedImage.TYPE_INT_RGB);
+ graphics = canvas.createGraphics();
+ graphics.setBackground(canvasBGColor);
+ graphics.clearRect(0, 0, canvasWidth, canvasHeight);
+ graphics.setPaint(canvasLineColor);
+ graphics.setStroke(new BasicStroke(1.0f));
+
+ drawLabel = new JLabel(new ImageIcon(canvas));
+ drawLabel.setName("drawLabel");
+
+ this.actionList = actionList;
+
+ runButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+
+ if (!isRunning) {
+ runButton.setText("Stop");
+ isRunning = true;
+ currAnimationThread = new AnimationThread();
+ currAnimationThread.execute();
+ } else {
+ currAnimationThread.cancel(true);
+ }
+ }
+ });
+
+ layout.setHorizontalGroup(layout.createParallelGroup()
+ .addComponent(drawLabel)
+ .addGroup(layout.createSequentialGroup()
+ .addComponent(runButton)
+ .addComponent(currentActionLabel)
+ .addComponent(currentAction)));
+ layout.setVerticalGroup(layout.createSequentialGroup()
+ .addComponent(drawLabel)
+ .addGroup(layout.createParallelGroup(Alignment.CENTER)
+ .addComponent(runButton)
+ .addComponent(currentActionLabel)
+ .addComponent(currentAction)));
+
+ pack();
+ }
+
+ public void stopAnimation() {
+ currentAction.setText("STOPPED");
+ isRunning = false;
+ runButton.setText("Run!");
+ }
+
+ public List getActionList() {
+ return actionList;
+ }
+
+ public BufferedImage getCanvas() {
+ return canvas;
+ }
+
+ public JLabel getDrawLabel() {
+ return drawLabel;
+ }
+
+ public void setCurrentAction(String s) {
+ currentAction.setText(s);
+ }
+
+ private class AnimationThread extends SwingWorker {
+
+ AnimationThread() {
+ super();
+ }
+
+ @Override
+ protected Void doInBackground() throws Exception {
+ animate();
+ return null;
+ }
+
+ private void animate() {
+ graphics.clearRect(0, 0, canvasWidth, canvasHeight);
+ drawLabel.repaint();
+
+ // first, calculate the total length of line segments and turns,
+ // in order to allocate drawtime proportionally later
+
+ double totalLength = 0;
+ for (Action a : actionList) {
+ if (a.type == ActionType.TURN) {
+ totalLength += LENGTH_OF_A_TURN;
+ } else if (a.type == ActionType.FORWARD) {
+ totalLength += a.lineSeg.length();
+ }
+ }
+
+ // now, draw the animation
+
+ double cumulativeLength = 0;
+ long initialTime = System.currentTimeMillis();
+ for (int i = 0; i < actionListSize; i++) {
+ if (isCancelled()) {
+ break;
+ }
+ Action action = actionList.get(i);
+ setCurrentAction((i + 1) + ". " + action);
+ if (action.lineSeg != null) {
+ long startTime = (long) (initialTime + cumulativeLength / totalLength * MILLIS_PER_DRAWING);
+ cumulativeLength += action.lineSeg.length();
+ long endTime = (long) (initialTime + cumulativeLength / totalLength * MILLIS_PER_DRAWING);
+ draw(action.lineSeg, startTime, endTime);
+ } else {
+ cumulativeLength += LENGTH_OF_A_TURN;
+ long drawTime = (long) (initialTime + cumulativeLength / totalLength * MILLIS_PER_DRAWING - System.currentTimeMillis());
+ if (drawTime > 0) {
+ try {
+ Thread.sleep((long) drawTime);
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+ }
+ stopAnimation();
+ }
+
+ private void draw(LineSegment lineSeg, long initialTime, long endTime) {
+ long drawTime = endTime - initialTime;
+
+ double initX = originX + lineSeg.start.x;
+ double initY = originY - lineSeg.start.y;
+
+ double finalX = originX + lineSeg.end.x;
+ double finalY = originY - lineSeg.end.y;
+
+ int fromX = (int) initX;
+ int fromY = (int) initY;
+
+ boolean abort = false;
+ long elapsedTime = System.currentTimeMillis() - initialTime;
+
+ while (!abort && elapsedTime + MILLIS_PER_FRAME < drawTime) {
+ // while we have time remaining for this action
+ double fractionDone = Math.max(elapsedTime * 1.0 / drawTime, 0);
+ int toX = (int) Math.round(initX * (1 - fractionDone) + finalX * fractionDone);
+ int toY = (int) Math.round(initY * (1 - fractionDone) + finalY * fractionDone);
+ graphics.drawLine(fromX, fromY, toX, toY);
+ drawLabel.repaint();
+
+ try {
+ Thread.sleep(MILLIS_PER_FRAME);
+ } catch (InterruptedException e) {
+ abort = true;
+ }
+
+ // update
+ fromX = toX;
+ fromY = toY;
+
+ elapsedTime = System.currentTimeMillis() - initialTime;
+ }
+
+ // finish the line if we're still not done
+ if (!abort && (fromX != finalX || fromY != finalY)) {
+ graphics.drawLine(fromX, fromY, (int) finalX, (int) finalY);
+ drawLabel.repaint();
+ }
+ }
+ }
+}
diff --git a/src/turtle/TurtleSoup.java b/src/turtle/TurtleSoup.java
new file mode 100644
index 0000000..3c0407d
--- /dev/null
+++ b/src/turtle/TurtleSoup.java
@@ -0,0 +1,125 @@
+package turtle;
+
+import java.lang.Math;
+import java.util.List;
+import java.util.ArrayList;
+
+public class TurtleSoup {
+
+ /**
+ * Draw a square.
+ *
+ * @param turtle the turtle context
+ * @param sideLength length of each side
+ */
+ public static void drawSquare(Turtle turtle, int sideLength) {
+ throw new RuntimeException();
+ }
+
+ /**
+ * Determine inside angles of a regular polygon.
+ *
+ * There is a simple formula for calculating the inside angles of a polygon;
+ * you should derive it and use it here.
+ *
+ * @param sides number of sides, must be >2
+ * @return angle, in degrees between 0 and 360
+ */
+ public static double calculateRegularPolygonAngle(int sides) {
+ throw new RuntimeException();
+ }
+
+ /**
+ * Determine number of sides given the interior angles of a regular polygon.
+ *
+ * There is a simple formula for this; you should derive it and use it here.
+ * Make sure you *properly round* the answer before you return it (see java.lang.Math).
+ * HINT: it is easier if you think about the exterior angles.
+ *
+ * @param angle interior angles, in degrees
+ * @return the integer number of sides
+ */
+ public static int calculatePolygonSidesFromAngle(double angle) {
+ throw new RuntimeException();
+ }
+
+ /**
+ * Given the number of sides, draw a regular polygon.
+ *
+ * (0,0) is the lower-left corner of the polygon; use only right-hand turns to draw.
+ *
+ * @param turtle the turtle context
+ * @param sides number of sides of the polygon to draw
+ * @param sideLength length of each side
+ */
+ public static void drawRegularPolygon(Turtle turtle, int sides, int sideLength) {
+ throw new RuntimeException();
+ }
+
+ /**
+ * Given the current direction, current location, and a target location, calculate the heading
+ * towards the target point.
+ *
+ * The return value is the angle input to turn() that would point the turtle in the direction of
+ * the target point (targetX,targetY), given that the turtle is already at the point
+ * (currentX,currentY) and is facing the angle currentHeading. The return angle must be expressed in
+ * degrees, and 0 <= angle < 360.
+ *
+ * HINT: look at http://en.wikipedia.org/wiki/Atan2 and Java's math libraries
+ *
+ * @param currentHeading current direction as clockwise from north
+ * @param currentX currentY current location
+ * @param targetX targetY target point
+ * @return adjustment to heading (right turn amount) to get to target point.
+ * Must be positive, and less than 360.
+ */
+ public static double calculateHeadingToPoint(double currentHeading, int currentX, int currentY,
+ int targetX, int targetY) {
+ throw new RuntimeException();
+ }
+
+ /**
+ * Given a sequence of points, calculate the heading adjustments needed to get from each point to the next.
+ *
+ * You should use your calculateHeadingToPoint() function in this one to simplify things. Assume
+ * that the turtle is at the first point, facing up (i.e. 0 degrees), and for further points,
+ * assume that the turtle is facing the direction last specified.
+ *
+ * @param xCoords list of x-coordinates (must be same length as yCoords)
+ * @param yCoords list of y-coordinates (must be same length as xCoords)
+ * @return list of heading adjustments between points, of size #points-1.
+ */
+ public static List calculateHeadings(List xCoords, List yCoords) {
+ throw new RuntimeException();
+ }
+
+ /**
+ * Draw your personal, custom art.
+ *
+ * Many interesting images can be drawn using the simple implementation of a turtle. For this
+ * function, draw something interesting; the complexity can be as little or as much as you want.
+ * We'll be peer-voting on the different images, and the highest-rated one will win a prize:
+ * free dinner with select staff members.
+ *
+ * @param turtle the turtle context
+ */
+ public static void drawPersonalArt(Turtle turtle) {
+ throw new RuntimeException();
+ }
+
+ /**
+ * Main method
+ *
+ * This is the method that runs when you run "java TurtleSoup". Right now, it
+ * will run your drawSquare() method.
+ */
+ public static void main(String args[]) {
+ DrawableTurtle turtle = new DrawableTurtle();
+
+ drawSquare(turtle, 40);
+
+ // draw the window
+ turtle.draw();
+ }
+
+}
diff --git a/src/turtle/TurtleSoupTest.java b/src/turtle/TurtleSoupTest.java
new file mode 100644
index 0000000..5365f90
--- /dev/null
+++ b/src/turtle/TurtleSoupTest.java
@@ -0,0 +1,61 @@
+package turtle;
+
+import org.junit.Test;
+import static org.junit.Assert.*;
+import java.util.List;
+import java.util.ArrayList;
+
+public class TurtleSoupTest {
+
+ /**
+ * Tests calculateRegularPolygonAngle().
+ */
+ @Test
+ public void calculateRegularPolygonAngleTest() {
+ assertEquals(60.0, TurtleSoup.calculateRegularPolygonAngle(3), 0.001);
+ assertEquals(128.57, TurtleSoup.calculateRegularPolygonAngle(7), 0.01);
+ assertEquals(108.0, TurtleSoup.calculateRegularPolygonAngle(5), 0.001);
+ }
+
+ /**
+ * Tests calculatePolygonSidesFromAngle().
+ */
+ @Test
+ public void calculatePolygonSidesFromAngleTest() {
+ assertEquals(3, TurtleSoup.calculatePolygonSidesFromAngle(60.0));
+ assertEquals(7, TurtleSoup.calculatePolygonSidesFromAngle(128.57));
+ assertEquals(5, TurtleSoup.calculatePolygonSidesFromAngle(108.0));
+
+ }
+
+ /**
+ * Test calculateHeadingToPoint()
+ */
+ @Test
+ public void calculateHeadingToPointTest() {
+ assertEquals(0.0, TurtleSoup.calculateHeadingToPoint(0.0, 0, 0, 0, 1), 0.001);
+ assertEquals(90.0, TurtleSoup.calculateHeadingToPoint(0.0, 0, 0, 1, 0), 0.001);
+ assertEquals(359.0, TurtleSoup.calculateHeadingToPoint(1.0, 4, 5, 4, 6), 0.001);
+ }
+
+ /**
+ * Test calculateHeadings()
+ */
+ @Test
+ public void calculateHeadingsTest() {
+ List xpoints = new ArrayList();
+ List ypoints = new ArrayList();
+ xpoints.add(0);
+ xpoints.add(1);
+ xpoints.add(1);
+ ypoints.add(0);
+ ypoints.add(1);
+ ypoints.add(2);
+
+ List result = TurtleSoup.calculateHeadings(xpoints, ypoints);
+ assertEquals(2, result.size());
+ assertEquals(45.0, result.get(0), 0.001);
+ assertEquals(315.0, result.get(1), 0.001);
+
+ }
+}