开发者

Why does this recursive method for a sudoku-solver keep on spinning?

开发者 https://www.devze.com 2023-02-25 18:44 出处:网络
In a school assignment we\'re supposed to make a soduko-solver. I have a recursive method that\'s supposed to help me solve the soduko-puzzles. It goes like this:

In a school assignment we're supposed to make a soduko-solver. I have a recursive method that's supposed to help me solve the soduko-puzzles. It goes like this:

public void setNumber() {

if (getNext() == null) {

    for (int i = 1; i < 10; i++) {
    if (acceptValue(i)) {
        value = i;
    }
    }
    board.stopRec();
    return; 

} else { 


    if(predefined()) { // if the square allready has a number
    getNext().setNumber();
    } else { // find value for undefined square

    for (int i = 1; i < 10; i++) {
        if (acceptValue(i)) {
        value = i // Does the Row class take notice of this?
        getNext().setNumber();
        }
    }
    /* no value was assigned */
    value = -1;

    }

}

}

The Board class has a method initGrid, that creates all the Squares and link them together using a nextSquare reference

class Board {

[...]

public void initGrid(int nSquaresBoxRowCol, int nRowsBox, int nColsBox, int[][] values) {

[...]

/* Create the rows, columns and squares */
Square prev = null;
for (int row = 1; row <= nRowsBoard; row++) {

    //Row r = new Row(row, squares[row-1]);
    Row r = new Row(row);
    rows[row-1] = r;

    for (int col = 1; col <= nColsBoard; col++) {
    if (row == 1) {
        Column c = new Column(col);
    }

    Square current = new Square(row, col, Math.ceil((float)row / (float)nRowsBox), Math.ceil((float)col / (float)nColsBox), values[row-1][col-1], r, this);

    if (!((row-1) == 0 && (col-1) == 0)) {
        p开发者_运维知识库rev.nextSquare = current;
    }

    prev = current;
    squares[row-1][col-1] = current;

    r.addSquare(current);

    /* Fill the boxes with squares */
    boxes[(int)(Math.ceil((float)row / (float)nRowsBox)) - 1][(int)(Math.ceil((float)col / (float)nColsBox)) - 1].addSquare(squares[row-1][col-1]);
    nSquares++;

    }

} // END for (int row ...

Objects of the Row class hopefully hold the square objects added to them in the initGrid-method in the Board class.

class Row {
int id;

Square[] squares;
ArrayList<Square> squareList;

Row(int id) {
this.id = id; // not currently used for anything
squareList = new ArrayList<Square>();
}

boolean checkValue(int val) {
System.out.println("Checking values for row " + id);    
Iterator<Square> iter  = squareList.iterator();
while(iter.hasNext()) {
    System.out.println("Value (boolean checkValue() in Row): " + iter.next().value);
    if (iter.next().value == val) {
    System.out.println("returned false");
    return false;
    }
}
return true;

}

public void addSquare(Square s) {
squareList.add(s);
System.out.println("class Row, method addSquare: Square with value " + s.value + " added to row.");
}

}


About the semi-recursive method

The method is inside class Square, all the squares are assembled in a two-dimensional array. The method is suppose to call itself for every square on the sudoku board. All the squares have a Square nextSquare pointer pointing at the next square in squares[][]. getNext() returns nextSquare.

acceptValue(i) checks the Squares' Row to see if there's a Square-object there with the value of i, it returns true if there isn't (Row has a square[], with its squares, assigned to it from Board)

I really thought this would do the trick, but the recurrsion just keep on spinning.

The only thing I can think of is that maybe the squares in the Row-object don't get the value-update going on in the recursion, and that this might cause the recursive method to go on forever. But I still don't see why that would make any sense, it should just give me wrong values according to the sudoku rules.

Please advise if I should include any more code.

Any suggestions is much appreciated. Thanks.


Well for one thing, if all of your other code works as expected and acceptValue(i) will really choose correctly everytime, then you would want a return after your getNext().setNumber();

Something like

for(i=1;i<10;i++){
    if(acceptValue(i)){
        value = i;
        getNext().setNumber();
        return;
    }
}

Otherwise if your code chose 2 as the value when the setNumber() returns it will try 3, 4, 5... and so on.

0

精彩评论

暂无评论...
验证码 换一张
取 消