From f1ef933963cb29fe76b549085916a471d9bb9175 Mon Sep 17 00:00:00 2001 From: Christopher Beckmann Date: Wed, 18 Nov 2015 13:15:29 +0100 Subject: [PATCH] Solved a Bug in the Solver. When solving Levels that have multiple solutions it would set wrong values. (Off by 1 error) --- app/build.gradle | 4 +++ .../sudoku/controller/GameController.java | 1 + .../tu_darmstadt/sudoku/game/GameBoard.java | 26 ++++---------- .../sudoku/game/solver/Solver.java | 8 ++--- .../sudoku/game/solver/SolverTest.java | 34 +++++++++++++++++-- 5 files changed, 48 insertions(+), 25 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index f77d0ee..4265675 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -4,6 +4,10 @@ android { compileSdkVersion 23 buildToolsVersion "23.0.2" + testOptions { + unitTests.returnDefaultValues = true + } + defaultConfig { applicationId "tu_darmstadt.sudoku" minSdkVersion 14 diff --git a/app/src/main/java/tu_darmstadt/sudoku/controller/GameController.java b/app/src/main/java/tu_darmstadt/sudoku/controller/GameController.java index 4d788eb..b1318e8 100644 --- a/app/src/main/java/tu_darmstadt/sudoku/controller/GameController.java +++ b/app/src/main/java/tu_darmstadt/sudoku/controller/GameController.java @@ -141,6 +141,7 @@ public class GameController { } public LinkedList solve() { + // TODO call solve at the beginning.. when loading a level. if(solvedBoards.size() == 0) { switch (gameType) { case Default_9x9: diff --git a/app/src/main/java/tu_darmstadt/sudoku/game/GameBoard.java b/app/src/main/java/tu_darmstadt/sudoku/game/GameBoard.java index aed0726..7b4c099 100644 --- a/app/src/main/java/tu_darmstadt/sudoku/game/GameBoard.java +++ b/app/src/main/java/tu_darmstadt/sudoku/game/GameBoard.java @@ -71,29 +71,17 @@ public class GameBoard implements Cloneable { public LinkedList getRow(final int row) { LinkedList result = new LinkedList(); for(int i = 0; i < size; i++) { - + result.add(field[row][i]); } - return actionOnCells(new ICellAction>() { - @Override - public LinkedList action(GameCell gc, LinkedList existing) { - if(gc.getRow() == row) { - existing.add(gc); - } - return existing; - } - }, new LinkedList()); + return result; } public LinkedList getColumn(final int col) { - return actionOnCells(new ICellAction>() { - @Override - public LinkedList action(GameCell gc, LinkedList existing) { - if(gc.getCol() == col) { - existing.add(gc); - } - return existing; - } - }, new LinkedList()); + LinkedList result = new LinkedList(); + for(int i = 0; i < size; i++) { + result.add(field[i][col]); + } + return result; } public LinkedList getSection(final int sec) { diff --git a/app/src/main/java/tu_darmstadt/sudoku/game/solver/Solver.java b/app/src/main/java/tu_darmstadt/sudoku/game/solver/Solver.java index 75aa43c..c6a1deb 100644 --- a/app/src/main/java/tu_darmstadt/sudoku/game/solver/Solver.java +++ b/app/src/main/java/tu_darmstadt/sudoku/game/solver/Solver.java @@ -131,7 +131,7 @@ public class Solver implements ISolver { GameCell copyGC = gameBoardCopy.getCell(p.x, p.y); - copyGC.setValue(i); + copyGC.setValue(i+1); result = solve(gameBoardCopy); @@ -295,19 +295,19 @@ public class Solver implements ISolver { for(int i = 0; i < gameBoard.getSize(); i++) { count = countUnsolved(gameBoard.getRow(i),candidate); - if(count < minimumCount) { + if(count != 0 && count < minimumCount) { minimumCount = count; bestCandidate.set(candidate.x, candidate.y); } count = countUnsolved(gameBoard.getColumn(i),candidate); - if(count < minimumCount) { + if(count != 0 && count < minimumCount) { minimumCount = count; bestCandidate.set(candidate.x, candidate.y); } count = countUnsolved(gameBoard.getSection(i),candidate); - if(count < minimumCount) { + if(count != 0 && count < minimumCount) { minimumCount = count; bestCandidate.set(candidate.x, candidate.y); } diff --git a/app/src/test/java/tu_darmstadt/sudoku/game/solver/SolverTest.java b/app/src/test/java/tu_darmstadt/sudoku/game/solver/SolverTest.java index 1808645..3b5487b 100644 --- a/app/src/test/java/tu_darmstadt/sudoku/game/solver/SolverTest.java +++ b/app/src/test/java/tu_darmstadt/sudoku/game/solver/SolverTest.java @@ -42,7 +42,7 @@ public class SolverTest { } @Test - public void solveTest1() { + public void solveSingleSolution1() { LinkedList result = controller.solve(); for(GameBoard gb : result) { @@ -61,7 +61,7 @@ public class SolverTest { } @Test - public void solveTest2() { + public void solveSingleSolution2() { controller.loadLevel(new GameInfoContainer(0, GameType.Default_9x9, new int[]{0,0,0,0,4,1,0,0,0,0,6,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,3,2,0,6,0,0,0,0,0,0,0,0,0,5,0,0,4,1,7,0,0,0,0,0,0,0,0,0,0,0,2,0,0,3,0,0,0,4,8,0,0,0,0,0,0,5,0,1,0,0,0,0,0,0} , null, null)); @@ -82,4 +82,34 @@ public class SolverTest { gb.toString()); } } + + @Test + public void solveMultipleSolutions1() { + controller.loadLevel(new GameInfoContainer(0, GameType.Default_6x6, + new int[]{1,0,0,0,0,6, + 4,0,6,1,0,0, + 0,0,2,3,0,5, + 0,4,0,0,1,0, + 0,6,0,2,0,0, + 0,3,0,5,0,1}, null,null)); + + LinkedList result = controller.solve(); + + assertEquals(2, result.size()); + + for(GameBoard gb : result) { + assertEquals("[GameBoard: \n" + + "\t[8 (0|0)] [7 (0|1)] [2 (0|2)] \t[9 (0|3)] [4 (0|4)] [1 (0|5)] \t[5 (0|6)] [6 (0|7)] [3 (0|8)] ]"+ + "\t[1 (1|0)] [6 (1|1)] [9 (1|2)] \t[5 (1|3)] [7 (1|4)] [3 (1|5)] \t[2 (1|6)] [8 (1|7)] [4 (1|8)] ]"+ + "\t[4 (2|0)] [5 (2|1)] [3 (2|2)] \t[8 (2|3)] [2 (2|4)] [6 (2|5)] \t[1 (2|6)] [9 (2|7)] [7 (2|8)] ]" + + "\t[3 (3|0)] [2 (3|1)] [4 (3|2)] \t[6 (3|3)] [1 (3|4)] [7 (3|5)] \t[8 (3|6)] [5 (3|7)] [9 (3|8)] ]" + + "\t[9 (4|0)] [8 (4|1)] [6 (4|2)] \t[3 (4|3)] [5 (4|4)] [2 (4|5)] \t[7 (4|6)] [4 (4|7)] [1 (4|8)] ]" + + "\t[7 (5|0)] [1 (5|1)] [5 (5|2)] \t[4 (5|3)] [9 (5|4)] [8 (5|5)] \t[6 (5|6)] [3 (5|7)] [2 (5|8)] ]" + + "\t[6 (6|0)] [9 (6|1)] [7 (6|2)] \t[2 (6|3)] [8 (6|4)] [4 (6|5)] \t[3 (6|6)] [1 (6|7)] [5 (6|8)] ]" + + "\t[2 (7|0)] [4 (7|1)] [8 (7|2)] \t[1 (7|3)] [3 (7|4)] [5 (7|5)] \t[9 (7|6)] [7 (7|7)] [6 (7|8)] ]" + + "\t[5 (8|0)] [3 (8|1)] [1 (8|2)] \t[7 (8|3)] [6 (8|4)] [9 (8|5)] \t[4 (8|6)] [2 (8|7)] [8 (8|8)] ]", + gb.toString()); + } + } + }