java.lang.ArrayIndexOutOfBoundsException

342
26 января 2017, 01:49

Помогите найти ошибку, плиз. Пытаюсь написать консольные крестики-нолики, однако один из циклов не думает заканчиваться, хотя вроде как все условия для этого выполнены. Сам цикл:

do {
    Scanner coord = new Scanner(System.in);
    System.out.println(player1Name + ", введите номер ячейки по горизонтали (от 1 до 3):");
    x = coord.nextInt() - 1;
    System.out.println(player1Name + ", введите номер ячейки по вертикали (от 1 до 3):");
    y = coord.nextInt() - 1;
    if (field[x][y] == '_'){
        field[x][y] = 'X';
    } else {
        System.out.println("Это поле уже занято, попробуйте снова.");
    }
       for (x = 0; x < SIZE; x++) {
            for (y = 0; y < SIZE; y++) {
                    System.out.print(field[x][y] + " ");
            }
            System.out.println();
    }
    System.out.println();
} while (field[x][y] == 'X');

Проблема где-то здесь while (field[x][y] == 'X'); насколько я понимаю, но в чем проблема, до меня не доходит. Поле 3х3, если игрок введет координаты х = 1, у = 2, то выведется поле вида

_ Х _
_ _ _
_ _ _

Т.е. как и должно, но проверку в конце цикла не проходит и опять начинает крутить сначала.

Ошибка полностью:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
at Main.main(Main.java:80)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Answer 1

По поводу того почему цикл не заканчивается:

do {
    //...пропуск
    if (field[x][y] == '_'){
        field[x][y] = 'X'; //Здесь мы заполнили поле x,y
    } else {
        System.out.println("Это поле уже занято, попробуйте снова.");
    }
    //после этого field[x][y] обязательно Х
    //...пропуск
} while (field[x][y] == 'X'); //а здесь мы проверяем, что х,у заполнено: ответ всегда да

Т.е. проверка выбранного поля производится после его заполнения.

Выйти из цикла можно разными способами:

  • сделать break из if при выборе пустого поля;
  • создать переменную-флаг и отслеживать было ли выбрано пустое поле или нет;
  • изменить структуру кода: в цикле только проверять возможность заполнения, а заполнять снаружи.

Почему возникает ArrayIndexOutOfBoundsException: переменные x и у используются повторно для распечатки массива, после выполнения циклов их значения меняются:

for (x = 0; x < SIZE; x++) {
        for (y = 0; y < SIZE; y++) {
                System.out.print(field[x][y] + " ");
        }
        //здесь у = SIZE
        System.out.println();
}
//здесь x=SIZE

Исправить это можно если использовать для циклов локальные переменные

for (int i = 0; i < SIZE; i++) {

либо вообще отдельный метод для распечатки.

Answer 2

По окончании циклов:

for (x = 0; x < SIZE; x++) {
        for (y = 0; y < SIZE; y++) {
                System.out.print(field[x][y] + " ");
        }
        System.out.println();
}

получится, что x=y=SIZE;

Далее вы пытаетесь извлечь field[x][y], где x, y уже лежат за границами массива и естественно получаете в ответ грубость.

Пересмотрите логику.

READ ALSO
AlarmManager срабатывает с задержкой

AlarmManager срабатывает с задержкой

AlarmManager срабатывает не в конкретно заданное время, а спустя ~5 минут после заданного времени

281
Почему не могу получить доступ к методам dll библиотеки?

Почему не могу получить доступ к методам dll библиотеки?

Добрый день, работаю с JNA подключился через интерфейс кdll библиотеке но при вызове из неё метода пишет

321
Настроить цикличный запуск

Настроить цикличный запуск

Доброго времени сутокЕсть код:

290
Удалить линию Line2D двойным кликом мышки (Java | JFrame)

Удалить линию Line2D двойным кликом мышки (Java | JFrame)

Добрый день! Хочу удалить нарисованную линию двойным кликом мышкиПри навведении на линию, курсор не меняется на крест

374