1. Member
Join Date
Feb 2010
Posts
75
Rep Power
0

## 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.
Java 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.

2. Member
Join Date
Feb 2010
Posts
75
Rep Power
0
Never mind. I just noticed like, eight different problems with this.

3. Senior Member
Join Date
Mar 2010
Posts
266
Rep Power
7
Java 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:
Java Code:
```public void oddSquare() {
square = new int[order][order];
// ...```
that way, you'll be referencing the instance variable and not the local one.

4. Member
Join Date
Feb 2010
Posts
75
Rep Power
0
Here's my new code. It now generates a NullPointerException at the same points.
Java 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("+");
}
}
}```

5. Member
Join Date
Feb 2010
Posts
75
Rep Power
0
Oh sorry, hadn't noticed iluxa's post.
Last edited by gandalf5166; 04-13-2010 at 08:57 PM.

6. Senior Member
Join Date
Mar 2010
Posts
266
Rep Power
7
that's more like it.

here's how scopes work in Java:

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.

Java 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

Java 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

Java 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.

7. Member
Join Date
Feb 2010
Posts
75
Rep Power
0
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.

8. Senior Member
Join Date
Mar 2010
Posts
266
Rep Power
7
that's cause you aren't printing the + signs inside any loop... take a look at your printing code again

9. Member
Join Date
Feb 2010
Posts
75
Rep Power
0
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.

10. Senior Member
Join Date
Mar 2010
Posts
266
Rep Power
7
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

11. Member
Join Date
Feb 2010
Posts
75
Rep Power
0
I have a debugger, I have no idea how to use it though..... :C

12. Senior Member
Join Date
Mar 2010
Posts
266
Rep Power
7
In that case, stick "System.out.println ("order now is" + order);" EVERYWHERE and see what's going on

13. Member
Join Date
Feb 2010
Posts
75
Rep Power
0
THANK YOU! OK, I can figure out this last error....

14. Member
Join Date
Feb 2010
Posts
75
Rep Power
0
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?
Java 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() {
}
}```

15. Member
Join Date
Feb 2010
Posts
75
Rep Power
0
I hate to do this...... but bump?

16. Member
Join Date
Feb 2010
Posts
75
Rep Power
0
FIGURED IT OUT!
Java 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.

17. Member
Join Date
Feb 2010
Posts
75
Rep Power
0
Actually, that wasn't the problem. The solution still works though!

18. Member
Join Date
Feb 2010
Posts
75
Rep Power
0
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.
Java 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?
Last edited by gandalf5166; 04-15-2010 at 03:51 AM.

19. Member
Join Date
Feb 2010
Posts
75
Rep Power
0
I am forced to do this once again...... bump.

20. Member
Join Date
Feb 2010
Posts
75
Rep Power
0
I figured it out. It had to do with a problem in the client code. Sorry.

Page 1 of 2 12 Last

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•