Eighth Assignment: Magic Squares CIT 591, David Matuszek, Fall 2001

Purposes of this assignment:

• To give you some practice working with arrays
• To give you further practice in creating GUIs

What a magic square is:

A magic square is an array of numbers from 1 to N squared, such that the sum of the numbers in each row, each column, and each of the two diagonals is the same. For example, here is a 3x3 magic square:

 8 1 6 3 5 7 4 9 2

Rows:
8 + 1 + 6 = 15
3 + 5 + 7 = 15
4 + 9 + 2 = 15

Columns:
8 + 3 + 4 = 15
1 + 5 + 9 = 15
6 + 7 + 2 = 15
Diagonals:
8 + 5 + 2 = 15
4 + 5 + 6 = 15

How to create a magic square:

There is a simple algorithm for creating an odd-order magic square (a magic square with an odd number of rows and columns).

Start by putting the number 1 in the center of the top row:
 1
 1 3 2
Count upward and to the right. If you go off the top, drop down to the bottom. (That is, if the row number becomes negative, reset it to the array length minus one.)
Continue counting upward and to the right. If you go off the right, come back in on the left. (Hint: use the modulo operator, `%`.)
 1 5 4 3 2
 1 5 4 6 3 2
Continue counting upward and to the right. If you reach a square that is already occupied, go directly under the previous number.
Continue in this manner as long as possible.
 1 8 15 5 7 14 4 6 13 10 12 3 11 2 9
 17 24 1 8 15 23 5 7 14 16 4 6 13 20 22 10 12 19 21 3 11 18 25 2 9

When you go off the top right corner, the same rules apply; the next square is already occupied (by 11), so drop directly below the 15. Then continue.

This technique works for any odd square.

If you are having trouble understanding how the "wrapping around" works in the above algorithm, it may help to think of the array as being surrounded by identical ghost copies of itself. As you move up and to the right, if you go off the edge of the array, go ahead and put the next number into the surrounding array, and that will show you where the number belongs in the original, "real" array.

For example, going diagonally upward from the initial` 1`, look where the` 2 `ends up in an adjacent array; this is where it should be in the original array (because it is identical to the "ghost" array).

This is only an aid for understanding; you should not use nine arrays in your program.

 17 24 1 8 15 23 5 7 14 16 4 6 13 20 22 10 12 19 21 3 11 18 25 2 9
 17 24 1 8 15 23 5 7 14 16 4 6 13 20 22 10 12 19 21 3 11 18 25 2 9
 17 24 1 8 15 23 5 7 14 16 4 6 13 20 22 10 12 19 21 3 11 18 25 2 9
 17 24 1 8 15 23 5 7 14 16 4 6 13 20 22 10 12 19 21 3 11 18 25 2 9
 17 24 1 8 15 23 5 7 14 16 4 6 13 20 22 10 12 19 21 3 11 18 25 2 9
 17 24 1 8 15 23 5 7 14 16 4 6 13 20 22 10 12 19 21 3 11 18 25 2 9
 17 24 1 8 15 23 5 7 14 16 4 6 13 20 22 10 12 19 21 3 11 18 25 2 9
 17 24 1 8 15 23 5 7 14 16 4 6 13 20 22 10 12 19 21 3 11 18 25 2 9
 17 24 1 8 15 23 5 7 14 16 4 6 13 20 22 10 12 19 21 3 11 18 25 2 9

Write a program that creates and displays magic squares. Here are the specific requirements:
 Your program must be an application, not an applet. Use a `BorderLayout`, and put: Your name in the `NORTH.` The magic square in a panel in the `CENTER.` A panel containing two buttons in the `SOUTH` . For the magic square, Use a `GridLayout` with N rows and N columns. Create and install a `Label` for each number in the magic square. Put these two buttons in the panel in the `SOUTH`: `Smaller`: When clicked, creates and displays a new magic square with two fewer rows and two fewer columns. Disabled if an only if the displayed magic square is 1x1. `Larger`: When clicked, creates and displays a new magic square with two more rows and two more columns. Always enabled. Attach a WindowListener that will close the window and quit the program when the close box is clicked. The result should look very much like this:

Suggestions:

I did several versions of this program before I found an organization that worked well. If you would like to use the same organization, here it is. I used the following three classes:

`public class MagicSquareMaker`
Contains the``` public static void main(String args[]) ```method, and nothing else. The only thing the main method does is create an instance of the `Gui`. (I did it this way because it's a nuisance trying to do anything inside a static method.)
`public class Gui extends Frame`
Sets up the Graphical User Interface, calls a constructor to make the initial `new MagicSquare`, displays the magic square, and adds a listener to handle window closing events.
`public class MagicSquare`
Has a constructor that takes an odd positive integer argument, and creates a magic square of that order. In addition, it contains a method that takes a Panel as an argument, removes the previous contents (if any) of the Panel, attaches a GridLayout manager to the Panel, and creates and add N*N numeric labels to the Panel, where N is the order of this magic square.

That is,

```public class MagicSquareMaker {

public static void main(String args[]) {
Gui gui = new Gui(5);
}
}
public class Gui extends Frame {
public Gui(int sizeOfMagicSquare) {...} // constructor
}
public class MagicSquare {
public MagicSquare(int size) {...} // constructor
public void fillPanel(Panel panel) {...}
}```

In this organization, the "Controller" and "View" are merged into the single class `Gui`, while the `MagicSquare` represents the "Model." This separation is not perfect, however, because some class has to take the responsibility of creating a `Panel` full of `Label`s from the information in the `MagicSquare` class. I decided to do this in the `MagicSquare` class, because it seemed better to use a `Panel` (which is a GUI thing) in the `MagicSquare` class than to give the `Gui` class access to all the numbers inside the magic square.

Another way to do this would have been to have a separate `View` class, and to write a method `public int[][] getArray() `in the `MagicSquare` class; the `View` class would use this to get the numbers it needs.

Necessary information:

A `Frame`, like an `Applet`, is a `Container`. Applets are usually embedded in web pages, while frames are usually used in applications (stand-alone programs). The most important differences between a `Frame` and an `Applet` are:

• The default layout manager for an `Applet` is `FlowLayout`; the default layout manager for a `Frame` is `BorderLayout`.
• An `Applet` is automatically visible, but you have to tell a `Frame` to make itself visible--send it the message` setVisible(true)`.
• The size of an `Applet` is given by the HTML page. The size of a `Frame` is very small unless you tell it to `setSize(width, height)`, where `width` and `height` are given in pixels.``` (200, 200) ```is a reasonable size to start with.

For an application, in order to respond to a `WindowClosing` event, you need a `WindowListener` to the `Frame`:

`    addWindowListener(new MyWindowCloser());`

The actual listener (best implemented as a member class) looks like this:

```    class MyWindowCloser extends WindowAdapter {
public void windowClosing(WindowEvent e) {
dispose();
System.exit(0);
}
}```

Usually, when you create a GUI, you don't keep changing the layout managers or the components. If you do, you have to do a little extra work.

`removeAll()`
This message, sent to a `Container`, will remove all the `Component`s in that `Container`. Use this to remove the old `Label`s from your magic square, before changing the layout manager and putting in the new `Label`s.
`validate()`
This message, sent to a `Container`, will tell Java that you have changed the contents of that `Container`, and Java needs to redraw it for you.

Due date:

This program is due by midnight on Wednesday, November 14. Please turn in a complete BlueJ package via Blackboard.

Late penalties of 5 points per day will apply. No programs will be accepted after Wednesday, November 21.