CIT 590 Assignment 9: Squarelotrons
Spring 2013, David Matuszek

Purpose of this assignment

General idea of the assignment

Anita is the baby sitter of Baron Von Hauser’s kids. Von Hauser is a famous physics professor, so the Von Hauser kids have weird toys, all of which Anita has to master to be able to effectively entertain the kids.

While Anita was cleaning the bathtub she found a new toy, a Squarelotron game. It is extremely weird, and possesses a lot of mathematical symmetry. She is determined to understand this new toy, otherwise she won´t be able to play with Von Hauser’s kids. However the complexity of such an extreme toy makes it difficult to play.

A Squarelotron consist basically of a matrix of numbers. This matrix can be decomposed as square rings which can rotate independently in 4 different ways: Upside-Down (↕), Left-Right (↔), through the Main Inverse Diagonal (↙), and through the Main Diagonal (↘).

For example, consider the following Squarelotrons.

Squarelotron a) has 2 rings. The outer ring contains the numbers 1, 2, 3, 4, 5, 8, 9, 12, 13, 14, 15, 16, while the inner ring contains the numbers 6, 7, 10, 11.

Squarelotron b) has two rings and a center piece. The outer ring contains the numbers 1, 2, 3, 4, 5, 6, 10, 11, 15, 16, 21, 25, 22, 19, 24, 20, while the inner ring contains 7, 8, 9, 12, 14, 17, 18, 23. The number 13 is by itself in the center.

A Upside-Down Flip of the outer ring of Squarelotron a) yields:

A Left-Right Flip of the inner ring of squarelotron b) yields:

A Flip through the Main Inverse Diagonal of the inner ring of squarelotron a) yields:

A Flip through the Main Diagonal of the outer ring of squarelotron b) yields:

Since the squarelotron is a physical object, it can be simply rotated. For example, if the top row of the 4x4 squarelotron contains (1, 2, 3, 4) and the squarelotron is rotated right by 90 degrees, then the rightmost column of the squarelotron will contain (1, 2, 3, 4). This is not considered a "flip."

Anita wants you to do a program which performs the following. It will ask you whether to use a 4x4 or a 5x5 squarelotron, then print out the initial squarelotron (with the numbers in order, as in (a) above; (b) is slightly jumbled). Then the program will let you tell it which flips to perform, and it will print out the new squarelotron after each flip. Finally, the program will let you start with a new squarelotron, or quit.

Details

Write and unit test the following methods. You should try using TDD, Test-Driven Design, as illustrated in class:

  1. Start with a method that doesn't do anything
  2. Write a test for the method.
  3. Run the test, and make sure it fails.
  4. Add code to the method to try to make the test pass.
  5. Run the test again.
    1. If the test fails, debug the method (or the test) until the test passes.
    2. If the test passes, continue.
  6. Is the method complete (does it do everything it should do)?
    1. If the method isn't complete, add code to the test to check the new methodality. Go to step 3.
    2. If the method is complete, you are done with this method.

As before, follow the specifications exactly, because we will also be using my unit tests to check your work. Also as before, the design of the user interface is up to you--but the program must provide clear instructions on how to use it. As before, write a start() method that we can use to begin your program.

Especially if you are an experienced programmer, you may be tempted to write the methods first, and only afterwards write the unit tests. Please don't. You are in this class to learn new things, and one of the things I want you to learn is whether TDD works for you. I know it will be awkward and seems backward at first, but please give it an honest try. Who knows? You might like it.

Required Classes

public interface SquarelotronMethods
We haven't yet discussed interfaces in class, so this is provided for you here. It is nothing more than a list of methods that have to be implemented by each of the SmallSquarelotron and LargeSquarelotron classes.
class Squarelotron
This class houses any variables and methods that are common to both SmallSquarelotron and LargeSquarelotron. (There may not be very many.) This class should declare the instance variable public int[][] squarelotron, which will be inherited by each of the two subclasses. (This variable really should be private, but we need to be able to access it in order to JUnit test your methods.)

This class contains the main method which interacts with the user, as described above, and is the only method that does input/output.
class SmallSquarelotron extends Squarelotron implements SquarelotronMethods
This class implements 4x4 squarelotrons.
class LargeSquarelotron extends Squarelotron implements SquarelotronMethods
This class implements 5x5 squarelotrons.

Methods in SmallSquarelotron and LargeSquarelotron

