Problem Set 1: Classes


Problem Set

Problem Set GitHub Repository link: https://github.com/CSE-116/ProblemSet-1

To submit your project, run problem.Zipper, which will create a zip file containing the problem set, and submit it to Autolab. Be sure every class and method exists before submitting to avoid Autolab errors, even if you did not complete all the methods yet.


Testing


This problem set does not require you to write any tests. tests.TestProblemSet1 contains tests for some of the methods that you can use to verify the correctness of your code. Note that not all methods have tests written for them. You are encouraged to follow the structure of these tests to write your own tests for the remaining methods. This is not required, but might save you time since you wouldn't have to submit to Atuolab to see if your code is correct.

You can run these tests just like a Java file with a main method (Right-click the file and choose run) and you will see feedback about which test cases you've passed/failed.

Some of these tests may have been commented out so that the problem set will compile. You can uncomment the tests as you get to these methods. You can highlight multiple lines and press control+/ (command+/ on mac) to quickly comment multiple lines in/out



Specification


Note that you must at least create every class/method from this specification to receive feedback. You can "stub out" these methods by having them always return a fixed value, but they must exist so the grading code, and your tests, can compile and run.

For this Problem Set, you will implement the following functionality. Note that all of the methods are public and non-static.

  • Location (5 points): Create a class in the problem package named Location. This class will represent a 2-dimensional point that will be used as the location of a shape. This class should implement the following methods:
    • Constructor: create a constructor which takes two doubles representing the x and y location, respectively.
    • getX: create a method named getX which takes no arguments and returns a double. This method should return the x component of the location.
    • getY: create a method named getY which takes no arguments and returns a double. This method should return the y component of the location.
    • setX: create a method named setX which takes a single double and returns void. This method should set the x component of the location to the input value.
    • setY: create a method named setY which takes a single double and returns void. This method should set the y component of the location to the input value.
  • Circle (5 points): Create a class in the problem package named Circle. This class will represent a circle based on a 2-dimensional location and a radius. This class should implement the following methods:
    • Constructor: create a constructor which takes a [reference to a] Location object and a double, in that order. These represent the location of the center of the circle and its radius.
    • getRadius: create a method named getRadius which takes no arguments and returns a double. This method should return the radius of this circle.
    • setRadius: create a method named setRadius which takes a single double and returns void. This method should set the radius of the circle to the input value.
    • getLocation: create a method named getLocation which takes no arguments and returns a [reference to a] Location object containing the location of the circle.
    • setLocation: create a method named setLocation which takes a single [reference to a] Location object and returns void. This method should set the location of the circle to the input location.
    • getArea: create a method named getArea which takes no arguments and returns a double. This method should calculate and return the area of the circle.
      • Remember that the area of a circle can be found with πr2, where r is the radius of the circle.
      • You can/should use Math.PI as the value of π instead of hard-coding your own estimate of π. Nothing needs to be imported to do so since Math is auto-imported.
  • Circle.move (5 points): Add a method to the Circle class named move that takes 2 doubles and returns void. The inputs are the amount to move the circle in the x direction and y direction respectively (dx and dy). The method should move the circle by these amounts.
  • Circle.detectCollision (5 points): Add a method to the Circle class named detectCollision that takes a [reference to a] Circle and returns a boolean. This method returns true if this circle overlaps at all with the circle from the parameter, false otherwise.
    • If two circles are exactly sharing a point, but are not overlapping, this should not be considered a collision.
    • The distance between two arbitrary points can be calculated as √((x1-x2)2 + (y1-y2)2).
  • CircleWorld (5 points): Create a class in the problem package named CircleWorld and implement the following methods in this class:
    • Constructor: You do not need to create a constructor for this class. If you choose to create one, it must not take any parameters (Autolab will create CircleWorld objects without providing arguments).
    • addCircle: create a method named addCircle which takes a [reference to a] Circle and returns void. This method should add this circle to the world. It is up to you how to handle this as long as the next method functions properly.
    • getCircles: create a method named getCircles which takes no parameters and returns an ArrayList of Circles. The returned ArrayList must contain every circle that was added to the world using the addCircle method.
  • CircleWorld.closestCircle (5 points): Add a method to the CircleWorld class named closestCircle that takes a Location as a parameter and returns a Circle. This method will return the closest circle to the given location.
    • Remember to take the radius into consideration. You are not returning the circle with a center closest to the point.
    • If the point is inside a circle, that's the closest circle
    • If any number of circles are tied in terms of closest distance, you may return any of those circles.
  • CircleWorld.collidingCircles (5 points): Add a method to the CircleWorld class named collidingCircles that takes no parameters and returns an ArrayList of Circles. This method will return an ArrayList containing every circle in the world that is colliding with another circle.
    • If a circle is colliding with multiple other circles, be sure to only add it the output once.
    • Take advantage of the detectCollision method you've written to make this method easier to write.
  • CircleWorld.resolveAllCollisions (15 points): Add a method to the CircleWorld class named resolveAllCollisions that takes a no parameters and returns void. This method will move, using the move method, the circles in the world such that no circle is colliding with any other circle.
    • This method is open-ended and you are encouraged to get creative with your solution. As long as no circles are colliding after this method is called, and all circles are still in the world and their radii have not been changed, the grader will give you credit.
    • It can help to call the collidingCircles method to help you write this method. If collidingCircles returns an empty ArrayList, you've resolved all collisions.
    • This method is graded in 3 phases, each worth 5 points. The phases have progressively more difficult test cases. To complete the last phase, you will have to handle a multitude of edge cases and unique positions of the circles.