Skip to content

Commit

Permalink
Release 2.2.7
Browse files Browse the repository at this point in the history
A few minor updates for the 2.2.7 pre-release.
  • Loading branch information
PseudoFish committed Nov 24, 2019
1 parent fa941d2 commit b7a9d18
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 31 deletions.
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,33 @@ heap size at startup.
Change log
==========

Version 2.2.7 (2019-11-23)
--------------------------

Features:

- The active cell selector has been made larger then the rest of the cell selection to distinguish it.

- Cell selection is more responsive. Immediate selection on down event.

- German translation support has been added.

Bug Fixes:

- Active cell selector position now updates correctly on mouse drag.

- "Solve up to" had a bug where it would go in an endless loop on a puzle where the engine gives-up.

- Cell selection bug when removing existing selection from previous selection.

- Solve Puzzle now throws an appropriate message when the puzzle has multiple solutions.

- Right click no longer clears the selection.

- An empty config file is deleted and re-generated.

- Internal code redesigning and refactoring.

Version 2.2.6 (2019-11-22)
--------------------------

Expand Down
11 changes: 0 additions & 11 deletions ToDo.txt
Original file line number Diff line number Diff line change
@@ -1,16 +1,5 @@
Crash:

Load this puzzle into Hodoku and press "Solve up to"
600270490009080030730006002047308065300400079900007000003000907072560300004702050

20191117:

I dislike having candidate highlight when pressing LCtrl to select cells. There should be an option to disable it.

Bugs:

Right click removed selection
Right click should not perform a selection
Single Click Mode right click commits without showing menu

20191116:
Expand Down
113 changes: 94 additions & 19 deletions src/sudoku/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -76,20 +76,22 @@ public String getSrcDir() {
}

void searchForType(List<StepType> typeList, DifficultyLevel level, String outFile) {
// Logger.getLogger(getClass().getName()).log(Level.INFO, "Starting search for "
// + type.getStepName());

System.out.println("Starting search for:");
if (typeList.size() > 0) {
for (StepType tmpType : typeList) {
System.out.println(" " + tmpType);
}
}

if (level != null) {
System.out.println(" " + level.getName());
}

SearchForTypeThread thread = new SearchForTypeThread(typeList, level, outFile);
thread.start();
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

try {
// 20120112: Pressing <ctrl><c> makes readLine() return null
// which leads to a NullPointerException
Expand All @@ -100,31 +102,74 @@ void searchForType(List<StepType> typeList, DifficultyLevel level, String outFil
break;
}
}

} catch (IOException ex) {
System.out.println("Error reading from console");
}

thread.interrupt();

try {
thread.join();
} catch (InterruptedException ex) {
System.out.println("Interrupted waiting for search thread");
}

System.out.println("Gesamt: " + thread.getAnz() + " Sudoku erzeugt (" + thread.getAnzFound() + " Treffer)");
}

