0

I have a class for finding a path through a basic maze. A maze is passed to path along with starting and ending positions. I use recursion to find a path between the points. The path is returned as a boolean array. For some reason the initial maze passed to the Path() gets changed. So I tried making a copy of the maze array to avoid changing any values but it is still not working.

Why is path() making changes to open[][]? Might be the C programming confusing me here.

public static boolean[][] path(boolean[][] open, 
                               int start_i, int start_j, 
                               int end_i, int end_j) 
{
    int n = open.length;
    boolean[][] openCopy = new boolean[n][n]; //make a copy of open

    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < n; j++)
        {
            openCopy[i][j] = open[i][j]; 
        }
    } 
    return findPath(openCopy, start_i, start_j, end_i, end_j);
}

public static boolean[][] findPath(boolean[][] openCopy, int start_i, int start_j, int end_i, int end_j) 
{
    boolean[][] path = new boolean[openCopy.length][openCopy[0].length];

    if(openCopy[start_i][start_j] == false) //return false if current position is not open
        return path;
    else
        openCopy[start_i][start_j] = false;  //make current position false if not (to prevent infinite backtracking)

    if(start_i == end_i && start_j == end_j) //if end found return true
    {
        path[start_i][start_j] = true;
        return path;
    }

    path = findPath(openCopy, start_i+1, start_j, end_i, end_j); // Move North
    path = findPath(openCopy, start_i, start_j+1, end_i, end_j); // Move East
    path = findPath(openCopy, start_i-1, start_j, end_i, end_j); // Move South
    path = findPath(openCopy, start_i, start_j-1, end_i, end_j); // Move West

    return path;
}
Ace
  • 462
  • 4
  • 10
  • 17
  • Look at this link: http://stackoverflow.com/questions/7127530/does-array-changes-in-method – AKS Mar 14 '14 at 20:06
  • 2
    @AKS "boolean[][] openCopy = new boolean[n][n];" should create a new array which can be changed without changing the original array. At least I think so. – Ace Mar 14 '14 at 20:14
  • How are you seeing the value change? Nothing here would affect the array `open` passed into `path()` – DHall Mar 14 '14 at 20:15
  • @DHall I printed 'open' before passing to path() and then printed it afterwards and it doesn't match. I will check my printing again for mistakes. – Ace Mar 14 '14 at 20:19

2 Answers2

3

It doesnt, I know this might not be exactly 'appropriate' input for the method, but it proves the point:

public class MainForm {


public static void main(String[] args) {
    boolean[][] array = new boolean[][] {{false, false, true, false, false, false}, 
            {false, false, true, false, false, false}, 
            {false, false, true, false, false, false}, 
            {false, false, true, false, false, false}};

    boolean[] [] another = path(array, 0, 0, 3, 5);

    for (boolean[] bArray : array) {
        for (boolean b : bArray) {
            System.out.println(b);
        }
    }
    System.out.println("***********************");
    for (boolean[] bArray : another) {
        for (boolean b : bArray) {
            System.out.println(b);
        }
    }
}

public static boolean[][] path(boolean[][] open, int start_i, int start_j, int end_i, int end_j) {
    int n = open.length;
    boolean[][] openCopy = new boolean[n][n]; // make a copy of open

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            openCopy[i][j] = open[i][j];
        }
    }
    return findPath(openCopy, start_i, start_j, end_i, end_j);
}

public static boolean[][] findPath(boolean[][] openCopy, int start_i, int start_j, int end_i, int end_j) {
    boolean[][] path = new boolean[openCopy.length][openCopy[0].length];

    if (openCopy[start_i][start_j] == false) // return false if current position is not open
        return path;
    else
        openCopy[start_i][start_j] = false; // make current position false if not (to prevent infinite backtracking)

    if (start_i == end_i && start_j == end_j) // if end found return true
    {
        path[start_i][start_j] = true;
        return path;
    }

    path = findPath(openCopy, start_i + 1, start_j, end_i, end_j); // Move North
    path = findPath(openCopy, start_i, start_j + 1, end_i, end_j); // Move East
    path = findPath(openCopy, start_i - 1, start_j, end_i, end_j); // Move South
    path = findPath(openCopy, start_i, start_j - 1, end_i, end_j); // Move West

    return path;
}
}

output

false
false
true
false
false
false
false
false
true
false
false
false
false
false
true
false
false
false
false
false
true
false
false
false
***********************
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false
false

Clearly the returned array and the one passed into path() are different in their contents, and the original values of the original array remain intact. I think the problem lies elsewhere in your application.

Mark W
  • 2,791
  • 1
  • 21
  • 44
0

i think the problem is, that you are passing around references in your inner for-loop. Try instead of this:

for(int j = 0; j < n; j++)
        {
            openCopy[i][j] = open[i][j]; 
        }

this:

for (int j = 0; j < n; j++) {
    openCopy[i][j] = new Boolean(open[i][j]);
}

I think it should help.

Gee858eeG
  • 185
  • 8
  • since the array is declared `boolean[][]` not `Boolean[][]`, they should be primitives and therefore not references. Does java automatically box/unbox primitives in an array of primitives? – clcto Mar 14 '14 at 20:26
  • Yeah, you might be right. Boxing unboxing is completely automatic in java. no need to worry about that, as i experienced. – Gee858eeG Mar 14 '14 at 20:28
  • Well program just crashed and now path isn't working at all :/ – Ace Mar 14 '14 at 20:36
  • What does stacktrace say? java.lang.ArrayIndexOutOfBoundsException? – Gee858eeG Mar 14 '14 at 20:59