Notice that in both the 4x4 and the 5x5 squarelotron, there are two rings that can be flipped (the center of the 5x5 ring is immobile). In each of the following methods, the ring should be one of the two strings "outer" and "inner", all lowercase, with the obvious meanings.

private SmallSquarelotron(int[] array)
private LargeSquarelotron(int[] array)
These are the constructors for squarelotrons. Given an int[] of the correct size (either 16 or 25 numbers), initializes a squarelotron. Inside the class, represent the squarelotron as the (inherited) public int[][] squarelotron instance variable. The first four or five numbers in the array form the first row of the int[][] array, and so on. Calling the constructor should not result in any input/output.
public static Squarelotron makeSquarelotron(int[] array) throws IllegalArgumentException
Constructs and returns a squarelotron if the following conditions are met: (1) The given array is either 16 or 25 in length, and (2) all the numbers in the array are nonnegative (zero is allowed) and less than or equal to 99. Throw an IllegalArgumentException if either of these conditions is violated. Calling this method should not result in any input/output.
public int[] numbers()
Given a 4x4 squarelotron, numbers returns an array of 16 numbers. Given a 5x5 squarelotron, it returns an array of 25 numbers. For a newly created squarelotron, the array returned by this method should have the same numbers in the same order as the array used to create the squarelotron. Calling this method should not result in any input/output.
public Squarelotron upsideDownFlip(String ring)
This method performs the Upside-Down Flip of the squarelotron, as described above, and returns the new squarelotron. The original squarelotron should not be modified (I will check for this). Calling this method should not result in any input/output.
public Squarelotron leftRightFlip(String ring)
This method performs the Left-Right Flip of the squarelotron, as described above, and returns the new squarelotron. The original squarelotron should not be modified (I will check for this). Calling this method should not result in any input/output.
public Squarelotron inverseDiagonalFlip(String ring)
This method performs the Main Inverse Diagonal of the squarelotron, as described above, and returns the new squarelotron. The original squarelotron should not be modified (I will check for this). Calling this method should not result in any input/output.
public Squarelotron mainDiagonalFlip(String ring)
This method performs the Main Diagonal Flip of the squarelotron, as described above, and returns the new squarelotron. The original squarelotron should not be modified (I will check for this). Calling this method should not result in any input/output.
public Squarelotron sideFlip(String side)
The argument side should be one of the four strings "left", "right", "top", and "bottom". The two indicated columns (leftmost or rightmost), or the two indicated rows (top two rows or bottom two rows) should be interchanged. The original squarelotron should not be modified (I will check for this). Calling this method should not result in any input/output.
public void rotateRight(int numberOfTurns)
The argument numberOfTurns indicates the number of times the squarelotron should be rotated 90° clockwise. Any integer, including zero and negative integers, is allowable as the second argument. A value of -1 indicates a 90° counterclockwise rotation. This method modifies the internal representation of the squarelotron; it does not create a new squarelotron. Calling this method should not result in any input/output.
@Override
public boolean equals(Object object)
Returns true if the object is a squarelotron that is equal to this squarelotron, and false otherwise. Squarelotrons that are the same except for rotations are considered equal. Squarelotrons of different sizes are never equal. Calling this method should not result in any input/output.
@Override
public String toString()
Returns a printable version of this squarelotron. The returned string should contain newline characters, '\n', between rows, so that printing the returned string produces neat, good-looking output. Calling this method should not result in any input/output. You do not need to unit test this method.

How to get started

Eclipse can save you a lot of typing. Here's how to begin:

  1. Create your project. Name it Squarelotron.
  2. Create a package. Name it squarelotron.
  3. Create an interface. Name it SquarelotronMethods.
  4. Copy/paste this file in place of your SquarelotronMethods file.
  5. Create the Squarelotron class.
  6. For both the SmallSquarelotron class and the LargeSquarelotron class:
    1. Create the class, but as you do so, add the interface SquarelotronMethods to it, and be sure Inherited abstract methods is checked. If you do this correctly, Eclipse will generate stubs for all the methods in the interface (except equals, toString and makeSquarelotron) you will have to create these yourself). If this doesn't happen, you did something wrong; delete the class and try again.
    2. Create the JUnit tests for the class, but click Next> and make sure all the above methods are checked. If you do this correctly, you will get test stubs for all the methods.

Reference

This assignment is a modified version of the problem "10016 - Flip-Flop the Squarelotron," from Online Judge.

Due date

Before 6am Friday March 29. Submit your zipped project file to Canvas. No other form of submission will be accepted.