public void batchSolve(String fileName, String puzzleString, boolean printSolution, boolean printSolutionPath,
boolean printStatistic, ClipboardMode cMode, Set<SolutionType> types, String outFile,
public void batchSolve(
String fileName,
String puzzleString,
boolean printSolution,
boolean printSolutionPath,
boolean printStatistic,
ClipboardMode cMode,
Set<SolutionType> types,
String outFile,
boolean findAllSteps) {
batchSolve(fileName, puzzleString, printSolution, printSolutionPath, printStatistic, cMode, types, outFile,
findAllSteps, false, null);

batchSolve(
fileName,
puzzleString,
printSolution,
printSolutionPath,
printStatistic,
cMode,
types,
outFile,
findAllSteps,
false,
null
);
}

public void batchSolve(String fileName, String puzzleString, boolean printSolution, boolean printSolutionPath,
boolean printStatistic, ClipboardMode cMode, Set<SolutionType> types, String outFile, boolean findAllSteps,
boolean bruteForceTest, List<SolutionType> testTypes) {

BatchSolveThread thread = new BatchSolveThread(fileName, puzzleString, printSolution, printSolutionPath,
printStatistic, cMode, types, outFile, findAllSteps, bruteForceTest, testTypes);
public void batchSolve(
String fileName,
String puzzleString,
boolean printSolution,
boolean printSolutionPath,
boolean printStatistic,
ClipboardMode cMode,
Set<SolutionType> types,
String outFile,
boolean findAllSteps,
boolean bruteForceTest,
List<SolutionType> testTypes) {

BatchSolveThread thread = new BatchSolveThread(
fileName,
puzzleString,
printSolution,
printSolutionPath,
printStatistic,
cMode,
types,
outFile,
findAllSteps,
bruteForceTest,
testTypes
);

thread.start();
ShutDownThread st = new ShutDownThread(thread);
Expand All @@ -138,8 +183,7 @@ public void batchSolve(String fileName, String puzzleString, boolean printSoluti

try {
Runtime.getRuntime().removeShutdownHook(st);
} catch (Exception ex) {
}
} catch (Exception ex) {}

int min = (int) (thread.getTicks() / 60000);
int sec = (int) (thread.getTicks() % 60000);
Expand All @@ -149,9 +193,13 @@ public void batchSolve(String fileName, String puzzleString, boolean printSoluti
int hours = min / 60;
min -= (hours * 60);

System.out.printf("%d puzzles in %dms (%d:%02d:%02d.%03d)\r\n", thread.getCount(), thread.getTicks(), hours,
min, sec, ms);
// System.out.println(thread.getCount() + " puzzles in " + thread.getTicks() + "ms (" + hours + ":" + min + ":" + sec + "." + ms + ")");
System.out.printf(
"%d puzzles in %dms (%d:%02d:%02d.%03d)\r\n",
thread.getCount(),
thread.getTicks(),
hours, min, sec, ms
);

System.out.printf("%.03f ms per puzzle\r\n", (thread.getTicks() / (double) thread.getCount()));
System.out.println(thread.getBruteForceAnz() + " puzzles require guessing!");
System.out.println(thread.getTemplateAnz() + " puzzles require templates!");
Expand All @@ -164,69 +212,86 @@ public void batchSolve(String fileName, String puzzleString, boolean printSoluti
}

if (printStatistic) {

System.out.println();

try {
thread.printStatistic(null, false);
} catch (IOException ex) {
ex.printStackTrace();
}

SudokuSolverFactory.getDefaultSolverInstance().getStepFinder().printStatistics();
}
}

void sortPuzzleFile(String fileName, List<StepType> typeList, String outFileName) {

try {

if (typeList.size() > 0) {
System.out.println("Filter:");
for (StepType tmpType : typeList) {
System.out.println(" " + tmpType);
}
}

BufferedReader in = new BufferedReader(new FileReader(fileName));
BufferedWriter out = null;

if (outFileName == null) {
outFileName = fileName + ".out.txt";
}

if (!outFileName.equals("stdout")) {
out = new BufferedWriter(new FileWriter(outFileName));
}

List<String> puzzleList = new ArrayList<String>();
String line = null;

int gesAnz = 0;
while ((line = in.readLine()) != null) {

gesAnz++;
boolean includePuzzle = true;
if (line.contains("#") && typeList.size() > 0) {

includePuzzle = false;
// determine puzzle type
String inputStr = line.substring(line.indexOf('#') + 1).trim();
int puzzleType = 3;
String[] types = inputStr.split(" ");

for (int i = 0; i < types.length; i++) {
if (types[i].equals("x")) {
puzzleType = 0;
break;
}
}
// if (inputStr.contains("x")) {
// puzzleType = 0;

if (puzzleType == 3) {

if (inputStr.startsWith("ssts")) {
puzzleType = 2;
}

if (inputStr.endsWith("ssts")) {
puzzleType = 1;
}
}

String typeStr = null;
int compAnz = 0;
String[] parts = inputStr.split(" ");

if (parts.length > 1) {
typeStr = parts[1];
} else {
// invalid type in input -> nothing to apply
continue;
}

int index1 = typeStr.indexOf('(');
int index2 = typeStr.indexOf(')');
String orgTypeStr = typeStr;
Expand All @@ -239,6 +304,7 @@ void sortPuzzleFile(String fileName, List<StepType> typeList, String outFileName
}
}
}

// apply filter
for (StepType actType : typeList) {
if (typeStr.equals(actType.type.getArgName()) && puzzleType >= actType.puzzleType) {
Expand All @@ -264,23 +330,28 @@ void sortPuzzleFile(String fileName, List<StepType> typeList, String outFileName
break;
}
}

if (includePuzzle) {
break;
}
}
}

if (includePuzzle) {
puzzleList.add(line);
}
}

in.close();
int anz = puzzleList.size();
Collections.sort(puzzleList, new Comparator<String>() {

@Override
public int compare(String s1, String s2) {

int index1 = s1.indexOf('#');
int index2 = s2.indexOf('#');

if (index1 == -1 && index2 == -1) {
return s1.compareTo(s2);
} else if (index1 == -1 && index2 != -1) {
Expand All @@ -292,6 +363,7 @@ public int compare(String s1, String s2) {
}
}
});

for (String key : puzzleList) {
if (out != null) {
out.write(key);
Expand All @@ -300,10 +372,13 @@ public int compare(String s1, String s2) {
System.out.println(key);
}
}

if (out != null) {
out.close();
}

System.out.println(anz + " puzzles sorted (" + gesAnz + ")!");

} catch (Exception ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, "Error sorting puzzle file", ex);
}
Expand Down
2 changes: 1 addition & 1 deletion src/sudoku/MainFrame.java
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@
public class MainFrame extends javax.swing.JFrame implements FlavorListener {

private static final long serialVersionUID = 1L;
public static final String VERSION = "HoDoKu - v2.2.6";
public static final String VERSION = "HoDoKu - v2.2.7";

// public static final String BUILD = "Build 16";
public static final String BUILD;
Expand Down

0 comments on commit b7a9d18

Please sign in to comment.