Заполнение двумерного массива случайными числами

Я начал проект, пытаясь создать загадку Кена Кена. Если вы не уверены, что такое Кен Кен, он похож на Судоку в том смысле, что в строке или столбце не может быть дублированных целочисленных значений.

Я пытаюсь заполнить 2D-массив числами из списка Array List, который создается для каждой новой строки. Я проверяю, не совпадает ли число, взятое из списка массивов, с какими-либо числами в его строке и столбце.

Когда я запускаю свой код, я получаю исключение "Индекс вне границ", когда я пытаюсь удалить целочисленное значение из списка. Я не уверен, почему это происходит, потому что я думаю, что получаю правильный элемент.

Вот мой код:

int GRID_SIZE = 4;int[][] grid = new int[GRID_SIZE][GRID_SIZE];List<Integer> nums = new ArrayList<Integer>();

private void populateGrid() {

    for (int row = 0; row < GRID_SIZE; row ++) {

        // Creates an array of values from 1 to grid size.
        for (int i = 1; i <= GRID_SIZE; i++) nums.add(i);

        for (int col = 0; col < GRID_SIZE; col++) {

            while (nums.size() > 0) {

                // Gets a random number from the Array List
                int ranNum = nums.get(numGen.nextInt(GRID_SIZE));

                // Checks to see if the number is placeable.
                if (canPlace(ranNum, row, col)) {

                    // Places the number in the 2D Array
                    grid[row][col] = ranNum;
                    break;

                } else {

                    // Removes duplicate element from the Array List.
                    nums.remove(ranNum); <------{Index Out Of Bounds Exception]
                }
            }
        }
    } 
}

private boolean canPlace(int ranNum, int row, int col) {

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

        // Checks if the specified number is already in the row/column.
        if (grid[col][i] == ranNum) return false;
        if (grid[i][row] == ranNum) return false;
    }

    return true;
}

У меня есть несколько вопросов по этому поводу:

Прежде всего, почему я получаю ошибку, которая у меня есть?

Во-вторых, есть ли что-нибудь лучше использовать, чем 2D Array для сетки и способ размещения моих чисел?

Наконец, правильно ли я использую перерыв?

Заранее спасибо за ваши ответы.

4 ответа

Решение

Как насчет другого подхода к проблеме? Начните с правильного квадрата и преобразуйте его. Две операции, "обмен двух строк" ​​и "обмен двух столбцов", сохраняют свойства квадрата. Это позволяет вам сделать два шаффла Фишера-Йейтса, один в строках и один в столбцах, которые дадут вам правильный рандомизированный квадрат, если вы начнете с действительного квадрата. Построение начального действительного квадрата тривиально:

123456
234561
345612
456123
561234
612345

IndexOutOFBoundsException происходит из-за сбоя (ИМО) в List API. Оно имеет remove(Object element) метод, который вы хотите вызвать, и remove(int index) метод, который вы на самом деле вызываете. Последний пытается удалить элемент по указанному индексу, которого там нет, так как ваш аргумент, вероятно, больше, чем размер списка. Вы можете бросить свой ranNum переменная либо Integer или же Object чтобы убедиться, что вы вызываете правильный метод.

for (int i = 0; i <= GRID_SIZE; i++) nums.add(i);

Это не имеет большого смысла для меня. Вы добавляете цифры от 0 до 4. У вас есть только до 3 индексов в ваших массивах. 0-1-2-3...

На самом деле не видеть больше кода или точно знать, где вы получаете свой индекс за пределами границ... это выстрел в темноте.

После тщательного анализа кода я понял, что моей главной ошибкой было canPlace(int ranNum, int row, int col) метод.

Все, что я сделал, это поменял col а также row ценности и это сработало.

Спасибо за вашу помощь.

Другие вопросы по тегам