Skip to content

Commit 27bd16a

Browse files
committed
Added Heuristic
Ready for release Code documented as well
1 parent 2ddfb01 commit 27bd16a

File tree

4 files changed

+121
-18
lines changed

4 files changed

+121
-18
lines changed

src/com/company/Main.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,9 @@ public class Main {
88
static protected int[][] sudoku_array = new int[9][9]; //Stores the sudoku
99
static protected ArrayList<Point> points = new ArrayList<>(); //stores the EMPTY points
1010
static protected guiController gui = new guiController();//Initializes program, calls sudokuInitializer as well
11-
public static void main(String[] args) {
1211

13-
//gui.setVisible(true);//sets the GUI as visible
14-
System.out.println("points : "+ points);
12+
13+
public static void main(String[] args) {
1514

1615
Thread t1 = new Thread(gui);
1716
t1.start();

src/com/company/guiController.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,11 @@ private void guiInit() {
113113
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
114114
setLocationRelativeTo(null);
115115
}
116+
/*
117+
\Function below clears the GUI
118+
sets the array to 0
119+
and textfields to null
120+
*/
116121
private void clearGUI(){
117122
for (int i = 0; i < 9; i++)
118123
for (int j = 0; j < 9; j++) {

src/com/company/solver.java

Lines changed: 113 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,115 @@
11
package com.company;
22

3-
class solver implements Runnable{
4-
//Choose a box with minimum empty values - MVP(minimum value remaining) heuristic
5-
//Reduce the domain of each box by prechecking the already fixed value in the box
3+
import java.awt.*;
4+
import java.util.*;
5+
import java.util.List;
66

7-
public void run(){
8-
if(getResult())
7+
class solver implements Runnable{ //Implemented as a Thread to avoid freezing and maximum efficiency for GUI with heavy operation
8+
//Chooses a box with MINIMUM VALUES REMAINING (It acts as a heuristic which optimizes the search for the solution
9+
ArrayList<Point> sortedPoints = new ArrayList<>(); //It stores the sorted points according
10+
// to box with least number of values unfilled
11+
public void run(){ //acts as a constructor for the class, works with Thread.start function
12+
setSortedPoints(); //sets sorted point
13+
if(getResult()) //calls the solving function
914
Main.gui.sud.printArray();
1015

1116
}
17+
/*
18+
This function creates a map for all the 9 boxes
19+
Sorts them, and creates a new arraylist of points which are sorted according to the boxes
20+
*/
21+
private void setSortedPoints(){
22+
HashMap<String,Integer> box_size= new HashMap<>(); //creates a map with default frequency one
23+
box_size.put("00",0);
24+
box_size.put("03",0);
25+
box_size.put("06",0);
26+
27+
box_size.put("30",0);
28+
box_size.put("33",0);
29+
box_size.put("36",0);
30+
31+
box_size.put("60",0);
32+
box_size.put("63",0);
33+
box_size.put("66",0);
34+
/*
35+
Below loop, calculates the size of each of unfilled elements in each box
36+
*/
37+
for (int i=0; i<Main.points.size(); i++) {
38+
String s = Integer.toString(boxRowCol((int)Main.points.get(i).getX()));
39+
s+=Integer.toString(+boxRowCol((int)Main.points.get(i).getY()));
40+
//System.out.println(s);
41+
42+
switch (s) {
43+
case "00":box_size.put("00",box_size.get("00")+1); break;
44+
case "03":box_size.put("03",box_size.get("03")+1);break;
45+
case "06":box_size.put("06",box_size.get("06")+1);break;
46+
47+
case "30":box_size.put("30",box_size.get("30")+1);break;
48+
case "33":box_size.put("33",box_size.get("33")+1);break;
49+
case "36":box_size.put("36",box_size.get("36")+1);break;
50+
51+
case "60":box_size.put("60",box_size.get("60")+1);break;
52+
case "63":box_size.put("63",box_size.get("63")+1);break;
53+
case "66":box_size.put("66",box_size.get("66")+1);break;
54+
}
55+
}
56+
57+
box_size = sortByValue(box_size); //This function sorts the hash map by value
58+
59+
/*
60+
Below loop sets the sortedpoints arraylist
61+
*/
62+
for (String key:box_size.keySet())
63+
for (int i=0; i<Main.points.size(); i++) {
64+
String s = Integer.toString(boxRowCol((int) Main.points.get(i).getX()));
65+
s += Integer.toString(+boxRowCol((int) Main.points.get(i).getY()));
66+
if (s.equals(key)){
67+
sortedPoints.add(new Point((int)Main.points.get(i).getX(),(int)Main.points.get(i).getY()));
68+
}
69+
70+
}
71+
}
72+
/*
73+
This function is soleley used for sorting the MAP by using list and default collections fucntions
74+
*/
75+
private static HashMap<String, Integer> sortByValue(HashMap<String , Integer> map_sorting)
76+
{
77+
// Create a list from elements of HashMap
78+
List<Map.Entry<String, Integer> > list =
79+
new LinkedList<>(map_sorting.entrySet());
80+
81+
82+
list.sort(Comparator.comparing(Map.Entry::getValue));
83+
84+
85+
HashMap<String, Integer> temp = new LinkedHashMap<>();
86+
for (Map.Entry<String, Integer> aa : list) {
87+
temp.put(aa.getKey(), aa.getValue());
88+
}
89+
return temp;
90+
}
91+
/*
92+
This is the MAIN function which solves the sudoku by using sortedpoints arraylist and constraints
93+
*/
1294
private boolean getResult(){
1395
if (checkSolved()) {
1496
return true;
1597
}
16-
int row_num = -1;
17-
int col_num = -1;
18-
for (int i=0; i<9; i++)
19-
for (int j=0; j<9; j++){
20-
if (Main.sudoku_array[i][j] == 0){
21-
row_num=i;
22-
col_num=j;
23-
}
98+
int row_num = -1,col_num = -1;
99+
/*
100+
sets col, row to get started
101+
*/
102+
for (Point pointIndex : sortedPoints) {
103+
if (Main.sudoku_array[(int) pointIndex.getX()][(int) pointIndex.getY()] == 0) {
104+
row_num = (int) pointIndex.getX();
105+
col_num = (int) pointIndex.getY();
106+
break;
24107
}
108+
}
25109

110+
/*
111+
it check for constraint and refreshes GUI after every move
112+
*/
26113
for (int i=1; i<=9; i++){
27114
if (checkConstraint(i,row_num,col_num)){
28115

@@ -47,21 +134,30 @@ private boolean getResult(){
47134
return false;
48135

49136
}
137+
/*
138+
adds delay
139+
*/
50140
private void timer(){
51141
try {
52-
Thread.sleep(1);
142+
Thread.sleep(5); //CHANGE DELAY TIME HERE , SET minimum 5ms for noticable difference and faster result
53143
//Thread.sleep(10000);
54144
} catch (InterruptedException e) {
55145
e.printStackTrace();
56146
}
57147
}
148+
/*
149+
It checks weather the sudoku has been solved or not
150+
*/
58151
private boolean checkSolved(){
59152
for (int i = 0 ; i < 9 ; i++)
60153
for (int j = 0 ; j < 9 ; j++)
61154
if (Main.sudoku_array[i][j] == 0)
62155
return false;
63156
return true;
64157
}
158+
/*
159+
it checks constraint on rows, cols and boxes
160+
*/
65161
private boolean checkConstraint(int value, int row_num,int col_num){
66162
/*
67163
Below for loop checks for the given value in row and col specified
@@ -84,6 +180,9 @@ private boolean checkConstraint(int value, int row_num,int col_num){
84180
//if every constraint is satisfied
85181
return true;
86182
}
183+
/*
184+
Returns box number
185+
*/
87186
private int boxRowCol(int num){
88187
if (num==0||num==1||num==2)
89188
return 0;

src/com/company/sudokuInitializer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ class sudokuInitializer {
88

99
/*
1010
Function to check whether the input given via file or manually is valid or not
11-
Thorws exception for Invalid Input
11+
Throws exception for Invalid Input
1212
*/
1313
boolean checkValidInput(String input) throws Exception{
1414
int n = Integer.parseInt(input+"");

0 commit comments

Comments
 (0)