Исключение `ArrayIndexOutOfBoundsException` при попытке повернуть массив на 90 градусов

Данный код выбрасывает исключение ArrayIndexOutOfBoundsException при попытке "повернуть" квадратный массив на 90 градусов, когда сохраняю результат в новый массив.

Перепроверял, но не вижу причины.

int[][] gameField = {
    {1,2,4,3},
    {1,0,4,0},
    {0,2,0,0},
    {8,4,2,0}
};
int[][] copyArr = {{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}};
//{{8,0,1,1},
//{4,2,0,2},
//{2,0,4,4},
//{0,0,0,3}}; пытаюсь получить такое,т.е. повернуть массив на 90 градусов

for (int x = 0; x < gameField.length; x++) {
    int i = 3;
    for (int y = 0; y < gameField[x].length; y++) {
        int temp = 0;
        copyArr[x+i][y] = gameField[y][x];
    }
    i -= 2;
}

Ответы (2 шт):

Автор решения: Сергей
int[][] gameField ={{1,2,4,3},{1,0,4,0},{0,2,0,0},{8,4,2,0}};
    int[][] copyArr = {{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}};
    //{{8,0,1,1},{4,2,0,2},{2,0,4,4},{0,0,0,3}}; пытаюсь получить такое,т.е. повернуть массив на 90градусов
    int i = 3; //нужно было вынести из цикла, иначе присваивалось заново каждый раз
for(int x = 0; x<gameField.length; x++){
    
      for(int y = 0;y<gameField[x].length;y++){
          copyArr[y][x+i] = gameField[x][y];
      }
      i-=2;
  }
  gameField = copyArr;
→ Ссылка
Автор решения: Nowhere Man

Вариант с инициализацией переменной i и "хитрой" индексной арифметикой copyArr[y][x+i] = gameField[x][y]; с последующей дополнительной коррекцией i -= 2 можно было бы упростить.

При "повороте" на 90 градусов последний столбец заполняется снизу элементами первой строки, предпоследний столбец - второй строки, и так далее, что можно было бы записать как показано ниже.

Также для инициализации двумерного массива нулями достаточно создать его, указав оба размера

static int[][] rotate90(int[][] square) {
    int n = square.length;
    int[][] arr = new int[n][n];
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            arr[j][n - 1 - i] = square[i][j];
        }
    }
    return arr;
}

Аналогично, первый столбец заполняется элементами последней строки, второй столбец -- предпоследней строки и т.д.:

static int[][] rotate90(int[][] square) {
    int n = square.length;
    int[][] arr = new int[n][n];
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            arr[j][i] = square[n - 1 - i][j];
        }
    }
    return arr;
}

Аналогично, первая строка заполняется "снизу" элементами первого столбца:

static int[][] rotate90(int[][] square) {
    int n = square.length;
    int[][] arr = new int[n][n];
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            arr[i][j] = square[n - 1 - j][i];
        }
    }
    return arr;
}
→ Ссылка