我正在用Java制作数独游戏,我需要一些帮助。
我有两个用于生成数独谜题的课程: SudokuSolver , SudokuGenerator 。
SudokuSolver 为空表创建一个完整的有效数独谜题, SudokuGenerator 从表中删除一个随机值,然后检查(使用 SudokuSolver )如果数独谜题是唯一。
我发现数独谜题不是唯一的,所以我认为我检查数独谜题的算法是不好的。
例如:我有这个数独谜题
497816532
132000000
000000000
910600080
086009000
000084963
021063059
743050020
600278304
这个解决方案:
497816532
132**745**698
568392471
914**637**285
386529147
275184963
821463759
743951826
659278314
我去了https://www.sudoku-solutions.com/,我添加了我的数独模式,他们给了我另一个解决方案:
497816532
132**547**698
568392471
914**635**287
386729145
275184963
821463759
743951826
659278314
有趣的想法是他们说这个谜题是有效的并且有一个独特的解决方案。
有些意见?谢谢
SudokuSolver
public class SudokuSolver {
public static final int GRID_SIZE = 9;
public static final int SUBGRID_SIZE = 3;
private static int validRow = 0;
private static int validCol = 0;
private int[] nums = {1, 2, 3, 4, 5, 6, 7, 8, 9};
public boolean solveSudoku(int[][] values, int forbiddenNum) {
if(!findUnassignedLocation(values)) return true;
//suffle the nums array - for having a different valid sudoku
shuffleNums();
for (int i = 0; i < GRID_SIZE; i++) {
int num = nums[i];
if(num == forbiddenNum) continue; //
if(isSafe(values,validRow, validCol, num)) {
values[validRow][validCol] = num;
if(solveSudoku(values, forbiddenNum)) return true;
if(validCol == 0) {
validRow--;
validCol = 8;
}else{
validCol--;
}
values[validRow][validCol] = 0;
}
}
return false;
}
public boolean createValidSudoku(int[][] values) {
if(!findUnassignedLocation(values)) return true;
shuffleNums();
for (int i = 0; i < GRID_SIZE; i++) {
int num = nums[i];
if(isSafe(values,validRow, validCol, num)) {
values[validRow][validCol] = num;
if(createValidSudoku(values)) return true;
if(validCol == 0) {
validRow--;
validCol = 8;
}else{
validCol--;
}
values[validRow][validCol] = 0;
}
}
return false;
}
private void shuffleNums() {
Random random = new Random();
for(int i = nums.length - 1; i > 0; i--) {
int index = random.nextInt(i + 1);
int a = nums[index];
nums[index] = nums[i];
nums[i] = a;
}
}
private boolean findUnassignedLocation(int[][] values) {
for(int row = 0; row < GRID_SIZE; row++) {
for(int col = 0; col < GRID_SIZE; col++) {
if (values[row][col] == 0) {
validRow = row;
validCol = col;
return true;
}
}
}
return false;
}
private boolean usedInRow(int[][] values, int row, int num) {
for (int col = 0; col < GRID_SIZE; col++) {
if(values[row][col] == num) return true;
}
return false;
}
private boolean usedInCol(int[][] values, int col, int num) {
for (int row = 0; row < GRID_SIZE; row++) {
if(values[row][col] == num) return true;
}
return false;
}
private boolean usedInBox(int[][] values, int boxStartRow, int boxStartCol, int num) {
for(int row = 0; row < SUBGRID_SIZE; row++) {
for (int col = 0; col < SUBGRID_SIZE; col++) {
if (values[row + boxStartRow][col + boxStartCol] == num) return true;
}
}
return false;
}
private boolean isSafe(int[][] values,int row, int col, int num) {
return !usedInRow(values, row, num) &&
!usedInCol(values, col, num) &&
!usedInBox(values, row - row % 3, col - col % 3, num);
}
public void printGrid(int[][] values) {
for (int row = 0; row < GRID_SIZE; row++) {
for (int col = 0; col < GRID_SIZE; col++) {
System.out.print(values[row][col]);
}
System.out.println();
}
}
}
SudokuGenerator
public class SudokuGenerator {
private int[][] generatorValues = new int[9][9];
public void generateSudoku() {
SudokuSolver sudokuSolver = new SudokuSolver();
//generate a random valid sudoku for an empty table
sudokuSolver.createValidSudoku(generatorValues);
int count = 0;
printNums(generatorValues);
while(count < 40){
Random random = new Random();
int row = 0;
int col = 0;
if(count < 15){
row = random.nextInt(3);
col = random.nextInt(9);
} else if (count >= 15 && count < 30) {
row = random.nextInt(3) + 3;
col = random.nextInt(9);
}else {
row = random.nextInt(3) + 6;
col = random.nextInt(9);
}
int num = generatorValues[row][col];
int tempValues[][] = Arrays.copyOf(generatorValues, generatorValues.length);
//System.out.println("Row:" + row + "Col: " + col + "Num: " + num);
//Set the cell to 0;
if(generatorValues[row][col] != 0){
generatorValues[row][col] = 0;
} else{
continue;
}
//If found a solution, set cell back to original num
if(sudokuSolver.solveSudoku(tempValues, num)) {
generatorValues[row][col] = num;
continue;
}
count++;
}
System.out.println("------------------");
printNums(generatorValues);
}
private void printNums(int[][] values) {
for (int row = 0; row < 9; row++) {
for(int col = 0; col < 9; col++) {
System.out.print(values[row][col]);
}
System.out.println();
}
}
public int[][] getGeneratorValues () {
return generatorValues;
}
}