Lern-X - 25 days ago 4x
Java Question

# Recursive N-Queens : missing solutions

I wrote a Java little algorithm of the N-Queens puzzle (with a c*c chessboard). You'll find the code of my recursive method bellow.

It doesn't find all the solutions.

# What does my function

The idea is to make, in the main method, a first call to my function giving it the maximum number of queens until a solution is found, the chessboard without any queen and these new-queen's coordinates : x=0,y=0.

The function will go through the chessboard. For each square, it tests if the queen(0;0) can be placed (ie. : no threat). The queen(0;0) can be placed ? Well, we do it (modifying the chessboard) and we call the function (recursive call). This recursive call is done with : "maximum number of queens - 1", the modified chessboard, and the "new-queen's y + 1" (a bit more complicated).

&&Q&

Q&&&

&&&Q

&Q&&

# Code of my function

``````private static void setQueen(int nb_queens, ArrayList<ArrayList<Boolean>> chessboard, int x, int y, ArrayList<ArrayList<ArrayList<Boolean>>> solutions) {
if (nb_queens == 0) {
drawChessboard(chessboard); // Il n'y a plus de reine à placer => on dessine cette solution
}

for(int i = x; i < chessboard.size(); i++) {
for (int z = y; z < chessboard.get(i).size(); z++) {
chessboard.get(z).set(i, true); // On peut donc placer cette reine(x;y) et on le fait
setQueen(nb_queens-1, chessboard, i, (z+1 >= WIDTH) ? 0 : z+1, solutions);
chessboard.get(z).set(i, false);
}
}
}

}
``````

# Code of isAQueenAlreadyPresent (in row, col and diagonal)

``````private static Boolean isAQueenAlreadyPresent(int new_x, int new_y, ArrayList<ArrayList<Boolean>> chessboard) {
for(int i = 0; i < chessboard.size(); i++) {
for(int z = 0; z < chessboard.get(i).size(); z++) {
if(chessboard.get(i).get(z) && (    new_x == z || new_y == i // Horizontal and vertical checks
||  Math.abs(new_x-z) == Math.abs(new_y-i) ) ) { // Diagonal check
return true;
}
}
}
return false;
}
``````

Oh right, that's because how you call recursively, your doing `setQueen(nb_queens-1, chessboard, i, z+1, solutions);`. The `z+1` part is the problem, it will always found solution at the right of the first queen you placed on the global board.

Edit: ah you found it before, nice.

So, the problem is that the for loop act as an `if(z>=y)` because it starts at `y`. It's alright when `i = x` (reading the first line), but not when `i > x`. So an easy fix is to put `y = ( i == x ) ? y : 0` just after the first `for` loop.

There are even cleaner solution, like using a single index to go throught the whole chessboard.

I also suggest you rename your parameter as startX and startY (instead of x and y, the you can use x and y in the loop to be more clear).

Edit2: because of the rules of the games, there will never be a queen on the same line so ou can make a recursive call like `setQueen(nb_queens-1, chessboard, i+1, 0, solutions);` (`i+1` because you start on the next line directly). Because of this, you can even remove the `int y` parameter from the `setQueen` method and always start the `z loop` at 0.

Source (Stackoverflow)