Reputation: 11
So I have a sudoku algorithm for a generating a completed game board. The problem is that the algorithm in some instances runs out of possible values to place in the grid, so by default it places a 0.
Here's the code:
public void generateBoard() {
// Determine values for board
int r, d;
// For every slot in grid
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
// Create HashSet with values 1-9
for (int k = 1; k <= 9; k++) {
set.add(k);
}
checkRow(i);
checkCol(j);
checkBox(i, j);
// Create an iterator
Iterator<Integer> iterator = set.iterator();
// Add HashSet values to ArrayList via Iterator
while (iterator.hasNext()) {
d = iterator.next();
values.add(d);
}
try {
// Randomly choose from list of viable values to be put into slot
r = new Random().nextInt(values.size());
slots[i][j] = (Integer) values.get(r);
} catch (Exception e) {
e.printStackTrace();
//resetBoard();
//continue;
}
// Clear HashSet and ArrayList after slot is assigned value
values.clear();
set.clear();
}
}
}
public void checkRow(int i) {
for (int c = 1; c <= 9; c++) {
for (int a = 0; a < 9; a++) {
// If c value is already in row remove from HashSet
if (c == slots[i][a]) {
set.remove(c);
}
}
}
}
public void checkCol(int j) {
for (int c = 1; c <= 9; c++) {
for (int a = 0; a < 9; a++) {
// If c value is already in column remove from HashSet
if (c == slots[a][j]) {
set.remove(c);
}
}
}
}
public void checkBox(int i, int j) {
int xSet = (i - (i % 3));
int ySet = (j - (j % 3));
for (int c = 1; c <= 9; c++) {
for (int x = xSet; x < xSet + 3; x++) {
for (int y = ySet; y < ySet + 3; y++) {
// If c value is already in box remove from HashSet
if (c == slots[x][y]) {
set.remove(c);
}
}
}
}
}
And this is what the generated board looks like: http://imgur.com/2cWh61j
Upvotes: 1
Views: 116
Reputation: 8161
The reason why your algorithm fails is because it's inherently wrong. Generating a Sudoku puzzle is more complicated than that.
A shortcut sometimes used to create a puzzle is to hardcode a few correct puzzles, picking one at random, shuffling the digits (swap all Xs with Ys and vice versa, and so on) shuffling the rows/columns (without moving any number outside its old box) and shuffling the 3x9 and 9x3 areas along the box borders. Doing so will create a puzzle that's TECHNICALLY the same as the original from a mathematical standpoint but should "feel" unique enough to a human.
Also keep in mind that even when you have a complete board, figuring out which tiles you can safely remove without creating an ambiguous puzzle is a bit tricky as well. The naive "remove x tiles at random" solution often fails.
Another question (with some useful answers) about how to create Sudokus can be found here: How to generate Sudoku boards with unique solutions
Upvotes: 2