0

I call function move with 2 dimensional array full of zeros at point [6, 5] which has value 0. The function increases the value to 1.

Then the same function call itself again move(x - 1, y, map, i), which means it is at point [5, 5] with value 0, which it increases to 1 and ends itself.

But why was the map variable updated also in the function, which was called first?

private static byte[10][10] myMap = {*all zeros*};

public static void main(String[] args) {
    move(6, 5, myMap, 0);
}

private static void move(int x, int y, byte[][] map, int i) {
    if (map[x][y] == 0) {
        map[x][y]++;
        i++;
    }
    if (i > 1) return;

    System.out.print(x + " " + y);
    // 6 5
    System.out.print(map[5][5] + " " + i);
    // 0 1
    move(x - 1, y, map, i);

    System.out.print(map[5][5] + " " + i);
    // 1 1 ... WTH? Shouldn't this return 0 1 like above?
}

And when it updates the map, why it doesn't update the i variable?

I'm struggling hours to find why, but still don't know:/ Thanks for help

user2781994
  • 469
  • 1
  • 5
  • 12
  • What about `private static byte[][] myMap = new byte[10][10]`? Note that in Java arrays will always be initialized to `false`, `0` or `null`. – Maarten Bodewes Nov 22 '14 at 13:43
  • I've updated the some example in the answer for using your map, but in the end you may want to create a `Board` class that uses the `byte[][]` as field (or cal it `GameMap`, but not `Map` as that is a heavily used class from `java.util`). – Maarten Bodewes Nov 22 '14 at 14:18
  • @owlstead Thanks, I just needed the cloneMap function.. Since I'm not doing any game, I don't have to store the maps, the only thing I care about is the **i** and time how long it takes to travel considering the robot I'm building this for.. I deleted all the methods and stuff around just to show my problem ;) – user2781994 Nov 22 '14 at 16:51

1 Answers1

3

This can be confusing at first sight, but it is very easy to understand when you understand passing by reference and passing by value.

Array variables consist of a reference to the actual array. Basically they are treated the same as objects. This means that you are updating the map that you give to the function.

int variables are primitive types (int, short, byte, long, char, float, double and of course boolean - note the initial lowercase character in the names), which are passed by value in Java. Basically a copy of the value is made. So you can never use such a variable to return any value. You need a return statement if you want to do that.


For example:

// using depth first, then width!!!
private static byte[][] myMap = new byte[10][10];

public static void main(String[] args) {
    move(6, 5, myMap, 0);
}

private static byte[][] cloneMap(byte[][] map) {
    byte[][] newMap = new byte[map.length][];
    for (int x = 0; x < map.length; x++) {
        newMap[x] = map[x].clone();
    }
    return newMap;
}

private static void printMap(byte[][] map) {
    for (int x = 0; x < map.length; x++) {
        for (int y = 0; y < map[0].length; y++) {
            System.out.printf("%3d ", map[x][y] & 0xFF);
        }
        System.out.printf("%n");
    }
}

private static int move(int x, int y, byte[][] map, int i) {
    if (map[x][y] == 0) {
        map[x][y]++;
        i++;
    }
    if (i > 1) return i;

    System.out.printf("x: %d, y: %d%n", x, y);
    // 6 5

    printMap(map);
    System.out.printf("i: %d%n", i);

    // -- note, you may still be missing some way of storing the maps
    map = cloneMap(map);
    i = move(x - 1, y, map, i);

    // System.out.println(map[5][5] + " " + i);
    printMap(map);
    System.out.printf("i: %d%n", i);
    return i;
}
Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
  • Ok, thanks! But how to pass that array by value? – user2781994 Nov 22 '14 at 13:23
  • 3
    @Dev no. Everything is pass by value. – MeBigFatGuy Nov 22 '14 at 13:34
  • @owlstead My bad, I flipped it (in fairness you did as well before you edited which tripped me up). My point was that primitives and objects are handled the same way pass-by-value, just primitives by their nature are immutable. Either way +1 for the explanation. – Dev Nov 22 '14 at 13:35
  • @owlstead I'm sorry, but I'm not sure how you meant it. Could you quickly show it? Thank you ;) – user2781994 Nov 22 '14 at 13:40
  • @Dev In Java, everything is passed by Value. You pass the copy of the object's reference in the function argument. – ha9u63a7 Nov 22 '14 at 13:43
  • @owlstead Thank you, I didn't know how to implement the cloneMap fn only ;) – user2781994 Nov 22 '14 at 13:58
  • @hagubear I understand this, the whole stream of comments is a misunderstanding. I copied an error owlstead made in the original post without realizing it while commenting on a different but related point and it made me look bad. Three people have been by to tell me so :(. It was an honest mistake, I swear! – Dev Nov 22 '14 at 14:05