Permalink
Browse files

Added a stopwatch and few smaller new features, few minor changes and…

… bugfixes

Added: a stopwatch on the menu bar
Added: congratulations popup when the puzzle is solved
Added: menu item that fills all suggestions
Fixed: a suggestions label on menu bar was not filled for new Sudoku
Fixed: the borders of cells are now displayed correctly in Sudoku 16x16
Fixed: uneffective solving algorithm now return the status instead of boolean
Fixed: Incorrect refreshing and colouring of numbers when using solve and reset has been fixed
Change: filling a cell now does not clear this cell's suggestions
  • Loading branch information...
Jarcionek committed Mar 13, 2012
1 parent 28f043c commit d82b84b020a5530c8365765cc6bb46280baa059b
@@ -21,4 +21,8 @@ public Change(int x, int y, int number, int operation, boolean last) {
this.operation = operation;
this.last = last;
}
public static Change marker() {
return new Change(-1, -1, -1, -1, true);
}
}
@@ -4,6 +4,7 @@
import java.util.Iterator;
import java.util.Random;
import java.util.Stack;
import javax.swing.JOptionPane;
/**
* @author Jaroslaw Pawlak
@@ -12,6 +13,10 @@
private static Grid solved = null;
//FIXME improve solving algorithm and remove this:
private static long temporarySolving = -1;
public static final int TEMP_TIME_OUT = 5000;
public static final int VALID = 1;
public static final int INVALID = 2;
public static final int UNKNOWN = 3;
private final Cell[][] grid;
private final int size;
@@ -66,8 +71,17 @@ public static Grid generate(boolean autoRemovePoss, boolean autoFillBasic,
}
}
if (!isSolvable(g.copy())) {
int status = isSolvable(g.copy());
if (status == INVALID) {
continue;
} else if (status == UNKNOWN) {
String msg = "<html><font size=4 color=orange>";
msg += "Algorithm was not able<br>";
msg += "to validate this puzzle.<br>";
msg += "It may not have a solution.";
msg += "</font></html>";
JOptionPane.showMessageDialog(null, msg,
"Sudoku Helper", JOptionPane.WARNING_MESSAGE);
}
if (autoRemovePoss) {
@@ -105,9 +119,10 @@ public boolean undo() {
}
}
public boolean solve() {
if (isSolvable(this.copy())) {
history.add(new Change(-1, -1, -1, -1, true)); //just a marker
public int solve() {
int status = isSolvable(this.copy());
if (status == VALID) {
history.add(Change.marker());
for (int i = 0; i < size*size; i++) {
for (int j = 0; j < size*size; j++) {
if (grid[i][j].value() == 0) {
@@ -116,9 +131,8 @@ public boolean solve() {
}
}
}
return true;
}
return false;
return status;
}
public void reset() {
@@ -205,6 +219,28 @@ private boolean isAllowed(Cell cell, int number) {
return true;
}
public void fillSuggestions() {
history.add(Change.marker());
for (Cell cell : all()) {
for (int n = 1; n <= size*size; n++) {
if (!cell.poss().contains(n)) {
history.add(new Change(cell.row, cell.column, n,
Change.POSS_REM, false));
cell.poss().add(n);
}
}
}
for (Cell cell : all()) {
for (int n : cell.poss()) {
if (!isAllowed(cell, n)) {
history.add(new Change(cell.row, cell.column, n,
Change.POSS_ADD, false));
cell.poss().remove(n);
}
}
}
}
public void fill(int row, int column, int number) {
fill(row, column, number, true);
}
@@ -214,12 +250,12 @@ private void fill(int row, int column, int number, boolean user) {
return;
}
history.add(new Change(row, column, grid[row][column].value(), Change.NORMAL, user));
if (user && autoRemovePoss) {
for (int n : grid[row][column].poss()) {
history.add(new Change(row, column, n, Change.POSS_ADD, false));
grid[row][column].poss().remove(n);
}
}
// if (user && autoRemovePoss) {
// for (int n : grid[row][column].poss()) {
// history.add(new Change(row, column, n, Change.POSS_ADD, false));
// grid[row][column].poss().remove(n);
// }
// }
if (grid[row][column].value() != 0) {
clear(row, column, user);
}
@@ -243,12 +279,13 @@ private void fillAll() {
if (autoFillBasic) {
for (Cell cell : all()) {
if (cell.value() == 0) {
if (cell.poss().size() == 1) {
if (isAllowed(cell, cell.poss().get())) {
fill(cell.row, cell.column, cell.poss().get(), false);
return;
}
if (cell.value() != 0) {
continue;
}
if (cell.poss().size() == 1) {
if (isAllowed(cell, cell.poss().get())) {
fill(cell.row, cell.column, cell.poss().get(), false);
return;
}
}
}
@@ -382,7 +419,7 @@ public Grid copy() {
return r;
}
private boolean isAllFilled() {
public boolean isAllFilled() {
for (Cell cell : all()) {
if (cell.value() == 0) {
return false;
@@ -393,12 +430,11 @@ private boolean isAllFilled() {
public static boolean isSolvable(Grid gridCopy) {
if (temporarySolving < 0) {
public static int isSolvable(Grid gridCopy) {
if (temporarySolving == -1) {
temporarySolving = System.currentTimeMillis();
} else if (System.currentTimeMillis() - temporarySolving > 5000) {
temporarySolving = -2;
return false;
} else if (System.currentTimeMillis() - temporarySolving > TEMP_TIME_OUT) {
return UNKNOWN;
}
if (!gridCopy.initialPoss) {
gridCopy.initialPoss = true;
@@ -416,15 +452,15 @@ public static boolean isSolvable(Grid gridCopy) {
if (gridCopy.isAllFilled()) {
temporarySolving = -1;
solved = gridCopy;
return true;
return VALID;
}
Point p = new Point(-1, -1);
for (int i = 0; i < gridCopy.size*gridCopy.size; i++) {
for (int j = 0; j < gridCopy.size*gridCopy.size; j++) {
if (gridCopy.grid[i][j].value() == 0) {
if (gridCopy.grid[i][j].poss().size() == 0) {
return false;
return INVALID;
} else if (p.x == -1 || gridCopy.grid[i][j].poss().size()
< gridCopy.grid[p.x][p.y].poss().size()) {
p.x = i;
@@ -437,15 +473,14 @@ public static boolean isSolvable(Grid gridCopy) {
for (int n : gridCopy.grid[p.x][p.y].poss()) {
Grid anotherCopy = gridCopy.copy();
anotherCopy.grid[p.x][p.y].fill(n);
if (isSolvable(anotherCopy)) {
int status = isSolvable(anotherCopy);
if (status == VALID || status == UNKNOWN) {
temporarySolving = -1;
return true;
}
if (temporarySolving == -2) {
return false;
return status;
}
}
return false;
temporarySolving = -1;
return INVALID;
}
@@ -4,22 +4,20 @@
* @author Jaroslaw Pawlak
*/
public class Main {
public static final String VERSION = "1.1+";
public static final String DATE = "not released yet";
public static final String VERSION = "1.2";
public static final String DATE = "12/03/2012";
public static void main(String[] args) {
new MainFrame();
}
}
/** //TODO
* auto last game save/load
* save/load settings
* best scores
* fix the borders
*
* change:
* history + undo in Grid
* solve button + confirmation
* auto add poss has been removed
* opt: isSolvable - use history instead of copying
* new: auto last game save/load
* new: save/load settings
* new: best scores
* new: hint - fill new number
* fix: solver in generate method (timeout is for single sudoku only
*/
Oops, something went wrong.

0 comments on commit d82b84b

Please sign in to comment.