Как я могу упростить код, например с помощью цикла?

if (gameField[0][0] == gameField[0][1] && gameField[0][0] == gameField[0][2] && (gameField[0][0] == 'X' || gameField[0][0] == 'O' )) {
    isGame = false;
} else if (gameField[1][0] == gameField[1][1] && gameField[1][0] == gameField[1][2] && (gameField[1][0] == 'X' || gameField[1][0] == 'O' )) {
    isGame = false;
} else if (gameField[2][0] == gameField[2][1] && gameField[2][0] == gameField[2][2] && (gameField[2][0] == 'X' || gameField[2][0] == 'O' )) {
    isGame = false;
} else if (gameField[0][0] == gameField[1][0] && gameField[0][0] == gameField[2][0] && (gameField[0][0] == 'X' || gameField[0][0] == 'O' )) {
    isGame = false;
} else if (gameField[0][1] == gameField[1][1] && gameField[0][1] == gameField[2][1] && (gameField[0][1] == 'X' || gameField[0][1] == 'O' )) {
    isGame = false;
} else if (gameField[0][2] == gameField[1][2] && gameField[0][2] == gameField[2][2] && (gameField[0][2] == 'X' || gameField[0][2] == 'O' )) {
    isGame = false;
} else if (gameField[0][0] == gameField[1][1] && gameField[0][0] == gameField[2][2] && (gameField[0][0] == 'X' || gameField[0][0] == 'O' )) {
    isGame = false;
} else if (gameField[2][0] == gameField[1][1] && gameField[2][0] == gameField[0][2] && (gameField[2][0] == 'X' || gameField[2][0] == 'O' )) {
    isGame = false;
}

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

Автор решения: Nowhere Man

Очень похоже, что данный код вычисляет условие завершения игры в обычные "крестики-нолики" размером 3х3 в "развёрнутом" виде: сначала проверяются строки, затем столбцы и в конце диагонали.

Разумеется, такой код можно переписать, чтобы заменить повторяющиеся условия на циклы, но в целом исправленный код вряд ли станет "проще".

Например, будем проверять в цикле строку или столбец, а проверку диагоналей выполним при необходимости вне цикла. Также будем проверять, что клетка не пустая, вместо "сложного" условия на заполнение клетки X или O.

final char EMPTY = ' '; // допустим что пустое поле обозначено пробелом
var isGame = true;
for (int i = 0; i < 3 && isGame; i++) {
    // строки
    if (arr[i][0] != EMPTY && arr[i][0] == arr[i][1] && arr[i][0] == arr[i][2]) {
        isGame = false;
    }
    // столбцы 
    else if (arr[0][i] != EMPTY && arr[0][i] == arr[1][i] && arr[0][i] == arr[2][i]) {
        isGame = false;
    }
}
// диагонали
if (isGame && arr[1][1] != EMPTY) {
    if ((arr[0][0] == arr[1][1] && arr[2][2] == arr [1][1]) || (arr[0][2] == arr[1][1] && arr[2][0] == arr [1][1])) {
        isGame = false;
    }
}

Также можно было бы просуммировать во вложенных циклах значения по строкам, столбцам, диагоналям, и если какая-то из сумм кратна нужному значению X или O, то выходим из внешнего цикла.

final int N = 3;
var isGame = true;

for (int i = 0; i < N && isGame; i++) {
    int row = 0, col = 0;
    int mainDiag = 0, antiDiag = 0;

    for (int j = 0; j < N; j++) {
        row += arr[i][j];
        col += arr[j][i];
        if (i == 0) {
            mainDiag += arr[j][j];
            antiDiag += arr[N - 1 - j][j];
        }
    }
    if (IntStream.of(row, col, mainDiag, antiDiag).anyMatch(x -> x / N == 'X' || x / N == 'O')) {
        isGame = false;
    }
}

В данном случае из кода исчезают почти все условные операторы, но логическая сложность просто переносится в циклы и операцию Stream API anyMatch.

→ Ссылка