Судоку Солвер Бесконечная рекурсия Java - PullRequest
0 голосов
/ 17 сентября 2018

Я строю решатель судоку на Java и использую алгоритм возврата. Произошла ошибка переполнения стека, и я подозреваю, что где-то в моем коде есть бесконечная рекурсия. Я знаю, что даю мало информации, но я так застрял и не знаю, как это сделать.

    public void run(int r, int c){
        if(!grid[r][c].isOriginal()){
            checkAll(r, c);
        }

        if(moveOn){
            if(c < 8){
                c++;
            } else if (r < 8){
                c = 0;
                r++;
            }
        } else {
            if(c > 0){
                c--;
            } else if(r > 0){
                c = 8;
                r--;
            }
        }

        if(!finished()) {
            run(r, c);
        }
    }

    public void checkAll(int r, int c){
        if(grid[r][c].getVal() < 9) {
            grid[r][c].setVal(grid[r][c].getVal() + 1);
            if(checkSquare(r, c) && checkRow(r, c) && checkCol(r, c)){
                moveOn = true;
            } else {
                checkAll(r, c);
            }
        } else {
            moveOn = false;
            grid[r][c].setVal(0);
        }
    }
}

Кажется, что все функции "checkRow", "checkCol" и "checkSquare" работают, как и "Finished" и "PrintGrid".

Я запускаю программу, вызывая

run(0, 0);

в основном, с программой, решающей судоку слева направо, затем сверху вниз.

Сетка, представляющая собой массив 9 на 9, представляющий каждый квадрат судоку, содержит пользовательский тип, называемый «Значение», который просто содержит целое число и логическое значение «isOriginal», указывающее, было ли значение заданным или изменяемым.

«moveOn» - это глобальная переменная, значение которой установлено в «checkAll» и решает, следует ли перейти к следующему квадрату судоку или возврату.

1 Ответ

0 голосов
/ 17 сентября 2018

Один совет, который может помочь вам в будущем, постарайтесь избегать глобальных переменных. Тот факт, что вы используете переменную "moveOn" в качестве глобальной, сложнее в отладке и менее предсказуем. Сделайте так, чтобы ваша функция "checkAll" возвращала логическое значение вместо этой глобальной переменной.

Теперь по вашей проблеме, я думаю, что при вашем рекурсивном вызове checkAll вам следует что-то изменить в одной из ваших переменных, верно? В противном случае он всегда будет иметь одинаковые параметры на входе.

...