user2741226
user2741226

Reputation: 33

how to flip a 2D array in Java

Hi I'm working on a simple L-game. I want to flip an array from left to right horizontally. For example,

{ 'x',' ',' ',' ' },

{ 'x',' ',' ',' ' },

{ 'x','x',' ',' ' },

{ ' ',' ',' ',' ' }

I want to flip it to

{ ' ','x',' ',' ' },

{ ' ','x',' ',' ' },

{ 'x','x',' ',' ' },

{ ' ',' ',' ',' ' }

And this is my current code

    public void flipArray() {
    int rows = cells.length;
    int cols = cells[0].length;
    char temp[][] = new char[rows][cols];
    for (int i = rows-1; i>=0; i--) {
        for (int j = cols-1; j>=0; j--) {
            temp[rows-1-i][cols-1-j] = cells[i][j];
        }
    }
    for (int i=0; i<rows; i++) {
        for (int j=0; j<cols; j++) {
            System.out.print(temp[i][j] + " ");
        }
    }
    }

Thank you so much any help is much appreciated. This is my desired outcome.



    rand_seed = 14427                                                       rand_seed = 14427
$ LGame.main({})                                                        $ LGame.main({})
A i i                                                                   A i i   
  o i                                                                     o i   
  o i                                                                     o i   
  o o B                                                                   o o B 
Move: o101                                                              Move: o101
A i i                                                                   A i i   
  o i                                                                |  o   i   
  o i                                                                |  o   i   
o o   B                                                                 o o   B 

Upvotes: 2

Views: 5356

Answers (1)

Durandal
Durandal

Reputation: 20069

Your code is so convoluted I'm not even trying to make sense of it. The problem gets a lot simpler and easier to grasp if you split it into sub problems.

First the basic building block, reversing a single array:

 static void flip(char[] array) {
     int left = 0;
     int right = array.length - 1;
     while (left < right) {
         char temp = array[left];
         array[left] = array[right];
         array[right] = temp;
         ++left;
         --right;
     }
 }

Now you can just walk your rows array and call flip for each row:

static void flip(char[][] rows) {
    for (char[] row : rows) {
        flip(row);
    } 
}

You see its pretty simple when you split it up into smaller problems.

Edit: Finding the bounding box of the "L" in the two-dimensional array can again be split into smaller problems. You can just walk the rows, check if they are completely empty and if they are not, find the min and max index where a cell is "set". For simplicity I do it in one method in two nested loops:

 static int[] getBoundingBox(char[][] rows) {
     int minY = Integer.MAX_VALUE;
     int maxY = Integer.MIN_VALUE;
     int minX = Integer.MAX_VALUE;
     int maxX = Integer.MIN_VALUE;
     for (int y=0; y<rows.length; ++y) {
         // find the rows min/max populated index
         char[] row = rows[y];
         int rowMinX = Integer.MAX_VALUE;
         int rowMaxX = Integer.MIN_VALUE;
         for (int x=0; x<row.length; ++x) {
             if (row[x] == 'x') {
                 rowMinX = Math.min(rowMinX, x);
                 rowMaxX = Math.max(rowMaxX, x);
             }                 
         }
         // check if the row is empty (min > max)
         if (rowMinX > rowMaxX) {
              // empty row, skip
              continue;
         }
         // update bounding box variables
         minY = Math.min(minY, y);
         maxY = Math.max(maxY, y);
         minX = Math.min(minX, rowMinX);
         maxX = Math.max(maxX, rowMaxX);
     }          
     // result is an array containing the bounds
     return new int[] { minX, minY, maxX, maxY };
}

You should really be able to connect the pieces now.

Edit2: All thats left to do is modify the flip(rows[][]) to take the bounds, and call flip(row[]) for just the rows in between minY and maxY. The row flip then needs to be passed the min/max X from the bounds and use the passed values instead of 0/length for left/right. Just think it through, it will be obvious if you think a little about it.

Off topic, but probably you're still in the process of learning that: The reason you split your code into small methods that solve only a sub-problem each is that you can a) re-use them to solve the same problem from a different place and b) the less code there is in a method the easier it is to verify what it does and if it works. Packing everything in one big method makes it harder to understand and when you need to solve part of the problem elsewhere you would duplicate code (and effort).

Upvotes: 2

Related Questions