Timer is now being saved when loading a game.
This commit is contained in:
parent
b4fb350fa0
commit
fc992778a0
10 changed files with 296 additions and 45 deletions
|
@ -9,7 +9,7 @@ import java.util.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
import java.util.logging.Handler;
|
import java.util.logging.Handler;
|
||||||
|
|
||||||
import tu_darmstadt.sudoku.controller.generator.Generator;
|
import tu_darmstadt.sudoku.controller.solver.Solver;
|
||||||
import tu_darmstadt.sudoku.game.CellConflict;
|
import tu_darmstadt.sudoku.game.CellConflict;
|
||||||
import tu_darmstadt.sudoku.game.CellConflictList;
|
import tu_darmstadt.sudoku.game.CellConflictList;
|
||||||
import tu_darmstadt.sudoku.game.GameBoard;
|
import tu_darmstadt.sudoku.game.GameBoard;
|
||||||
|
@ -42,11 +42,13 @@ public class GameController implements IModelChangedListener {
|
||||||
private CellConflictList errorList = new CellConflictList();
|
private CellConflictList errorList = new CellConflictList();
|
||||||
private int selectedValue;
|
private int selectedValue;
|
||||||
private LinkedList<IGameSolvedListener> solvedListeners = new LinkedList<>();
|
private LinkedList<IGameSolvedListener> solvedListeners = new LinkedList<>();
|
||||||
|
private boolean notifiedOnSolvedListeners = false;
|
||||||
private Timer timer;
|
private Timer timer;
|
||||||
private android.os.Handler handler = new android.os.Handler();
|
private android.os.Handler handler = new android.os.Handler();
|
||||||
private TimerTask timerTask;
|
private TimerTask timerTask;
|
||||||
private int time = 0;
|
private int time = 0;
|
||||||
private LinkedList<ITimerListener> timerListeners = new LinkedList<>();
|
private LinkedList<ITimerListener> timerListeners = new LinkedList<>();
|
||||||
|
private boolean timerRunning = false;
|
||||||
|
|
||||||
// private Solver solver;
|
// private Solver solver;
|
||||||
// private SudokuGenerator generator;
|
// private SudokuGenerator generator;
|
||||||
|
@ -70,8 +72,11 @@ public class GameController implements IModelChangedListener {
|
||||||
return gameID;
|
return gameID;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadNewLevel(GameType type, int difficulty) {
|
public void loadNewLevel(GameType type, GameDifficulty difficulty) {
|
||||||
Generator generator = new Generator();
|
//Generator generator = new Generator(type, difficulty);
|
||||||
|
//GameBoard randomBoard = generator.getGameBoard();
|
||||||
|
|
||||||
|
|
||||||
// TODO call methods to generate level.
|
// TODO call methods to generate level.
|
||||||
|
|
||||||
switch(type) {
|
switch(type) {
|
||||||
|
@ -85,7 +90,7 @@ public class GameController implements IModelChangedListener {
|
||||||
0,3,0,5,0,1}, null,null));
|
0,3,0,5,0,1}, null,null));
|
||||||
break;
|
break;
|
||||||
case Default_12x12:
|
case Default_12x12:
|
||||||
loadLevel(new GameInfoContainer(2, GameDifficulty.Easy, GameType.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,
|
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,
|
10, 0,12, 0, 0, 2, 1,11, 0, 0, 0, 6,
|
||||||
6, 0, 0, 4, 0,12, 0, 0, 0, 0, 2, 1,
|
6, 0, 0, 4, 0,12, 0, 0, 0, 0, 2, 1,
|
||||||
|
@ -103,7 +108,7 @@ public class GameController implements IModelChangedListener {
|
||||||
case Default_9x9:
|
case Default_9x9:
|
||||||
case Unspecified:
|
case Unspecified:
|
||||||
default:
|
default:
|
||||||
loadLevel(new GameInfoContainer(3, GameDifficulty.Easy, GameType.Default_9x9,
|
loadLevel(new GameInfoContainer(3, GameDifficulty.Moderate, GameType.Default_9x9,
|
||||||
new int[]{5, 0, 1, 9, 0, 0, 0, 0, 0,
|
new int[]{5, 0, 1, 9, 0, 0, 0, 0, 0,
|
||||||
2, 0, 0, 0, 0, 4, 9, 5, 0,
|
2, 0, 0, 0, 0, 4, 9, 5, 0,
|
||||||
3, 9, 0, 7, 0, 0, 0, 2, 6,
|
3, 9, 0, 7, 0, 0, 0, 2, 6,
|
||||||
|
@ -117,12 +122,17 @@ public class GameController implements IModelChangedListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getTime() {
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
public void loadLevel(GameInfoContainer gic) {
|
public void loadLevel(GameInfoContainer gic) {
|
||||||
int[] fixedValues = gic.getFixedValues();
|
int[] fixedValues = gic.getFixedValues();
|
||||||
int[] setValues = gic.getSetValues();
|
int[] setValues = gic.getSetValues();
|
||||||
boolean[][] setNotes = gic.getSetNotes();
|
boolean[][] setNotes = gic.getSetNotes();
|
||||||
this.gameID = gic.getID();
|
this.gameID = gic.getID();
|
||||||
this.difficulty = gic.getDifficulty();
|
this.difficulty = gic.getDifficulty();
|
||||||
|
this.time = gic.getTime();
|
||||||
|
|
||||||
setGameType(gic.getGameType());
|
setGameType(gic.getGameType());
|
||||||
this.gameBoard = new GameBoard(gic.getGameType());
|
this.gameBoard = new GameBoard(gic.getGameType());
|
||||||
|
@ -261,7 +271,12 @@ public class GameController implements IModelChangedListener {
|
||||||
gameID = settings.getInt("lastGameID", 0)+1;
|
gameID = settings.getInt("lastGameID", 0)+1;
|
||||||
|
|
||||||
SharedPreferences.Editor editor = settings.edit();
|
SharedPreferences.Editor editor = settings.edit();
|
||||||
|
// is anyone ever gonna play so many levels? :)
|
||||||
|
if(gameID == Integer.MAX_VALUE-1) {
|
||||||
|
editor.putInt("lastGameID", 1);
|
||||||
|
} else {
|
||||||
editor.putInt("lastGameID", gameID);
|
editor.putInt("lastGameID", gameID);
|
||||||
|
}
|
||||||
editor.commit();
|
editor.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -414,11 +429,19 @@ public class GameController implements IModelChangedListener {
|
||||||
if(gameBoard.isFilled()) {
|
if(gameBoard.isFilled()) {
|
||||||
List<CellConflict> errorList = new LinkedList<>();
|
List<CellConflict> errorList = new LinkedList<>();
|
||||||
if(gameBoard.isSolved(errorList)) {
|
if(gameBoard.isSolved(errorList)) {
|
||||||
|
if(!notifiedOnSolvedListeners) {
|
||||||
|
notifiedOnSolvedListeners = true;
|
||||||
notifySolvedListeners();
|
notifySolvedListeners();
|
||||||
|
//TODO disable controls and play animation in view. onSolved method is called.
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
//notifiedOnSolvedListeners = false;
|
||||||
|
|
||||||
// TODO: errorList now holds all the errors
|
// TODO: errorList now holds all the errors
|
||||||
// TODO: display errors .. notify some view?
|
// TODO: display errors .. notify some view?
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
notifiedOnSolvedListeners = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -451,30 +474,35 @@ public class GameController implements IModelChangedListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initTimer() {
|
private void initTimer() {
|
||||||
|
|
||||||
timerTask = new TimerTask() {
|
timerTask = new TimerTask() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
handler.post(new Runnable() {
|
handler.post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
if(timerRunning) {
|
||||||
notifyTimerListener(time++);
|
notifyTimerListener(time++);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
timer = new Timer();
|
timer = new Timer();
|
||||||
}
|
|
||||||
|
|
||||||
public void startTimer() {
|
|
||||||
|
|
||||||
timer.scheduleAtFixedRate(timerTask,0,1000);
|
timer.scheduleAtFixedRate(timerTask,0,1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void startTimer() {
|
||||||
|
if(!timerRunning) {
|
||||||
|
timerRunning = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void pauseTimer(){
|
public void pauseTimer(){
|
||||||
timer.cancel();
|
if(timerRunning) {
|
||||||
|
timerRunning = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,11 +76,15 @@ public class SaveLoadController {
|
||||||
|
|
||||||
// fill the container
|
// fill the container
|
||||||
String id = file.getName().substring(5, file.getName().lastIndexOf("."));
|
String id = file.getName().substring(5, file.getName().lastIndexOf("."));
|
||||||
|
int i = 0;
|
||||||
gic.setID(Integer.valueOf(id)); // save_x.txt
|
gic.setID(Integer.valueOf(id)); // save_x.txt
|
||||||
gic.parseGameType(values[0]);
|
gic.parseGameType(values[i++]);
|
||||||
gic.parseFixedValues(values[1]);
|
gic.parseTime(values[i++]);
|
||||||
gic.parseSetValues(values[2]);
|
gic.parseDate(values[i++]);
|
||||||
gic.parseNotes(values[3]);
|
gic.parseDifficulty(values[i++]);
|
||||||
|
gic.parseFixedValues(values[i++]);
|
||||||
|
gic.parseSetValues(values[i++]);
|
||||||
|
gic.parseNotes(values[i++]);
|
||||||
} catch(IllegalArgumentException e) {
|
} catch(IllegalArgumentException e) {
|
||||||
file.delete();
|
file.delete();
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -1,8 +1,164 @@
|
||||||
package tu_darmstadt.sudoku.controller.generator;
|
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.
|
* Created by Chris on 19.11.2015.
|
||||||
*/
|
*/
|
||||||
public class Generator {
|
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<GameCell> candidates = getListOfCandidates(workingBoard);
|
||||||
|
// choose one of them
|
||||||
|
GameCell chosen = candidates.get(random.nextInt(candidates.size()));
|
||||||
|
// get all possible values
|
||||||
|
List<Integer> 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<GameBoard> 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<Boolean>() {
|
||||||
|
@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<Integer> getPossibleValues(GameCell c) {
|
||||||
|
List<Integer> result = new LinkedList<>();
|
||||||
|
for(int i = 0; i < size; i++) {
|
||||||
|
if(c.getNotes()[i]) {
|
||||||
|
result.add(i+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<GameCell> getListOfCandidates(GameBoard gameBoard) {
|
||||||
|
final ArrayList<GameCell> candidates = new ArrayList<>();
|
||||||
|
|
||||||
|
gameBoard.actionOnCells(new ICellAction<ArrayList<GameCell>>() {
|
||||||
|
@Override
|
||||||
|
public ArrayList<GameCell> action(GameCell gc, ArrayList<GameCell> 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,9 +31,9 @@ public class GameInfoContainer {
|
||||||
}
|
}
|
||||||
public GameInfoContainer(int ID, GameDifficulty difficulty, Date lastTimePlayed, int timePlayed, GameType gameType, int[] fixedValues, int[] setValues, boolean[][] setNotes) {
|
public GameInfoContainer(int ID, GameDifficulty difficulty, Date lastTimePlayed, int timePlayed, GameType gameType, int[] fixedValues, int[] setValues, boolean[][] setNotes) {
|
||||||
this.ID = ID;
|
this.ID = ID;
|
||||||
|
this.timePlayed = timePlayed;
|
||||||
this.difficulty = difficulty;
|
this.difficulty = difficulty;
|
||||||
this.gameType = gameType;
|
this.gameType = gameType;
|
||||||
this.timePlayed = timePlayed;
|
|
||||||
this.lastTimePlayed = lastTimePlayed;
|
this.lastTimePlayed = lastTimePlayed;
|
||||||
this.fixedValues = fixedValues;
|
this.fixedValues = fixedValues;
|
||||||
this.setValues = setValues;
|
this.setValues = setValues;
|
||||||
|
@ -46,6 +46,36 @@ public class GameInfoContainer {
|
||||||
|
|
||||||
public void parseGameType(String s) {
|
public void parseGameType(String s) {
|
||||||
gameType = Enum.valueOf(GameType.class, s);
|
gameType = Enum.valueOf(GameType.class, s);
|
||||||
|
if(gameType == null) {
|
||||||
|
throw new IllegalArgumentException("GameInfoContainer: gameType could not be set.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTime() {
|
||||||
|
return timePlayed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void parseTime(String s) {
|
||||||
|
try {
|
||||||
|
this.timePlayed = Integer.valueOf(s);
|
||||||
|
} catch(NumberFormatException e) {
|
||||||
|
throw new IllegalArgumentException("GameInfoContainer: Can not parse time.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void parseDate(String s) {
|
||||||
|
try {
|
||||||
|
this.lastTimePlayed = new Date(Long.valueOf(s));
|
||||||
|
} catch(NumberFormatException e) {
|
||||||
|
throw new IllegalArgumentException("GameInfoContainer: LastTimePlayed Date can not be extracted.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void parseDifficulty(String s) {
|
||||||
|
difficulty = Enum.valueOf(GameDifficulty.class, s);
|
||||||
|
if(difficulty == null) {
|
||||||
|
throw new IllegalArgumentException("GameInfoContainer: difficulty could not be set.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void parseFixedValues(String s){
|
public void parseFixedValues(String s){
|
||||||
|
@ -127,10 +157,16 @@ public class GameInfoContainer {
|
||||||
|
|
||||||
public static String getGameInfo(GameController controller) {
|
public static String getGameInfo(GameController controller) {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
|
Date today = new Date();
|
||||||
// TODO add some game information
|
// TODO add some game information
|
||||||
sb.append(controller.getGameType().name());
|
sb.append(controller.getGameType().name());
|
||||||
sb.append("/");
|
sb.append("/");
|
||||||
|
sb.append(controller.getTime());
|
||||||
|
sb.append("/");
|
||||||
|
sb.append(today.getTime());
|
||||||
|
sb.append("/");
|
||||||
|
sb.append(controller.getDifficulty().name());
|
||||||
|
sb.append("/");
|
||||||
sb.append(getFixedCells(controller));
|
sb.append(getFixedCells(controller));
|
||||||
sb.append("/");
|
sb.append("/");
|
||||||
sb.append(getSetCells(controller));
|
sb.append(getSetCells(controller));
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package tu_darmstadt.sudoku.controller;
|
package tu_darmstadt.sudoku.controller.solver;
|
||||||
|
|
||||||
import android.graphics.Point;
|
import android.graphics.Point;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
@ -88,8 +88,7 @@ public class Solver {
|
||||||
|
|
||||||
checkSolvedCells(gameBoard);
|
checkSolvedCells(gameBoard);
|
||||||
|
|
||||||
String string = gameBoard.toString();
|
//String string = gameBoard.toString();
|
||||||
|
|
||||||
if(isDone(gameBoard)) {
|
if(isDone(gameBoard)) {
|
||||||
solutions.add(gameBoard);
|
solutions.add(gameBoard);
|
||||||
return true;
|
return true;
|
||||||
|
@ -98,6 +97,9 @@ public class Solver {
|
||||||
if(showPossibles(gameBoard))
|
if(showPossibles(gameBoard))
|
||||||
return solve(gameBoard);
|
return solve(gameBoard);
|
||||||
|
|
||||||
|
if(isImpossible(gameBoard))
|
||||||
|
return false;
|
||||||
|
|
||||||
if(searchHiddenSingles(gameBoard))
|
if(searchHiddenSingles(gameBoard))
|
||||||
return solve(gameBoard);
|
return solve(gameBoard);
|
||||||
|
|
||||||
|
@ -135,6 +137,11 @@ public class Solver {
|
||||||
|
|
||||||
result = solve(gameBoardCopy);
|
result = solve(gameBoardCopy);
|
||||||
|
|
||||||
|
if(solutions.size() > 1) {
|
||||||
|
// don't search for more than 1 solution
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
//if (result) {
|
//if (result) {
|
||||||
// stop after we found 1 solution
|
// stop after we found 1 solution
|
||||||
//return true;
|
//return true;
|
||||||
|
@ -152,6 +159,15 @@ public class Solver {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isImpossible(GameBoard gameBoard) {
|
||||||
|
return gameBoard.actionOnCells(new ICellAction<Boolean>() {
|
||||||
|
@Override
|
||||||
|
public Boolean action(GameCell gc, Boolean existing) {
|
||||||
|
return (gc.getNoteCount() == 0 && !gc.hasValue()) ? true : existing;
|
||||||
|
}
|
||||||
|
}, false);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean calculateNextPossibleStep() {
|
public boolean calculateNextPossibleStep() {
|
||||||
|
|
||||||
return false;
|
return false;
|
|
@ -71,25 +71,25 @@ public class GameCell implements Cloneable {
|
||||||
if(!isFixed()) {
|
if(!isFixed()) {
|
||||||
noteCount = notes[val - 1] ? noteCount - 1 : noteCount + 1;
|
noteCount = notes[val - 1] ? noteCount - 1 : noteCount + 1;
|
||||||
notes[val - 1] = !notes[val - 1];
|
notes[val - 1] = !notes[val - 1];
|
||||||
}
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void setNote(int val) {
|
public void setNote(int val) {
|
||||||
if(!isFixed()) {
|
if(!isFixed()) {
|
||||||
noteCount = notes[val - 1] ? noteCount : noteCount + 1;
|
noteCount = notes[val - 1] ? noteCount : noteCount + 1;
|
||||||
notes[val - 1] = true;
|
notes[val - 1] = true;
|
||||||
}
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void deleteNote(int val) {
|
public void deleteNote(int val) {
|
||||||
if(!isFixed()) {
|
if(!isFixed()) {
|
||||||
noteCount = notes[val - 1] ? noteCount - 1 : noteCount;
|
noteCount = notes[val - 1] ? noteCount - 1 : noteCount;
|
||||||
notes[val - 1] = false;
|
notes[val - 1] = false;
|
||||||
}
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public int getNoteCount() {
|
public int getNoteCount() {
|
||||||
return noteCount;
|
return noteCount;
|
||||||
|
|
|
@ -14,6 +14,7 @@ import android.support.v7.widget.Toolbar;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.widget.RatingBar;
|
import android.widget.RatingBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
|
@ -36,9 +37,7 @@ public class GameActivity extends AppCompatActivity implements NavigationView.On
|
||||||
SudokuFieldLayout layout;
|
SudokuFieldLayout layout;
|
||||||
SudokuKeyboardLayout keyboard;
|
SudokuKeyboardLayout keyboard;
|
||||||
SudokuSpecialButtonLayout specialButtonLayout;
|
SudokuSpecialButtonLayout specialButtonLayout;
|
||||||
Timer t = new Timer();
|
|
||||||
TextView timerView;
|
TextView timerView;
|
||||||
boolean isActive = true;
|
|
||||||
TextView viewName ;
|
TextView viewName ;
|
||||||
RatingBar ratingBar;
|
RatingBar ratingBar;
|
||||||
|
|
||||||
|
@ -84,7 +83,7 @@ public class GameActivity extends AppCompatActivity implements NavigationView.On
|
||||||
gameController.loadLevel(loadableGames.get(loadLevelID));
|
gameController.loadLevel(loadableGames.get(loadLevelID));
|
||||||
} else {
|
} else {
|
||||||
// load a new level
|
// load a new level
|
||||||
gameController.loadNewLevel(gameType, gameDifficulty);
|
gameController.loadNewLevel(gameType, GameDifficulty.getValidDifficultyList().get(gameDifficulty));
|
||||||
}
|
}
|
||||||
|
|
||||||
layout.setGame(gameController);
|
layout.setGame(gameController);
|
||||||
|
@ -141,12 +140,13 @@ public class GameActivity extends AppCompatActivity implements NavigationView.On
|
||||||
@Override
|
@Override
|
||||||
public void onPause(){
|
public void onPause(){
|
||||||
super.onPause();
|
super.onPause();
|
||||||
isActive = false;
|
gameController.saveGame(this);
|
||||||
|
gameController.pauseTimer();
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void onResume(){
|
public void onResume(){
|
||||||
super.onResume();
|
super.onResume();
|
||||||
isActive = true;
|
gameController.startTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -156,7 +156,6 @@ public class GameActivity extends AppCompatActivity implements NavigationView.On
|
||||||
if (drawer.isDrawerOpen(GravityCompat.START)) {
|
if (drawer.isDrawerOpen(GravityCompat.START)) {
|
||||||
drawer.closeDrawer(GravityCompat.START);
|
drawer.closeDrawer(GravityCompat.START);
|
||||||
} else {
|
} else {
|
||||||
gameController.saveGame(getBaseContext());
|
|
||||||
finish();
|
finish();
|
||||||
super.onBackPressed();
|
super.onBackPressed();
|
||||||
}
|
}
|
||||||
|
@ -181,7 +180,6 @@ public class GameActivity extends AppCompatActivity implements NavigationView.On
|
||||||
case R.id.nav_newgame:
|
case R.id.nav_newgame:
|
||||||
//create new game
|
//create new game
|
||||||
intent = new Intent(this, MainActivity.class);
|
intent = new Intent(this, MainActivity.class);
|
||||||
gameController.saveGame(getBaseContext());
|
|
||||||
finish();
|
finish();
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
break;
|
break;
|
||||||
|
@ -189,7 +187,6 @@ public class GameActivity extends AppCompatActivity implements NavigationView.On
|
||||||
case R.id.nav_continue:
|
case R.id.nav_continue:
|
||||||
//create new game
|
//create new game
|
||||||
intent = new Intent(this, LoadGameActivity.class);
|
intent = new Intent(this, LoadGameActivity.class);
|
||||||
gameController.saveGame(getBaseContext());
|
|
||||||
finish();
|
finish();
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
break;
|
break;
|
||||||
|
@ -197,8 +194,6 @@ public class GameActivity extends AppCompatActivity implements NavigationView.On
|
||||||
case R.id.menu_settings:
|
case R.id.menu_settings:
|
||||||
//open settings
|
//open settings
|
||||||
intent = new Intent(this,SettingsActivity.class);
|
intent = new Intent(this,SettingsActivity.class);
|
||||||
gameController.saveGame(getBaseContext());
|
|
||||||
finish();
|
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -211,8 +206,6 @@ public class GameActivity extends AppCompatActivity implements NavigationView.On
|
||||||
case R.id.menu_about:
|
case R.id.menu_about:
|
||||||
//open about page
|
//open about page
|
||||||
intent = new Intent(this,AboutActivity.class);
|
intent = new Intent(this,AboutActivity.class);
|
||||||
gameController.saveGame(getBaseContext());
|
|
||||||
finish();
|
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -231,6 +224,8 @@ public class GameActivity extends AppCompatActivity implements NavigationView.On
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSolved() {
|
public void onSolved() {
|
||||||
|
Toast t = Toast.makeText(this,"Congratulations you have solved the puzzle!", Toast.LENGTH_SHORT);
|
||||||
|
t.show();
|
||||||
// TODO: WE WON.. do something awesome :)
|
// TODO: WE WON.. do something awesome :)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -129,7 +129,7 @@ public class MainActivity extends AppCompatActivity {
|
||||||
break;
|
break;
|
||||||
case R.id.playButton:
|
case R.id.playButton:
|
||||||
GameType gameType = GameType.getValidGameTypes().get(mViewPager.getCurrentItem());
|
GameType gameType = GameType.getValidGameTypes().get(mViewPager.getCurrentItem());
|
||||||
int gameDifficulty = difficultyBar.getProgress();
|
int gameDifficulty = difficultyBar.getProgress()-1;
|
||||||
|
|
||||||
// save current setting for later
|
// save current setting for later
|
||||||
SharedPreferences.Editor editor = settings.edit();
|
SharedPreferences.Editor editor = settings.edit();
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="testMode"
|
android:text="@string/gametype_unspecified"
|
||||||
android:id="@+id/gameModeText"
|
android:id="@+id/gameModeText"
|
||||||
android:layout_weight="8"/>
|
android:layout_weight="8"/>
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
|
@ -39,13 +39,14 @@
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="lable"
|
android:text="@string/difficulty_easy"
|
||||||
android:layout_centerHorizontal="true"
|
android:layout_centerHorizontal="true"
|
||||||
android:id="@+id/difficultyText"
|
android:id="@+id/difficultyText"
|
||||||
/>
|
/>
|
||||||
<RatingBar
|
<RatingBar
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:numStars="3"
|
||||||
android:clickable="false"
|
android:clickable="false"
|
||||||
android:id="@+id/gameModeStar"
|
android:id="@+id/gameModeStar"
|
||||||
android:layout_centerHorizontal="true"
|
android:layout_centerHorizontal="true"
|
||||||
|
@ -56,7 +57,7 @@
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="test"
|
android:text="00:00:00"
|
||||||
android:layout_weight="2"
|
android:layout_weight="2"
|
||||||
android:id="@+id/timerView"
|
android:id="@+id/timerView"
|
||||||
android:gravity="right"
|
android:gravity="right"
|
||||||
|
|
|
@ -113,4 +113,19 @@ public class SolverTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void solveNotSolvableTest() {
|
||||||
|
controller.loadLevel(new GameInfoContainer(0, GameDifficulty.Easy, GameType.Default_6x6,
|
||||||
|
new int[]{1,2,0,0,0,6,
|
||||||
|
4,0,6,1,3,0,
|
||||||
|
0,0,2,3,0,5,
|
||||||
|
0,4,0,0,1,0,
|
||||||
|
0,5,0,2,0,0,
|
||||||
|
0,3,0,5,0,1}, null,null));
|
||||||
|
|
||||||
|
LinkedList<GameBoard> result = controller.solve();
|
||||||
|
|
||||||
|
assertEquals(0, result.size());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue