# Magic square

Show 40 post(s) from this thread on one page
Page 1 of 2 12 Last
• 04-13-2010, 08:35 PM
gandalf5166
Magic square
Alright, I've had so many problems with this that I just made an ongoing thread that way my OCD doesn't keep me from just posting another problem in the same thread. My problem is weird. It compiles fine, but after I enter the size it throws a ArrayIndexOutOfBoundsException. I know what that is, I just don't understand why it throws in this instance.
Code:

```public class Magic {         public static void main(String[] args) {             int order;             Scanner input = new Scanner(System.in);             Square square;             System.out.print("Enter the order of the magic square no greater than 20: ");             order = input.nextInt();             square = new Square(order);             while(order > 20 || order < 3) {                     System.out.println("Invalid input. Please enter an positive order no greater than 20: ");                     order = input.nextInt();               }               if (order % 2 == 1) {                     square.oddSquare();                     square.printSquare(); //it throws at this line             } else if(order % 4 == 0) {                     square.doubleSquare();                     square.printSquare();             } else {                     square.singleSquare();                     square.printSquare();             }     } }  class Square {         int x;         int y;         int order;         int[][] square;         int diag;         int num;         int counter;         public Square(int order) {         int diag = 1;         int num = 1;         int counter = 1;         }         public void oddSquare() {                 int[][] square = new int[order][order];                 y = 0;                 x = order / 2;                 square[y][x] = num; //it also throws at this line                 while (counter <= order) {                 while (diag <= order) {                         num += 1;                         x += 1;                         y -= 1;                         if (x > order - 1) {                                 x = 0;                         }                         if (y < 0) {                                 y = order - 1;                         }                         square[y][x] = num;                         diag += 1;                 }                 diag = 1;                 counter += 1;                 y += 1;                 }         }         public void singleSquare() {                         }         public void doubleSquare() {                         }         public void printSquare() {                 System.out.print("+");                 for (int i = 1; i <= order; i++) {                 System.out.print("-----");                                        }                 System.out.println("+");                 for (int row = 0; row < order; row++) {                         for (int col = 0; col < order; col++) {                         System.out.print("|");                         System.out.format("%3d" + square[row][col]);                         }                 System.out.println("|");                 System.out.print("+");                 for (int i = 1; i <= order; i++) {                         System.out.print("----");                                        }                 System.out.println("+");                 }         }  }```
The purpose of the program is to create a magic square.
• 04-13-2010, 08:39 PM
gandalf5166
Never mind. I just noticed like, eight different problems with this.
• 04-13-2010, 08:44 PM
iluxa
Code:

```public void oddSquare() {                 int[][] square = new int[order][order]; // ...```
What you've done is created a local variable called "square". as soon as you exit the function that variable ceases to exist. I'm actually surprised you arent getting a NullPointerException.

What you should do instead is this:
Code:

```public void oddSquare() {                 square = new int[order][order]; // ...```
that way, you'll be referencing the instance variable and not the local one.
• 04-13-2010, 08:47 PM
gandalf5166
Here's my new code. It now generates a NullPointerException at the same points.
Code:

```public class Magic {         public static void main(String[] args) {             int order;             Scanner input = new Scanner(System.in);             Square square;             System.out.print("Enter the order of the magic square no greater than 20: ");             order = input.nextInt();             square = new Square(order);             while(order > 20 || order < 3) {                     System.out.println("Invalid input. Please enter an positive order no greater than 20: ");                     order = input.nextInt();               }               if (order % 2 == 1) {                       square.oddSquare();                     square.printSquare();             } else if(order % 4 == 0) {                     square.doubleSquare();                     square.printSquare();             } else {                     square.singleSquare();                     square.printSquare();             }     } }  class Square {         int x;         int y;         int order;         int[][] square;         int diag;         int num;         int counter;         public Square(int order) {         int diag = 1;         int num = 1;         int counter = 1;         int[][] square = new int[order][order];         }         public void oddSquare() {                 y = 0;                 x = order / 2;                 square[y][x] = num;                 while (counter <= order) {                 while (diag <= order) {                         num += 1;                         x += 1;                         y -= 1;                         if (x > order - 1) {                                 x = 0;                         }                         if (y < 0) {                                 y = order - 1;                         }                         square[y][x] = num;                         diag += 1;                 }                 diag = 1;                 counter += 1;                 y += 1;                 }         }         public void singleSquare() {                         }         public void doubleSquare() {                         }         public void printSquare() {                 System.out.print("+");                 for (int i = 1; i <= order; i++) {                 System.out.print("-----");                                        }                 System.out.println("+");                 for (int row = 0; row < order; row++) {                         for (int col = 0; col < order; col++) {                         System.out.print("|");                         System.out.format("%3d" + square[row][col]);                         }                 System.out.println("|");                 System.out.print("+");                 for (int i = 1; i <= order; i++) {                         System.out.print("----");                                        }                 System.out.println("+");                 }         }  }```
• 04-13-2010, 08:51 PM
gandalf5166
Oh sorry, hadn't noticed iluxa's post.
• 04-13-2010, 08:54 PM
iluxa
that's more like it.

here's how scopes work in Java:

Code:

```class A {   int x = 21;   public A () {   System.out.println (x);   int x = 48;   System.out.println (x);   printStuff ();   }   void printStuff () {   System.out.println (x);   } }```
will print "21", "48", "21"

The reason is this: when you say smth like "x=48", Java needs to decide exactly which variable you're talking about. In my example, there's two variables: one belongs to the class, and one you have just declared in the constructor. Java takes the most-recently-defined variable into account. When it goes out of scope, however, (meaning you've closed the } ), you're back to the original one.

Code:

```public Square(int order) {         int diag = 1;         int num = 1;         int counter = 1;         int[][] square = new int[order][order];         }```
what it does is defines local variables in the constructor, assigns values to them, and throws them away as soon as the constructor is done. The class variables are never touched. What you should do is

Code:

```public Square(int order) {         diag = 1;         num = 1;         counter = 1;         square = new int[order][order];         }```
so that you don't declare new variables. A useful practice is to say

Code:

```public Square(int order) {         this.diag = 1;         this.num = 1;         this.counter = 1;         this.square = new int[order][order];         }```
so that no ambiguity is left: "this" talks about the class, so you're assigning class's variables rather than local ones.
• 04-13-2010, 09:01 PM
gandalf5166
Ok, did what you said, and I'm not getting any more error messages, but for some reason all it will print out is 2 +'s no matter what the order is.
• 04-13-2010, 09:03 PM
iluxa
that's cause you aren't printing the + signs inside any loop... take a look at your printing code again
• 04-13-2010, 09:20 PM
gandalf5166
Yeah, but it won't print out anything else. Like the -'s or the |'s or the numbers. And actually, although it is kinda confusing, the +'s are being printed within a loop towards the end.
• 04-13-2010, 09:22 PM
iluxa
oh, i see what you're doing.

you're making the scope mistake again.

you're assigning "order" in one place, but using it in another where it was not assigned by anybody - see if you can figure it out.

if you have a debugger, would be useful to step through you program
• 04-13-2010, 09:28 PM
gandalf5166
I have a debugger, I have no idea how to use it though..... :C
• 04-13-2010, 09:31 PM
iluxa
In that case, stick "System.out.println ("order now is" + order);" EVERYWHERE and see what's going on
• 04-13-2010, 09:33 PM
gandalf5166
THANK YOU! OK, I can figure out this last error....
• 04-14-2010, 05:06 AM
gandalf5166
OK, it runs perfectly, but I've got a logic error. When it calculates the square it is supposed to start with one at the top in the middle. Then it should go up and to the right and put two there. If it goes of to the right or to the top, it should wrap around. Then, once it reaches a square that is already filled, it should move down a square and continue. The problem is, that instead of moving down, it moves to the right. Here's my code, what's going on?
Code:

``` class Square {         int x;         int y;         int order;         int[][] square;         int diag;         int num;         int counter;         public Square(int order) {         this.order = order;         this.diag = 1;         this.num = 0;         this.counter = 1;         square = new int[order][order];         }         public void oddSquare() {                 y = 0;                 x = order / 2;                 while (counter <= order) {                 while (diag <= order) {                         num += 1;                         if (x > order - 1) {                                 x = 0;                         }                         if (y < 0) {                                 y = order - 1;                         }                         square[y][x] = num;                         diag += 1;                         x += 1;                         y -= 1;                 }                 diag = 1;                 counter += 1;                 y += 1;                 if (y > order - 1) {                         y = 0;                 }                 }         }         public void singleSquare() {                         }         public void doubleSquare() {                         }         public void printSquare() {                 System.out.print("+");                 for (int i = 1; i <= order; i++) {                         if(i % 2 == 0) {                         System.out.print("---");                         } else {                         System.out.print("----");                         }                                        }                 System.out.println("+");                 for (int row = 0; row < order; row++) {                         for (int col = 0; col < order; col++) {                         System.out.print("|");                         System.out.format("%3d", + square[row][col]);                         }                 System.out.println("|");                 System.out.print("+");                 for (int i = 1; i <= order; i++) {                         if(i % 2 == 0) {                         System.out.print("---");                         } else {                         System.out.print("----");                         }                                        }                 System.out.println("+");                 }         }         public void magicNumber() {         }  }```
• 04-14-2010, 08:33 PM
gandalf5166
I hate to do this...... but bump?
• 04-14-2010, 08:48 PM
gandalf5166
FIGURED IT OUT!
Code:

```while (counter <= order) {                 while (diag <= order) {                         num += 1;                         x += 1;                         y -= 1;                         if (x > order - 1) {                                 x = 0;                         }                         if (y < 0) {                                 y = order - 1;                         }                         square[y][x] = num;                         diag += 1;                 }                 diag = 1;                 counter += 1;                 y += 1;                 }```
This part was screwed up. Once it fulfilled the condition of diag > order, it would still add 1 to x and subtract 1 from y. Therefore, when it then added 1 to y to go down, it would actually just counteract the minus 1 earlier, leaving the additional one to x. All I had to do was add an if statement so it would check the status of diag before it moved up and to the right.
• 04-14-2010, 08:49 PM
gandalf5166
Actually, that wasn't the problem. The solution still works though!
• 04-15-2010, 03:49 AM
gandalf5166
Ok, so I've started on the method for squares whose orders can be divided by four. The way you do those starts with dividing the square in to as many 4x4 squares as it takes and drawing diagonal lines through each of these smaller squares. So I'm writing the bit that does that. Rather than drawing a line, it changes the value to 900. So the way I'm testing this is, before I write the rest, I'm running the program so it will print out the square with just zeros and 900's. So I should see mostly zeros with diagonal lines of 900's through it. But what I am seeing is a table of zeros. If you're having trouble seeing what I'm doing, draw a 4x4 square and then draw diagonal lines through it. This was the only way I could think of to get the same effect. Here's the code for the line drawing.
Code:

```x = 0;                 y = 0;                 for (int i = 0; i  <= order / 4; i++){                 for (int j = 0; j  <= order / 4; j++){                         square[y][x] = 900;                         x += 3;                         square[y][x] = 900;                         x += 1;                 }                 x = 0;                 y += 1;                 for (int j = 0; j <= order / 4; j++) {                         x += 1;                         square[y][x] = 900;                         x += 1;                         square[y][x] = 900;                         x += 2;                 }                 x = 0;                 y += 1;                 for (int j = 0; j <= order / 4; j++) {                         x += 1;                         square[y][x] = 900;                         x += 1;                         square[y][x] = 900;                         x += 2;                 }                 x = 0;                 y += 1;                 for (int j = 0; j  <= order / 4; j++) {                         square[y][x] = 900;                         x += 3;                         square[y][x] = 900;                         x += 1;         }         y += 1;         }```
And while I'm at it, does a for condition check before or after it counts up?
• 04-15-2010, 05:57 PM
gandalf5166
I am forced to do this once again...... bump.
• 04-15-2010, 07:08 PM
gandalf5166
I figured it out. It had to do with a problem in the client code. Sorry.
Show 40 post(s) from this thread on one page
Page 1 of 2 12 Last