diff --git a/app/src/main/java/tu_darmstadt/sudoku/controller/DoUndo.java b/app/src/main/java/tu_darmstadt/sudoku/controller/DoUndo.java new file mode 100644 index 0000000..ee2df81 --- /dev/null +++ b/app/src/main/java/tu_darmstadt/sudoku/controller/DoUndo.java @@ -0,0 +1,77 @@ +package tu_darmstadt.sudoku.controller; + +import java.util.LinkedList; +import java.util.List; + +import tu_darmstadt.sudoku.game.GameBoard; + +/** + * Created by Chris on 24.11.2015. + */ +public class DoUndo { + + private int activeState; + private LinkedList states = new LinkedList<>(); + + public DoUndo(GameBoard initState) { + // we get the base state and set it as active state. + try { + + states.addLast(initState.clone()); + activeState = 0; + + } catch (CloneNotSupportedException e) { + e.printStackTrace(); + } + } + + public boolean isUnDoAvailable() { + return activeState > 0 && states.size() > 1; + } + + public boolean isRedoAvailable() { + return activeState < states.size()-1; + } + + public GameBoard UnDo() { + if(isUnDoAvailable()) { + return states.get(--activeState); + } else { + return null; + } + } + + public GameBoard ReDo() { + if(isRedoAvailable()) { + return states.get(++activeState); + } else { + return null; + } + } + + public void addState(GameBoard gameBoard) { + + LinkedList deleteList = new LinkedList<>(); + + for(int i = 0; i < states.size(); i++) { + if (i > activeState) { // 3 states // state 1 is active // means 0,[1],2 + // delete rest of the list // i > activeState // i > 1 // so i = 2 will be deleted // 0 can not be deleted + deleteList.add(states.get(i)); + } + } + for(GameBoard g : deleteList) { + states.removeLastOccurrence(g); + } + + // then append the current state + try { + + GameBoard board = gameBoard.clone(); + states.addLast(board); + activeState = states.size()-1; + + } catch (CloneNotSupportedException e) { + e.printStackTrace(); + } + } +} 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 a41797c..61fc847 100644 --- a/app/src/main/java/tu_darmstadt/sudoku/controller/GameController.java +++ b/app/src/main/java/tu_darmstadt/sudoku/controller/GameController.java @@ -8,7 +8,6 @@ import java.util.List; import java.util.Timer; import java.util.TimerTask; -import tu_darmstadt.sudoku.controller.solver.Solver; import tu_darmstadt.sudoku.game.CellConflict; import tu_darmstadt.sudoku.game.CellConflictList; import tu_darmstadt.sudoku.game.GameBoard; @@ -17,9 +16,9 @@ import tu_darmstadt.sudoku.controller.helper.GameInfoContainer; import tu_darmstadt.sudoku.game.GameDifficulty; import tu_darmstadt.sudoku.game.GameType; import tu_darmstadt.sudoku.game.ICellAction; -import tu_darmstadt.sudoku.game.listeners.IGameSolvedListener; -import tu_darmstadt.sudoku.game.listeners.IModelChangedListener; -import tu_darmstadt.sudoku.game.listeners.ITimerListener; +import tu_darmstadt.sudoku.game.listener.IGameSolvedListener; +import tu_darmstadt.sudoku.game.listener.IModelChangedListener; +import tu_darmstadt.sudoku.game.listener.ITimerListener; /** * Created by Chris on 06.11.2015. @@ -30,9 +29,7 @@ public class GameController implements IModelChangedListener { private int sectionHeight; private int sectionWidth; private GameBoard gameBoard; - private Solver solver; private int[] solution; - private LinkedList solvedBoards = new LinkedList<>(); private GameType gameType; private int selectedRow; private int selectedCol; @@ -40,6 +37,7 @@ public class GameController implements IModelChangedListener { private int gameID = 0; private GameDifficulty difficulty; private CellConflictList errorList = new CellConflictList(); + private DoUndo doUndo; private int selectedValue; private LinkedList solvedListeners = new LinkedList<>(); private boolean notifiedOnSolvedListeners = false; @@ -76,59 +74,13 @@ public class GameController implements IModelChangedListener { } public void loadNewLevel(GameType type, GameDifficulty difficulty) { - //Generator generator = new Generator(type, gameDifficulty); - //GameBoard randomBoard = generator.getGameBoard(); - SaveLoadLevelManager saveLoadLevelManager = SaveLoadLevelManager.getInstance(); + int[] level = saveLoadLevelManager.loadLevel(type, difficulty); + loadLevel(new GameInfoContainer(0, difficulty, type, level, null, null)); + saveLoadLevelManager.checkAndRestock(); - - // TODO call methods to generate level. - //int[] generated = qqWingController.generate(type, difficulty); - //loadLevel(new GameInfoContainer(0, difficulty, type, generated, null, null)); - - /* switch(type) { - case Default_6x6: - loadLevel(new GameInfoContainer(1, GameDifficulty.Easy, 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)); - break; - case Default_12x12: - loadLevel(new GameInfoContainer(2, GameDifficulty.Hard, GameType.Default_12x12, - new int[] {0, 2, 1, 0, 0, 6, 0, 0, 0, 8, 9, 0, - 10, 0,12, 0, 0, 2, 1,11, 0, 0, 0, 6, - 6, 0, 0, 4, 0,12, 0, 0, 0, 0, 2, 1, - 0, 0, 0, 5, 0, 0, 0, 4,11,10, 0, 0, - 0,10, 0, 1, 0, 0, 6, 0, 0, 0, 0, 0, - 0, 7, 0, 0,11, 0, 0, 0, 0,12, 8, 9, - 2, 1,11, 0, 0, 0, 0, 7, 0, 0, 6, 0, - 0, 0, 0, 0, 0, 5, 0, 0, 4, 0,10, 0, - 0, 0, 7, 3, 9, 0, 0, 0, 1, 0, 0, 0, - 1, 5, 0, 0, 0, 0, 4, 0,10, 0, 0,11, - 9, 0, 0, 0, 1,10, 2, 0, 0, 6, 0, 7, - 0, 6,10, 0, 0, 0, 8, 0, 0, 1,12, 0} - ,null, null)); - break; - case Default_9x9: - case Unspecified: - default: - loadLevel(new GameInfoContainer(3, GameDifficulty.Moderate, GameType.Default_9x9, - new int[]{5, 0, 1, 9, 0, 0, 0, 0, 0, - 2, 0, 0, 0, 0, 4, 9, 5, 0, - 3, 9, 0, 7, 0, 0, 0, 2, 6, - 0, 3, 0, 0, 0, 1, 0, 7, 2, - 0, 0, 6, 0, 5, 7, 0, 0, 0, - 0, 7, 2, 0, 0, 9, 0, 4, 1, - 0, 0, 0, 0, 7, 0, 4, 0, 9, - 6, 4, 0, 0, 0, 0, 0, 0, 0, - 7, 0, 0, 0, 1, 0, 3, 0, 5} - , null, null)); - }*/ } public int getTime() { @@ -174,6 +126,7 @@ public class GameController implements IModelChangedListener { gameBoard.registerOnModelChangeListener(this); + doUndo = new DoUndo(gameBoard); // call the solve function to get the solution of this board //qqWingController.solve(gameBoard); } @@ -188,25 +141,8 @@ public class GameController implements IModelChangedListener { solution = qqWingController.solve(gameBoard); } return solution; - -// if(solvedBoards.size() == 0) { -// -// solver = new Solver(gameBoard); -// -// if (solver.solve(solver.getGameBoard())) { -// solvedBoards.addAll(solver.getSolutions()); -// return solvedBoards; -// } -// } -// return solvedBoards; } - /*public boolean loadLevel(GameBoard level) { - if(GameBoard.isValid(level)) { - gameBoard = level; - } - }*/ - private void setGameType(GameType type) { this.gameType = type; this.size = type.getSize(); @@ -328,6 +264,7 @@ public class GameController implements IModelChangedListener { if(!c.isFixed()) { c.setValue(0); //notifyListeners(); + return true; } return false; @@ -358,6 +295,9 @@ public class GameController implements IModelChangedListener { public void toggleNote(int row, int col, int value) { GameCell c = gameBoard.getCell(row,col); + if(c.hasValue()) { + c.setValue(0); + } c.toggleNote(value); //notifyListeners(); } @@ -410,15 +350,29 @@ public class GameController implements IModelChangedListener { } public void selectValue(int value) { - if(isValidCellSelected()) setValue(selectedRow, selectedCol, value); + if(isValidCellSelected() && getSelectedValue() != value) { + setValue(selectedRow, selectedCol, value); + // add state to undo + doUndo.addState(gameBoard); + } + } public void deleteSelectedValue() { - if(isValidCellSelected()) deleteValue(selectedRow, selectedCol); + if(isValidCellSelected() && getSelectedValue() != 0) { + deleteValue(selectedRow, selectedCol); + // add state to undo + doUndo.addState(gameBoard); + } + } public void toggleSelectedNote(int value) { - if(isValidCellSelected()) toggleNote(selectedRow, selectedCol, value); + if(isValidCellSelected()) { + toggleNote(selectedRow, selectedCol, value); + // add state to undo + doUndo.addState(gameBoard); + } } public boolean isValidCellSelected() { @@ -450,7 +404,6 @@ public class GameController implements IModelChangedListener { //TODO disable controls and play animation in view. onSolved method is called. } } else { - //notifiedOnSolvedListeners = false; // TODO: errorList now holds all the errors // TODO: display errors .. notify some view? @@ -520,4 +473,48 @@ public class GameController implements IModelChangedListener { } } + public void ReDo() { + updateGameBoard(doUndo.ReDo()); + } + + public void UnDo() { + updateGameBoard(doUndo.UnDo()); + } + + public boolean isRedoAvailable() { + return doUndo.isRedoAvailable(); + } + public boolean isUndoAvailable() { + return doUndo.isUnDoAvailable(); + } + + public void updateGameBoard(final GameBoard gameBoard) { + if(gameBoard == null) { + return; + } + for(int i = 0; i < gameBoard.getSize(); i++) { + for(int j = 0; j < gameBoard.getSize(); j++) { + GameCell other_c = gameBoard.getCell(i,j); + GameCell this_c = this.gameBoard.getCell(i,j); + if(other_c.isFixed()) { + continue; + } + if(other_c.hasValue()) { + this_c.setValue(other_c.getValue()); + } else { + this_c.setValue(0); + for(int k = 0; k < gameBoard.getSize(); k++) { + if(other_c.getNotes()[k]) { + this_c.setNote(k+1); + } else { + this_c.deleteNote(k+1); + } + } + } + } + } + + return; + } + } diff --git a/app/src/main/java/tu_darmstadt/sudoku/controller/generator/Generator.java b/app/src/main/java/tu_darmstadt/sudoku/controller/generator/Generator.java deleted file mode 100644 index 9a2dbb1..0000000 --- a/app/src/main/java/tu_darmstadt/sudoku/controller/generator/Generator.java +++ /dev/null @@ -1,164 +0,0 @@ -package tu_darmstadt.sudoku.controller.generator; - -import android.graphics.Point; -import android.support.v7.util.SortedList; - -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; -import java.util.Random; - -import tu_darmstadt.sudoku.controller.solver.Solver; -import tu_darmstadt.sudoku.game.GameBoard; -import tu_darmstadt.sudoku.game.GameCell; -import tu_darmstadt.sudoku.game.GameDifficulty; -import tu_darmstadt.sudoku.game.GameType; -import tu_darmstadt.sudoku.game.ICellAction; - -/** - * Created by Chris on 19.11.2015. - */ -public class Generator { - - private Random random; - private int size; - private int sectionHeight; - private int sectionWidth; - private GameBoard gameBoard; - - public Generator(GameType type, GameDifficulty difficulty) { - this.size = type.getSize(); - this.sectionHeight = type.getSectionHeight(); - this.sectionWidth = type.getSectionWidth(); - this.gameBoard = new GameBoard(type); - gameBoard.initCells(new int[size*size]); - setNotes(gameBoard); - - // generate a random valid board. - gameBoard = generate(); - - // produce a level out of it. - gameBoard = createLevel(difficulty); - } - - public GameBoard createLevel(GameDifficulty difficulty) { - return gameBoard; - } - - public GameBoard getGameBoard() { - return gameBoard; - } - - - public GameBoard generate() { - random = new Random(); - - GameBoard workingBoard = gameBoard; - GameBoard board = gameBoard; - - /*GameCell chosen = gameBoard.getCell(random.nextInt(9), random.nextInt(9)); - while(chosen.getNoteCount() <= 2) { - chosen = gameBoard.getCell(random.nextInt(9), random.nextInt(9)); - }*/ - - while(workingBoard != null && !workingBoard.isFilled()) { - - // clone board - try { - workingBoard = board.clone(); - } catch (CloneNotSupportedException e) { - e.printStackTrace(); - return null; - } - - // get all candidates - List candidates = getListOfCandidates(workingBoard); - // choose one of them - GameCell chosen = candidates.get(random.nextInt(candidates.size())); - // get all possible values - List possibleValues = getPossibleValues(chosen); - // set a random value of that pool - chosen.setValue(possibleValues.get(random.nextInt(possibleValues.size()))); - - deleteConnectedValues(workingBoard, chosen); - - Solver solver = new Solver(workingBoard); - if (solver.solve(solver.getGameBoard())) { - List solutions = solver.getSolutions(); - switch(solutions.size()) { - case 0: // if we get no solution .. revert change - continue; - case 1: // if we get 1 solution we are done and return the solution - return solutions.get(0); - default: // if we get more than 1 solution .. keep setting numbers - board = workingBoard; - continue; - } - } else { - - } - } - - - - - return null; - } - - private boolean deleteConnectedValues(final GameBoard gameBoard, final GameCell cell) { - return gameBoard.actionOnCells(new ICellAction() { - @Override - public Boolean action(GameCell gc, Boolean existing) { - if (!gc.hasValue() && !gc.equals(cell)) { - if (gc.getRow() == cell.getRow() - || gc.getCol() == cell.getCol() - || (int) (Math.floor(gc.getRow() / sectionHeight) * sectionHeight + Math.floor(gc.getCol() / sectionWidth)) == - (int) (Math.floor(cell.getRow() / sectionHeight) * sectionHeight + Math.floor(cell.getCol() / sectionWidth))) { - gc.deleteNote(cell.getValue()); - if(gc.getNoteCount() == 0) { - existing = true; - } - } - } - return existing; - } - }, false); - } - - private List getPossibleValues(GameCell c) { - List result = new LinkedList<>(); - for(int i = 0; i < size; i++) { - if(c.getNotes()[i]) { - result.add(i+1); - } - } - return result; - } - - private List getListOfCandidates(GameBoard gameBoard) { - final ArrayList candidates = new ArrayList<>(); - - gameBoard.actionOnCells(new ICellAction>() { - @Override - public ArrayList action(GameCell gc, ArrayList existing) { - if(gc.getNoteCount() > 1) { - existing.add(gc); - } - return existing; - } - }, candidates); - - return candidates; - } - - private void setNotes(GameBoard gameBoard) { - for(int i = 0; i < gameBoard.getSize(); i++) { - for(int j = 0; j < gameBoard.getSize(); j++) { - for(int k = 1; k <= gameBoard.getSize(); k++) { - gameBoard.getCell(i,j).setNote(k); - } - } - } - } - -} diff --git a/app/src/main/java/tu_darmstadt/sudoku/controller/solver/Solver.java b/app/src/main/java/tu_darmstadt/sudoku/controller/solver/Solver.java deleted file mode 100644 index 45f37d1..0000000 --- a/app/src/main/java/tu_darmstadt/sudoku/controller/solver/Solver.java +++ /dev/null @@ -1,352 +0,0 @@ -package tu_darmstadt.sudoku.controller.solver; - -import android.graphics.Point; -import android.util.Log; - -import java.util.LinkedList; -import java.util.List; - -import tu_darmstadt.sudoku.controller.helper.GameInfoContainer; -import tu_darmstadt.sudoku.game.CellConflict; -import tu_darmstadt.sudoku.game.GameBoard; -import tu_darmstadt.sudoku.game.GameCell; -import tu_darmstadt.sudoku.game.ICellAction; - -/** - * Created by Chris on 10.11.2015. - */ -public class Solver { - - private GameBoard gameBoard = null; - private LinkedList solutions = new LinkedList<>(); - - public Solver(GameBoard gf) { - try { - if(gf == null) { - throw new IllegalArgumentException("GameBoard may not be null."); - } - - gameBoard = gf.clone(); - } catch(CloneNotSupportedException e) { - throw new IllegalArgumentException("This GameBoard is not cloneable.", e); - } - - gameBoard.reset(); - if(!isSolvable(gameBoard)) { - throw new IllegalArgumentException("This GameBoard is not solveable."); - } - - setNotes(gameBoard); - } - - public void setNotes(GameBoard gameBoard) { - for(int i = 0; i < gameBoard.getSize(); i++) { - for(int j = 0; j < gameBoard.getSize(); j++) { - for(int k = 1; k <= gameBoard.getSize(); k++) { - gameBoard.getCell(i,j).setNote(k); - } - } - } - } - - public boolean isSolvable(GameBoard gameBoard) { - for(int i = 0; i < gameBoard.getSize(); i++) { - if(hasErrors(gameBoard.getRow(i))) return false; - if(hasErrors(gameBoard.getColumn(i))) return false; - if(hasErrors(gameBoard.getSection(i))) return false; - } - return true; - } - - public boolean hasErrors(LinkedList list) { - LinkedList checked = new LinkedList(); - for(GameCell c : list) { - if(checked.contains(c.getValue())) { - return true; - } - if(c.hasValue()) { - checked.add(c.getValue()); - } - } - return false; - } - - public LinkedList getSolutions() { - return solutions; - } - - public boolean isDone(GameBoard gameBoard) { - for(int i = 0; i < gameBoard.getSize(); i++) { - for(int j = 0; j < gameBoard.getSize(); j++) { - if(!gameBoard.getCell(i,j).hasValue()) return false; - } - } - return true; - } - - public boolean solve(final GameBoard gameBoard) { - - checkSolvedCells(gameBoard); - - //String string = gameBoard.toString(); - if(isDone(gameBoard)) { - solutions.add(gameBoard); - return true; - } - - if(showPossibles(gameBoard)) - return solve(gameBoard); - - if(isImpossible(gameBoard)) - return false; - - if(searchHiddenSingles(gameBoard)) - return solve(gameBoard); - - if(searchNakedPairsTriples(gameBoard)) - return solve(gameBoard); - - if(searchHiddenPairsTriples(gameBoard)) - return solve(gameBoard); - - if(searchNakedQuads(gameBoard)) - return solve(gameBoard); - - if(searchPointingPairs(gameBoard)) - return solve(gameBoard); - - if(searchBoxLineReduction(gameBoard)) - return solve(gameBoard); - - - // if every defined strategy fails.. we have to guess - // get the best candidate - Point p = getBestCandidate(gameBoard); - - // then we test every possible value for that candidate, but we do it on a cloned gameBoard - boolean result = false; - for(int i = 0; i < gameBoard.getSize(); i++) { - GameCell gc = gameBoard.getCell(p.x,p.y); - try { - if(gc.getNotes()[i]) { - GameBoard gameBoardCopy = gameBoard.clone(); - - GameCell copyGC = gameBoardCopy.getCell(p.x, p.y); - - copyGC.setValue(i+1); - - result = solve(gameBoardCopy); - - if(solutions.size() > 1) { - // don't search for more than 1 solution - return result; - } - - //if (result) { - // stop after we found 1 solution - //return true; - - // or keep going to find multiple solutions - //} - - } else { - continue; - } - } catch(CloneNotSupportedException e) { - return false; - } - } - return result; - } - - public boolean isImpossible(GameBoard gameBoard) { - return gameBoard.actionOnCells(new ICellAction() { - @Override - public Boolean action(GameCell gc, Boolean existing) { - return (gc.getNoteCount() == 0 && !gc.hasValue()) ? true : existing; - } - }, false); - } - - public boolean calculateNextPossibleStep() { - - return false; - } - - public GameBoard getGameBoard() { - return gameBoard; - } - - private boolean checkSolvedCells(final GameBoard gameBoard) { - return gameBoard.actionOnCells(new ICellAction() { - @Override - public Boolean action(GameCell gc, Boolean existing) { - int value = -1; - if(!gc.hasValue() && gc.getNoteCount() == 1) { - for(int i = 0; i < gameBoard.getSize(); i++) { - if(gc.getNotes()[i]) { - value = i+1; - break; - } - } - gc.setValue(value); - existing = true; - } - return existing; - }}, false); - } - - - public boolean showPossibles(final GameBoard gameBoard) { - boolean deletedSomething = false; - LinkedList list = new LinkedList(); - for(int i = 0; i < gameBoard.getSize(); i++) { - for(int j = 0; j < gameBoard.getSize(); j++) { - GameCell gc = gameBoard.getCell(i,j); - if(!gc.hasValue()) { - list.clear(); - list.addAll(gameBoard.getRow(i)); - list.addAll(gameBoard.getColumn(j)); - list.addAll(gameBoard.getSection(i,j)); - for(GameCell c : list) { - for(int k = 0; k < gameBoard.getSize(); k++) { - if(gc.getNotes()[k] && c.hasValue() && !c.equals(gc) && k+1 == c.getValue()) { - gc.deleteNote(c.getValue()); - deletedSomething = true; - } - } - } - } - } - } - return deletedSomething; - } - - private boolean searchHiddenSingles(final GameBoard gameBoard) { - boolean foundHiddenSingles = false; - - LinkedList list = new LinkedList<>(); - - for(int i = 0; i < gameBoard.getSize()*3; i++) { - - int index = i % gameBoard.getSize(); - int listSelector = (int)Math.floor(i / gameBoard.getSize()); - - if(listSelector == 0) list = gameBoard.getRow(index); - if(listSelector == 1) list = gameBoard.getColumn(index); - if(listSelector == 2) list = gameBoard.getSection(index); - - LinkedList possibles = new LinkedList<>(); - LinkedList notPossibles = new LinkedList(); - - for(GameCell c : list) { // check all gameCells in Row - - if(c.hasValue()) { - notPossibles.add(c.getValue()); - continue; - } - - for(int k = 0; k < gameBoard.getSize(); k++) { // check all nodes - if(c.getNotes()[k]) { // if k note active - for(int p = 0; p < possibles.size(); p++) { // check possible list - if(possibles.get(p)[2] == k+1) { // is value in possible list? - // value already exists in possible list - // add to impossibles - if(!notPossibles.contains(k+1)) { - notPossibles.add(k + 1); - } - } - } - if(!notPossibles.contains(k+1)){ // if k node is possible - possibles.add(new Integer[] {c.getRow(), c.getCol(), k+1}); - } - } - } - } - // we checked a section/row/column - // now set the remaining possibles that are not impossible - boolean possible = true; - for(int p = 0; p < possibles.size(); p++) { - possible = true; - for(int np = 0; np < notPossibles.size(); np++) { - if(possibles.get(p)[2] == notPossibles.get(np)) { - // found that current possible is impossible - possible = false; - } - } - // if this is still possible then SET IT :D YAY - if(possible) { - gameBoard.getCell(possibles.get(p)[0],possibles.get(p)[1]).setValue(possibles.get(p)[2]); - foundHiddenSingles = true; - } - } - } - - return foundHiddenSingles; - } - - - public boolean searchNakedPairsTriples(final GameBoard gameBoard) { - return false; - } - public boolean searchHiddenPairsTriples(final GameBoard gameBoard) { - return false; - } - public boolean searchNakedQuads(final GameBoard gameBoard) { - return false; - } - public boolean searchPointingPairs(final GameBoard gameBoard) { - return false; - } - public boolean searchBoxLineReduction(final GameBoard gameBoard) { - return false; - } - - public Point getBestCandidate(GameBoard gameBoard) { - Point bestCandidate = new Point(); - int minimumCount = gameBoard.getSize(); - int count = 0; - Point candidate = new Point(); - for(int i = 0; i < gameBoard.getSize(); i++) { - - count = countUnsolved(gameBoard.getRow(i),candidate); - if(count != 0 && count < minimumCount) { - minimumCount = count; - bestCandidate.set(candidate.x, candidate.y); - } - - count = countUnsolved(gameBoard.getColumn(i),candidate); - if(count != 0 && count < minimumCount) { - minimumCount = count; - bestCandidate.set(candidate.x, candidate.y); - } - - count = countUnsolved(gameBoard.getSection(i),candidate); - if(count != 0 && count < minimumCount) { - minimumCount = count; - bestCandidate.set(candidate.x, candidate.y); - } - - if(minimumCount == 2) { - return bestCandidate; - } - } - return bestCandidate; - } - - public int countUnsolved(final List list, Point p) { - int count = 0; - for(GameCell gc : list) { - if(!gc.hasValue()) { - count++; - p.set(gc.getRow(), gc.getCol()); - } - } - return count; - } - - - - - -} 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 0b88187..ba807bc 100644 --- a/app/src/main/java/tu_darmstadt/sudoku/game/GameBoard.java +++ b/app/src/main/java/tu_darmstadt/sudoku/game/GameBoard.java @@ -3,7 +3,7 @@ package tu_darmstadt.sudoku.game; import java.util.LinkedList; import java.util.List; -import tu_darmstadt.sudoku.game.listeners.IModelChangedListener; +import tu_darmstadt.sudoku.game.listener.IModelChangedListener; /** * Created by Christopher Beckmann on 06.11.2015. diff --git a/app/src/main/java/tu_darmstadt/sudoku/game/GameCell.java b/app/src/main/java/tu_darmstadt/sudoku/game/GameCell.java index f795672..5943ccf 100644 --- a/app/src/main/java/tu_darmstadt/sudoku/game/GameCell.java +++ b/app/src/main/java/tu_darmstadt/sudoku/game/GameCell.java @@ -4,7 +4,7 @@ import java.util.Arrays; import java.util.LinkedList; import java.util.List; -import tu_darmstadt.sudoku.game.listeners.IModelChangedListener; +import tu_darmstadt.sudoku.game.listener.IModelChangedListener; /** * Created by Chris on 06.11.2015. @@ -174,8 +174,9 @@ public class GameCell implements Cloneable { @Override public GameCell clone() throws CloneNotSupportedException { GameCell clone = (GameCell) super.clone(); - clone.modelChangedListeners = new LinkedList(); + // keep listeners .. so we can just replace the board and still have the listeners clone.notes = (notes == null) ? null : Arrays.copyOf(notes, notes.length); + return clone; } diff --git a/app/src/main/java/tu_darmstadt/sudoku/game/listener/IGameSolvedListener.java b/app/src/main/java/tu_darmstadt/sudoku/game/listener/IGameSolvedListener.java new file mode 100644 index 0000000..ecd3723 --- /dev/null +++ b/app/src/main/java/tu_darmstadt/sudoku/game/listener/IGameSolvedListener.java @@ -0,0 +1,8 @@ +package tu_darmstadt.sudoku.game.listener; + +/** + * Created by Chris on 19.11.2015. + */ +public interface IGameSolvedListener { + public void onSolved(); +} diff --git a/app/src/main/java/tu_darmstadt/sudoku/game/listeners/IModelChangedListener.java b/app/src/main/java/tu_darmstadt/sudoku/game/listener/IModelChangedListener.java similarity index 79% rename from app/src/main/java/tu_darmstadt/sudoku/game/listeners/IModelChangedListener.java rename to app/src/main/java/tu_darmstadt/sudoku/game/listener/IModelChangedListener.java index dd54674..2214a43 100644 --- a/app/src/main/java/tu_darmstadt/sudoku/game/listeners/IModelChangedListener.java +++ b/app/src/main/java/tu_darmstadt/sudoku/game/listener/IModelChangedListener.java @@ -1,4 +1,4 @@ -package tu_darmstadt.sudoku.game.listeners; +package tu_darmstadt.sudoku.game.listener; import tu_darmstadt.sudoku.game.GameCell; diff --git a/app/src/main/java/tu_darmstadt/sudoku/game/listeners/ITimerListener.java b/app/src/main/java/tu_darmstadt/sudoku/game/listener/ITimerListener.java similarity index 72% rename from app/src/main/java/tu_darmstadt/sudoku/game/listeners/ITimerListener.java rename to app/src/main/java/tu_darmstadt/sudoku/game/listener/ITimerListener.java index 6f9b436..ec07c0d 100644 --- a/app/src/main/java/tu_darmstadt/sudoku/game/listeners/ITimerListener.java +++ b/app/src/main/java/tu_darmstadt/sudoku/game/listener/ITimerListener.java @@ -1,4 +1,4 @@ -package tu_darmstadt.sudoku.game.listeners; +package tu_darmstadt.sudoku.game.listener; /** * Created by TMZ_LToP on 20.11.2015. diff --git a/app/src/main/java/tu_darmstadt/sudoku/game/listeners/IGameSolvedListener.java b/app/src/main/java/tu_darmstadt/sudoku/game/listeners/IGameSolvedListener.java deleted file mode 100644 index 4e5ee72..0000000 --- a/app/src/main/java/tu_darmstadt/sudoku/game/listeners/IGameSolvedListener.java +++ /dev/null @@ -1,11 +0,0 @@ -package tu_darmstadt.sudoku.game.listeners; - -import tu_darmstadt.sudoku.controller.GameController; -import tu_darmstadt.sudoku.game.GameBoard; - -/** - * Created by Chris on 19.11.2015. - */ -public interface IGameSolvedListener { - public void onSolved(); -} diff --git a/app/src/main/java/tu_darmstadt/sudoku/ui/GameActivity.java b/app/src/main/java/tu_darmstadt/sudoku/ui/GameActivity.java index 687dc54..68a475e 100644 --- a/app/src/main/java/tu_darmstadt/sudoku/ui/GameActivity.java +++ b/app/src/main/java/tu_darmstadt/sudoku/ui/GameActivity.java @@ -23,8 +23,8 @@ import tu_darmstadt.sudoku.controller.GameController; import tu_darmstadt.sudoku.controller.helper.GameInfoContainer; import tu_darmstadt.sudoku.game.GameDifficulty; import tu_darmstadt.sudoku.game.GameType; -import tu_darmstadt.sudoku.game.listeners.IGameSolvedListener; -import tu_darmstadt.sudoku.game.listeners.ITimerListener; +import tu_darmstadt.sudoku.game.listener.IGameSolvedListener; +import tu_darmstadt.sudoku.game.listener.ITimerListener; import tu_darmstadt.sudoku.ui.view.R; import tu_darmstadt.sudoku.ui.view.SudokuFieldLayout; import tu_darmstadt.sudoku.ui.view.SudokuKeyboardLayout; diff --git a/app/src/main/java/tu_darmstadt/sudoku/ui/LoadGameActivity.java b/app/src/main/java/tu_darmstadt/sudoku/ui/LoadGameActivity.java index d08aec2..05c3b9e 100644 --- a/app/src/main/java/tu_darmstadt/sudoku/ui/LoadGameActivity.java +++ b/app/src/main/java/tu_darmstadt/sudoku/ui/LoadGameActivity.java @@ -13,10 +13,10 @@ import android.preference.PreferenceManager; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.LayoutInflater; +import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; -import android.widget.ArrayAdapter; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.ListView; @@ -32,6 +32,7 @@ import java.util.TimeZone; import tu_darmstadt.sudoku.controller.SaveLoadGameStateController; import tu_darmstadt.sudoku.controller.helper.GameInfoContainer; import tu_darmstadt.sudoku.game.GameDifficulty; +import tu_darmstadt.sudoku.ui.listener.IDeleteDialogFragmentListener; import tu_darmstadt.sudoku.ui.view.R; public class LoadGameActivity extends AppCompatActivity implements IDeleteDialogFragmentListener { @@ -46,11 +47,26 @@ public class LoadGameActivity extends AppCompatActivity implements IDeleteDialog setContentView(R.layout.activity_load_game); + android.support.v7.app.ActionBar actionBar = getSupportActionBar(); + actionBar.setTitle(R.string.menu_continue_game); + actionBar.setDisplayHomeAsUpEnabled(true); + settings = PreferenceManager.getDefaultSharedPreferences(this); init(); } + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + // Respond to the action bar's Up/Home button + case android.R.id.home: + finish(); + return true; + } + return super.onOptionsItemSelected(item); + } + public void init() { SaveLoadGameStateController saveLoadGameStateController = new SaveLoadGameStateController(this, settings); diff --git a/app/src/main/java/tu_darmstadt/sudoku/ui/IDeleteDialogFragmentListener.java b/app/src/main/java/tu_darmstadt/sudoku/ui/listener/IDeleteDialogFragmentListener.java similarity index 84% rename from app/src/main/java/tu_darmstadt/sudoku/ui/IDeleteDialogFragmentListener.java rename to app/src/main/java/tu_darmstadt/sudoku/ui/listener/IDeleteDialogFragmentListener.java index 33260a0..9e8eb95 100644 --- a/app/src/main/java/tu_darmstadt/sudoku/ui/IDeleteDialogFragmentListener.java +++ b/app/src/main/java/tu_darmstadt/sudoku/ui/listener/IDeleteDialogFragmentListener.java @@ -1,4 +1,4 @@ -package tu_darmstadt.sudoku.ui; +package tu_darmstadt.sudoku.ui.listener; import android.app.DialogFragment; @@ -8,4 +8,4 @@ import android.app.DialogFragment; public interface IDeleteDialogFragmentListener { public void onDialogPositiveClick(int position); public void onDialogNegativeClick(int position); -} +} \ No newline at end of file diff --git a/app/src/main/java/tu_darmstadt/sudoku/ui/view/SudokuSpecialButtonLayout.java b/app/src/main/java/tu_darmstadt/sudoku/ui/view/SudokuSpecialButtonLayout.java index a3665f5..7953361 100644 --- a/app/src/main/java/tu_darmstadt/sudoku/ui/view/SudokuSpecialButtonLayout.java +++ b/app/src/main/java/tu_darmstadt/sudoku/ui/view/SudokuSpecialButtonLayout.java @@ -42,15 +42,17 @@ public class SudokuSpecialButtonLayout extends LinearLayout { keyboard.toggleNotesEnabled(); break; case Do: - // TODO: not implemented + gameController.ReDo(); + gameController.saveGame(getContext()); break; case Undo: - // TODO: not implemented + gameController.UnDo(); + gameController.saveGame(getContext()); break; case Hint: if(gameController.isValidCellSelected()) { int[] solved = gameController.solve(); - // TODO test every placed value so far + // TODO test every placed value so far? Or just reveal current selected? // and reveal the selected value. gameController.selectValue(solved[row * gameController.getSize() + col]); @@ -79,7 +81,7 @@ public class SudokuSpecialButtonLayout extends LinearLayout { fixedButtons = new SudokuButton[fixedButtonsCount]; LayoutParams p; int i = 0; - ArrayList type = (ArrayList) SudokuButtonType.getSpecialButtons(); + //ArrayList type = (ArrayList) SudokuButtonType.getSpecialButtons(); for (SudokuButtonType t : SudokuButtonType.getSpecialButtons()){ fixedButtons[i] = new SudokuButton(getContext(),null); p = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT,1); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 0d7c2ad..fe0a79f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -67,4 +67,6 @@ Delete Cancel + +