Added Game Difficulty Enum. The Difficulty Selection now checks the enum for valid difficulty types and sets itself automaticly. Added IModelChangeListeners to the GameCells.
This commit is contained in:
parent
f1ef933963
commit
02419e1028
13 changed files with 185 additions and 21 deletions
|
@ -11,14 +11,16 @@ import tu_darmstadt.sudoku.game.CellConflictList;
|
|||
import tu_darmstadt.sudoku.game.GameBoard;
|
||||
import tu_darmstadt.sudoku.game.GameCell;
|
||||
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.IModelChangedListener;
|
||||
import tu_darmstadt.sudoku.game.solver.Solver;
|
||||
|
||||
/**
|
||||
* Created by Chris on 06.11.2015.
|
||||
*/
|
||||
public class GameController {
|
||||
public class GameController implements IModelChangedListener {
|
||||
|
||||
private int size;
|
||||
private int sectionHeight;
|
||||
|
@ -59,7 +61,7 @@ public class GameController {
|
|||
public void loadNewLevel(GameType type, int difficulty) {
|
||||
switch(type) {
|
||||
case Default_6x6:
|
||||
loadLevel(new GameInfoContainer(1, GameType.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,
|
||||
|
@ -68,7 +70,7 @@ public class GameController {
|
|||
0,3,0,5,0,1}, null,null));
|
||||
break;
|
||||
case Default_12x12:
|
||||
loadLevel(new GameInfoContainer(2, GameType.Default_12x12,
|
||||
loadLevel(new GameInfoContainer(2, GameDifficulty.Easy, 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,
|
||||
|
@ -86,7 +88,7 @@ public class GameController {
|
|||
case Default_9x9:
|
||||
case Unspecified:
|
||||
default:
|
||||
loadLevel(new GameInfoContainer(3, GameType.Default_9x9,
|
||||
loadLevel(new GameInfoContainer(3, GameDifficulty.Easy, 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,
|
||||
|
@ -234,12 +236,7 @@ public class GameController {
|
|||
}
|
||||
|
||||
public boolean checkIfBoardIsFilled() {
|
||||
//if(gameBoard.getEmptyCellCount() == 0) {
|
||||
// TODO: board is filled. check it for errors.
|
||||
|
||||
//return true;
|
||||
//}
|
||||
return false;
|
||||
return gameBoard.isFilled();
|
||||
}
|
||||
|
||||
public void saveGame(Context context) {
|
||||
|
@ -395,6 +392,19 @@ public class GameController {
|
|||
return sectionWidth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onModelChange(GameCell c) {
|
||||
if(gameBoard.isFilled()) {
|
||||
List<CellConflict> errorList = new LinkedList<>();
|
||||
if(gameBoard.isSolved(errorList)) {
|
||||
// TODO: WE WON! :D
|
||||
} else {
|
||||
// TODO: errorList now holds all the errors
|
||||
// TODO: display errors .. notify some view?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// public void notifyListeners() {
|
||||
// for(IModelChangeListener l : listeners) {
|
||||
// l.onModelChanged();
|
||||
|
|
|
@ -8,7 +8,10 @@ public enum Symbol {
|
|||
SaveFormat(new String[] {"1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "O", "P"}),
|
||||
Default(new String[] {"1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N"}),
|
||||
Roman(new String[] {"I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X", "XI", "XII", "XIII", "XIV", "XV", "XVI", "XVII", "XVIII", "XIX", "XX", "XXI", "XXII"}),
|
||||
Fancy(new String[] {"♪", "♫", "☼", "♥", "♦", "♣", "♠", "•", "○", "A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N" });
|
||||
Fancy(new String[] {"♪", "♫", "☼", "♥", "♦", "♣", "♠", "•", "○", "A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N" }),
|
||||
Chinese(new String[] {"一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二", "十三", "十四", "十五", "十六" }),
|
||||
Greek(new String[] { "α", "β", "γ", "δ", "ε", "ϛ", "ζ", "η", "θ", "ι", "ια", "ιβ", "ιγ", "ιδ", "ιε", "ιϛ", "ιζ", "ιη", "ιθ", "κ"}),
|
||||
Indian(new String[] { "१", "२", "३", "४", "५", "६", "७", "८", "९", "१०", "११", "१२", "१३", "१४", "१५", "१६", "१७"});
|
||||
|
||||
private String[] map;
|
||||
|
||||
|
@ -26,5 +29,4 @@ public enum Symbol {
|
|||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,9 +2,12 @@ package tu_darmstadt.sudoku.controller.helper;
|
|||
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import tu_darmstadt.sudoku.controller.GameController;
|
||||
import tu_darmstadt.sudoku.controller.Symbol;
|
||||
import tu_darmstadt.sudoku.game.GameCell;
|
||||
import tu_darmstadt.sudoku.game.GameDifficulty;
|
||||
import tu_darmstadt.sudoku.game.GameType;
|
||||
import tu_darmstadt.sudoku.game.ICellAction;
|
||||
|
||||
|
@ -15,16 +18,23 @@ public class GameInfoContainer {
|
|||
|
||||
GameType gameType;
|
||||
int ID;
|
||||
int time;
|
||||
int difficulty;
|
||||
int timePlayed;
|
||||
Date lastTimePlayed;
|
||||
GameDifficulty difficulty;
|
||||
int[] fixedValues;
|
||||
int[] setValues;
|
||||
boolean[][] setNotes;
|
||||
|
||||
public GameInfoContainer() {}
|
||||
public GameInfoContainer(int ID, GameType gameType, int[] fixedValues, int[] setValues, boolean[][] setNotes) {
|
||||
public GameInfoContainer(int ID, GameDifficulty difficulty, GameType gameType, int[] fixedValues, int[] setValues, boolean[][] setNotes) {
|
||||
this(ID, difficulty, new Date(), 0, gameType, fixedValues, setValues, setNotes);
|
||||
}
|
||||
public GameInfoContainer(int ID, GameDifficulty difficulty, Date lastTimePlayed, int timePlayed, GameType gameType, int[] fixedValues, int[] setValues, boolean[][] setNotes) {
|
||||
this.ID = ID;
|
||||
this.difficulty = difficulty;
|
||||
this.gameType = gameType;
|
||||
this.timePlayed = timePlayed;
|
||||
this.lastTimePlayed = lastTimePlayed;
|
||||
this.fixedValues = fixedValues;
|
||||
this.setValues = setValues;
|
||||
this.setNotes = setNotes;
|
||||
|
|
|
@ -15,6 +15,7 @@ public class GameBoard implements Cloneable {
|
|||
//private List additionalSections
|
||||
private int size;
|
||||
private GameCell[][] field;
|
||||
private List<IModelChangedListener> modelChangedListeners = new LinkedList<>();
|
||||
|
||||
public GameBoard(int size, int sectionHeight, int sectionWidth) {
|
||||
this.sectionHeight = sectionHeight;
|
||||
|
@ -199,4 +200,40 @@ public class GameBoard implements Cloneable {
|
|||
return sb.toString();
|
||||
}
|
||||
|
||||
public boolean isFilled() {
|
||||
return actionOnCells(new ICellAction<Boolean>() {
|
||||
@Override
|
||||
public Boolean action(GameCell gc, Boolean existing) {
|
||||
return gc.hasValue() ? existing : false;
|
||||
}
|
||||
}, true);
|
||||
}
|
||||
|
||||
public void registerOnModelChangeListener(final IModelChangedListener listener) {
|
||||
if(!modelChangedListeners.contains(listener)) {
|
||||
actionOnCells(new ICellAction<Boolean>() {
|
||||
|
||||
@Override
|
||||
public Boolean action(GameCell gc, Boolean existing) {
|
||||
gc.registerOnModelChangeListener(listener);
|
||||
return existing;
|
||||
}
|
||||
}, false);
|
||||
modelChangedListeners.add(listener);
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteOnModelChangeListener(final IModelChangedListener listener) {
|
||||
if(modelChangedListeners.contains(listener)) {
|
||||
actionOnCells(new ICellAction<Boolean>() {
|
||||
|
||||
@Override
|
||||
public Boolean action(GameCell gc, Boolean existing) {
|
||||
gc.removeOnModelChangeListener(listener);
|
||||
return existing;
|
||||
}
|
||||
}, false);
|
||||
modelChangedListeners.remove(listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package tu_darmstadt.sudoku.game;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Chris on 06.11.2015.
|
||||
|
@ -14,6 +16,7 @@ public class GameCell implements Cloneable {
|
|||
private int noteCount = 0;
|
||||
private boolean notes[];
|
||||
private int size = 0;
|
||||
private List<IModelChangedListener> modelChangedListeners = new LinkedList<IModelChangedListener>();
|
||||
|
||||
public GameCell(int row, int col, int size) {
|
||||
this(row,col,size,0);
|
||||
|
@ -43,6 +46,7 @@ public class GameCell implements Cloneable {
|
|||
public void setValue(int val) {
|
||||
deleteNotes();
|
||||
value = val;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
|
@ -66,6 +70,7 @@ public class GameCell implements Cloneable {
|
|||
noteCount = notes[val - 1] ? noteCount - 1 : noteCount + 1;
|
||||
notes[val - 1] = !notes[val - 1];
|
||||
}
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
public void setNote(int val) {
|
||||
|
@ -73,6 +78,7 @@ public class GameCell implements Cloneable {
|
|||
noteCount = notes[val - 1] ? noteCount : noteCount + 1;
|
||||
notes[val - 1] = true;
|
||||
}
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
public void deleteNote(int val) {
|
||||
|
@ -80,6 +86,7 @@ public class GameCell implements Cloneable {
|
|||
noteCount = notes[val - 1] ? noteCount - 1 : noteCount;
|
||||
notes[val - 1] = false;
|
||||
}
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
public int getNoteCount() {
|
||||
|
@ -96,6 +103,7 @@ public class GameCell implements Cloneable {
|
|||
public void deleteNotes() {
|
||||
noteCount = 0;
|
||||
notes = new boolean[size];
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
public boolean isFixed() {
|
||||
|
@ -164,7 +172,26 @@ public class GameCell implements Cloneable {
|
|||
@Override
|
||||
public GameCell clone() throws CloneNotSupportedException {
|
||||
GameCell clone = (GameCell) super.clone();
|
||||
clone.modelChangedListeners = new LinkedList<IModelChangedListener>();
|
||||
clone.notes = (notes == null) ? null : Arrays.copyOf(notes, notes.length);
|
||||
return clone;
|
||||
}
|
||||
|
||||
public void registerOnModelChangeListener(IModelChangedListener listener) {
|
||||
if(!modelChangedListeners.contains(listener)) {
|
||||
modelChangedListeners.add(listener);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeOnModelChangeListener(IModelChangedListener listener) {
|
||||
if(modelChangedListeners.contains(listener)) {
|
||||
modelChangedListeners.remove(listener);
|
||||
}
|
||||
}
|
||||
|
||||
public void notifyListeners() {
|
||||
for(IModelChangedListener m : modelChangedListeners) {
|
||||
m.onModelChange(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
package tu_darmstadt.sudoku.game;
|
||||
|
||||
import android.support.annotation.StringRes;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
import tu_darmstadt.sudoku.ui.view.R;
|
||||
|
||||
/**
|
||||
* Created by Chris on 18.11.2015.
|
||||
*/
|
||||
public enum GameDifficulty {
|
||||
|
||||
Easy(R.string.difficulty_easy),
|
||||
Moderate(R.string.difficulty_moderate),
|
||||
Hard(R.string.difficulty_hard);
|
||||
|
||||
private int resID;
|
||||
|
||||
GameDifficulty(@StringRes int resID) {
|
||||
//getResources().getString(resID);
|
||||
this.resID = resID;
|
||||
}
|
||||
|
||||
public int getStringResID() {
|
||||
return resID;
|
||||
}
|
||||
|
||||
public static LinkedList<GameDifficulty> getValidDifficultyList() {
|
||||
LinkedList<GameDifficulty> validList = new LinkedList<>();
|
||||
validList.add(Easy);
|
||||
validList.add(Moderate);
|
||||
validList.add(Hard);
|
||||
return validList;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package tu_darmstadt.sudoku.game;
|
||||
|
||||
/**
|
||||
* Created by Chris on 19.11.2015.
|
||||
*/
|
||||
public interface IModelChangedListener {
|
||||
public void onModelChange(GameCell c);
|
||||
}
|
|
@ -21,16 +21,19 @@ import android.widget.ImageView;
|
|||
import android.widget.RatingBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import tu_darmstadt.sudoku.controller.SaveLoadController;
|
||||
import tu_darmstadt.sudoku.controller.helper.GameInfoContainer;
|
||||
import tu_darmstadt.sudoku.game.GameDifficulty;
|
||||
import tu_darmstadt.sudoku.game.GameType;
|
||||
import tu_darmstadt.sudoku.ui.view.R;
|
||||
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
|
||||
RatingBar difficultyBar;
|
||||
TextView difficultyText;
|
||||
SharedPreferences settings;
|
||||
|
||||
/**
|
||||
|
@ -76,6 +79,19 @@ public class MainActivity extends AppCompatActivity {
|
|||
|
||||
// Set the difficulty Slider to whatever was chosen the last time
|
||||
difficultyBar = (RatingBar)findViewById(R.id.difficultyBar);
|
||||
difficultyText = (TextView) findViewById(R.id.difficultyText);
|
||||
final LinkedList<GameDifficulty> difficultyList = GameDifficulty.getValidDifficultyList();
|
||||
difficultyBar.setNumStars(difficultyList.size());
|
||||
difficultyBar.setMax(difficultyList.size());
|
||||
difficultyBar.setOnRatingBarChangeListener(new RatingBar.OnRatingBarChangeListener() {
|
||||
@Override
|
||||
public void onRatingChanged(RatingBar ratingBar, float rating, boolean fromUser) {
|
||||
if (rating < 1) {
|
||||
ratingBar.setRating(1);
|
||||
}
|
||||
difficultyText.setText(getString(difficultyList.get((int)ratingBar.getRating()-1).getStringResID()));
|
||||
}
|
||||
});
|
||||
int lastChosenDifficulty = settings.getInt("lastChosenDifficulty", 1);
|
||||
difficultyBar.setProgress(lastChosenDifficulty);
|
||||
|
||||
|
|
|
@ -61,6 +61,12 @@
|
|||
android:gravity="center_horizontal"
|
||||
style="?android:buttonBarStyle">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/difficultyText"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:text="@string/difficulty_easy"
|
||||
android:textSize="25dp"/>
|
||||
|
||||
<RatingBar
|
||||
android:layout_width="wrap_content"
|
||||
|
|
|
@ -29,4 +29,9 @@
|
|||
<!-- New Game -->
|
||||
<string name="start_game">Spiel starten</string>
|
||||
|
||||
<!-- ###Difficulty### -->
|
||||
<string name="difficulty_easy">Leicht</string>
|
||||
<string name="difficulty_moderate">Normal</string>
|
||||
<string name="difficulty_hard">Schwer</string>
|
||||
|
||||
</resources>
|
|
@ -36,7 +36,6 @@
|
|||
<string name="pref_automatic_note_deletion">Note deletion</string>
|
||||
<string name="pref_automatic_note_deletion_summary">Automatically remove notes when setting values on connected cells</string>
|
||||
|
||||
|
||||
<!-- ###ABOUT### -->
|
||||
<string name="app_name_long">Privacy friendly Sudoku</string>
|
||||
<string name="version_number">v0.9</string>
|
||||
|
@ -47,4 +46,9 @@
|
|||
<string name="more_info">More information can be found on:</string>
|
||||
<string name="url"><a href="https://www.secuso.informatik.tu-darmstadt.de/en/research/results/">https://www.secuso.org</a></string>
|
||||
|
||||
<!-- ###Difficulty### -->
|
||||
<string name="difficulty_easy">Easy</string>
|
||||
<string name="difficulty_moderate">Moderate</string>
|
||||
<string name="difficulty_hard">Hard</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -4,6 +4,7 @@ import org.junit.Before;
|
|||
import org.junit.Test;
|
||||
|
||||
import tu_darmstadt.sudoku.controller.helper.GameInfoContainer;
|
||||
import tu_darmstadt.sudoku.game.GameDifficulty;
|
||||
import tu_darmstadt.sudoku.game.GameType;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
@ -19,7 +20,7 @@ public class GameControllerTest {
|
|||
@Before
|
||||
public void init() {
|
||||
controller = new GameController();
|
||||
controller.loadLevel(new GameInfoContainer(3, GameType.Default_9x9,
|
||||
controller.loadLevel(new GameInfoContainer(3, GameDifficulty.Easy, 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,
|
||||
|
@ -31,7 +32,7 @@ public class GameControllerTest {
|
|||
7, 0, 0, 0, 1, 0, 3, 0, 5}
|
||||
, null, null));
|
||||
controller2 = new GameController();
|
||||
controller2.loadLevel(new GameInfoContainer(2, GameType.Default_12x12,
|
||||
controller2.loadLevel(new GameInfoContainer(2, GameDifficulty.Easy, 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,
|
||||
|
|
|
@ -10,6 +10,7 @@ import java.util.LinkedList;
|
|||
import tu_darmstadt.sudoku.controller.GameController;
|
||||
import tu_darmstadt.sudoku.controller.helper.GameInfoContainer;
|
||||
import tu_darmstadt.sudoku.game.GameBoard;
|
||||
import tu_darmstadt.sudoku.game.GameDifficulty;
|
||||
import tu_darmstadt.sudoku.game.GameType;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
|
@ -24,7 +25,7 @@ public class SolverTest {
|
|||
@Before
|
||||
public void init() {
|
||||
controller = new GameController();
|
||||
controller.loadLevel(new GameInfoContainer(0, GameType.Default_9x9,
|
||||
controller.loadLevel(new GameInfoContainer(0, GameDifficulty.Easy ,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,
|
||||
|
@ -62,7 +63,7 @@ public class SolverTest {
|
|||
|
||||
@Test
|
||||
public void solveSingleSolution2() {
|
||||
controller.loadLevel(new GameInfoContainer(0, GameType.Default_9x9,
|
||||
controller.loadLevel(new GameInfoContainer(0, GameDifficulty.Easy, 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));
|
||||
|
||||
|
@ -85,7 +86,7 @@ public class SolverTest {
|
|||
|
||||
@Test
|
||||
public void solveMultipleSolutions1() {
|
||||
controller.loadLevel(new GameInfoContainer(0, GameType.Default_6x6,
|
||||
controller.loadLevel(new GameInfoContainer(0, 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,
|
||||
|
|
Loading…
Reference in a new issue