-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSudoku.java
157 lines (135 loc) · 5.74 KB
/
Sudoku.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
package sudoku;
import java.util.Random;
public class Sudoku {
private static final int Grid_Size = 9;
private static final Random random = new Random();
public static void main(String[] args) {
int[][] board = new int[Grid_Size][Grid_Size];
if (fillBoard(board)) {
System.out.println("Initial solution:");
printBoard(board);
makePuzzle(board);
System.out.println("\nPuzzle to solve:");
printBoard(board);
if(solveBoard(board)){
System.out.println("Solved generated map");
printBoard(board);
}
} else {
System.out.println("Failed to generate a solution.");
}
}
private static boolean fillBoard(int[][] board) {
for (int row = 0; row < Grid_Size; row++) {
for (int column = 0; column < Grid_Size; column++) {
if (board[row][column] == 0) {
for (int number = 1; number <= Grid_Size; number++) {
int numToTry = (number + random.nextInt(Grid_Size)) % Grid_Size+ 1; // Add randomness
if (isValidPlacement(board, numToTry, row, column)) {
board[row][column] = numToTry;
if (fillBoard(board)) {
return true;
} else {
board[row][column] = 0;
}
}
}
return false; // backtrack
}
}
}
return true; // puzzle filled
}
private static void printBoard(int[][] board) {
for ( int row =0 ; row < Grid_Size ; row ++){
if ( row % 3 ==0 & row !=0 ){
System.out.println("---------------");
}
for (int column =0 ; column <Grid_Size ; column ++){
if (column % 3 ==0 & column!=0){
System.out.print(" | ");
}
System.out.print(board[row][column]);
}
System.out.println();
}
}
private static boolean isNumberInRow(int [][]board,int number , int row){
for (int i=0 ; i <Grid_Size; i++){
if (board[row][i] == number){
return true;
}
}
return false;
}
private static boolean isNumberInColumn(int[][] board,int number , int column){
for (int i=0; i < Grid_Size ;i++){
if (board[i][column] == number){
return true;
}
}
return false;
}
// so we need to get the row we could use the mod and get reminder
// like row (that's passed ) -> % 3
// more real case could be row - row % 3 (e.g) row 1
// 1- 1 %3
// =0
// we got at row 0
// that's what we need coordinate of top left corner inside the box
private static boolean isNumberInBox (int [][]board , int number , int row , int column){
int localBoxRow = row - row % 3;
int localBoxColumn = column - column % 3;
for (int i= localBoxRow;i<localBoxRow+3;i++){
for (int j =localBoxColumn ; j<localBoxColumn +3 ;j++){
if(board[i][j]==number){
return true;
}
}
}
return false;
}
private static boolean isValidPlacement(int [][]board,int number , int row , int column){
return !isNumberInRow(board,number,row)&&
!isNumberInColumn(board,number,column)&&
!isNumberInBox(board,number,row,column) ;
}
private static void makePuzzle(int[][] board) {
int steps = Grid_Size * 3; // Adjust this for difficulty
while (steps > 0) {
int row = random.nextInt(Grid_Size);
int col = random.nextInt(Grid_Size);
if (board[row][col] != 0) {
board[row][col] = 0;
steps--;
}
}
}
private static boolean solveBoard(int[][]board){
for (int row =0 ; row <Grid_Size ;row++){ // all rows
for (int column =0 ; column <Grid_Size ;column++){ // all columns in row
if(board[row][column] ==0){ // taking 0 as a blank to tell computer
for (int numberToTry =1 ; numberToTry<=Grid_Size ; numberToTry ++){ // check number 1 to 9
// already have isValidPlacement method
if(isValidPlacement(board,numberToTry,row,column)){ // if it's a valid placement we place
// the number there
board[row][column]=numberToTry;
// now recursion of this algorithm
// method would start again and check for next blank spots means 0 to place to valid number there
if(solveBoard(board)){
return true;
}
else {
board[row][column]=0; // set back to zero if it could not solve
// even if a number is valid, but we could get a case board could not be solved
// if recursion does not work we set it back to 0;
}
}
}
return false; // return if it could not place any valid number after checking all numbers
}
}
}
return true; // solved finally after checking and doing all steps!
}
}