Updated Model, Solver and GameController.
This commit is contained in:
parent
b9dcf4e2d2
commit
c7402d1196
6 changed files with 163 additions and 100 deletions
|
@ -5,7 +5,7 @@
|
|||
<GradleProjectSettings>
|
||||
<option name="distributionType" value="LOCAL" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="gradleHome" value="D:\Program Files\Android\Android Studio\gradle\gradle-2.4" />
|
||||
<option name="gradleHome" value="C:\Program Files\Android\Android Studio\gradle\gradle-2.4" />
|
||||
<option name="gradleJvm" value="1.8" />
|
||||
<option name="modules">
|
||||
<set>
|
||||
|
|
|
@ -17,6 +17,8 @@ import tu_darmstadt.sudoku.game.ICellAction;
|
|||
public class GameController {
|
||||
|
||||
private int size;
|
||||
private int sectionHeight;
|
||||
private int sectionWidth;
|
||||
private GameField gameField;
|
||||
private CellConflictList errorList = new CellConflictList();
|
||||
private GameSettings settings = new GameSettings();
|
||||
|
@ -30,8 +32,8 @@ public class GameController {
|
|||
}
|
||||
|
||||
public GameController(GameType type) {
|
||||
gameField = new GameField(type);
|
||||
size = gameField.getSize();
|
||||
setGameType(type);
|
||||
gameField = new GameField(size, sectionHeight, sectionWidth);
|
||||
}
|
||||
|
||||
/*public boolean loadLevel(GameField level) {
|
||||
|
@ -40,7 +42,41 @@ public class GameController {
|
|||
}
|
||||
}*/
|
||||
|
||||
private void setGameType(GameType type) {
|
||||
switch(type) {
|
||||
case Default_9x9:
|
||||
this.size = 9;
|
||||
this.sectionHeight = 3;
|
||||
this.sectionWidth = 3;
|
||||
break;
|
||||
case Default_12x12:
|
||||
this.size = 12;
|
||||
this.sectionHeight = 3;
|
||||
this.sectionWidth = 4;
|
||||
break;
|
||||
case Default_6x6:
|
||||
this.size = 6;
|
||||
this.sectionHeight = 2;
|
||||
this.sectionWidth = 3;
|
||||
break;
|
||||
case Unspecified:
|
||||
default:
|
||||
this.size = 1;
|
||||
this.sectionHeight = 1;
|
||||
this.sectionWidth = 1;
|
||||
throw new IllegalArgumentException("GameType can not be unspecified.");
|
||||
}
|
||||
}
|
||||
|
||||
/** Use with care.
|
||||
*/
|
||||
public GameCell getGameCell(int row, int col) {
|
||||
return gameField.getCell(row,col);
|
||||
}
|
||||
|
||||
public boolean isSolved() {
|
||||
return gameField.isSolved(new LinkedList<CellConflict>());
|
||||
}
|
||||
|
||||
public void setValue(int row, int col, int value) {
|
||||
GameCell cell = gameField.getCell(row, col);
|
||||
|
@ -58,8 +94,6 @@ public class GameController {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void deleteNotes(List<GameCell> updateList, int value) {
|
||||
for(GameCell c : updateList) {
|
||||
c.deleteNote(value);
|
||||
|
@ -85,49 +119,6 @@ public class GameController {
|
|||
return 0 < val && val <= size;
|
||||
}
|
||||
|
||||
public boolean isSolved() {
|
||||
boolean solved = true;
|
||||
|
||||
// this will automatically build the CellConflict list. so we reset it before we call the checks
|
||||
errorList = new CellConflictList();
|
||||
|
||||
for(int i = 0; i < size; i++) {
|
||||
if(!checkList(gameField.getRow(i))) solved = false;
|
||||
if(!checkList(gameField.getColumn(i))) solved = false;
|
||||
if(!checkList(gameField.getSection(i))) solved = false;
|
||||
}
|
||||
return solved;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the given list if every number occurs only once.
|
||||
* This method will automatically build the errorList.
|
||||
* @param list the list of {@link GameCell}s that is supposed to be tested.
|
||||
* @return true if every cell has a value and every value occurs only once
|
||||
*/
|
||||
private boolean checkList(List<GameCell> list) {
|
||||
boolean isNothingEmpty = true;
|
||||
CellConflict lastFound = null;
|
||||
|
||||
for(int i = 0; i < list.size(); i++) {
|
||||
for(int j = i + 1; j < list.size(); j++) {
|
||||
GameCell c1 = list.get(i);
|
||||
GameCell c2 = list.get(j);
|
||||
|
||||
if(c1.getValue() == 0 || c2.getValue() == 0) {
|
||||
isNothingEmpty = false;
|
||||
}
|
||||
|
||||
// Same value in one set should not exist
|
||||
if(c1.getValue() != 0 && c1.getValue() == c2.getValue()) {
|
||||
// we found an error..
|
||||
errorList.add(new CellConflict(c1, c2));
|
||||
}
|
||||
}
|
||||
}
|
||||
return isNothingEmpty ? (errorList.size() == 0) : false;
|
||||
}
|
||||
|
||||
public List<CellConflict> getErrorList() {
|
||||
return errorList;
|
||||
}
|
||||
|
|
|
@ -106,6 +106,10 @@ public class GameCell implements Cloneable {
|
|||
fixed = b;
|
||||
}
|
||||
|
||||
public boolean hasValue() {
|
||||
return value > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if(!(other instanceof GameCell)) return false;
|
||||
|
|
|
@ -2,6 +2,7 @@ package tu_darmstadt.sudoku.game;
|
|||
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Christopher Beckmann on 06.11.2015.
|
||||
|
@ -12,21 +13,21 @@ public class GameField implements Cloneable {
|
|||
private int sectionHeight;
|
||||
private int sectionWidth;
|
||||
//private List additionalSections
|
||||
private CellConflictList errorList = new CellConflictList();
|
||||
private int size;
|
||||
private GameCell[][] field;
|
||||
|
||||
public GameField() {
|
||||
this(GameType.Default_9x9);
|
||||
}
|
||||
|
||||
public GameField(GameType type) {
|
||||
setGameType(type);
|
||||
public GameField(int size, int sectionHeight, int sectionWidth) {
|
||||
this.sectionHeight = sectionHeight;
|
||||
this.sectionWidth = sectionWidth;
|
||||
this.size = size;
|
||||
|
||||
field = new GameCell[size][size];
|
||||
}
|
||||
|
||||
|
||||
public void initCells(int[][] level) {
|
||||
// TODO: this is a placeholder, because we don't have real levels yet.
|
||||
int[][] level = {{ 5, 0, 1, 9, 0, 0, 0, 0, 0 },
|
||||
int[][] placeholder = {{ 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 },
|
||||
|
||||
|
@ -38,30 +39,10 @@ public class GameField implements Cloneable {
|
|||
{ 6, 4, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 7, 0, 0, 0, 1, 0, 3, 0, 5 }};
|
||||
|
||||
initCells(level);
|
||||
}
|
||||
|
||||
private void setGameType(GameType type) {
|
||||
switch(type) {
|
||||
case Default_9x9:
|
||||
this.size = 9;
|
||||
this.sectionHeight = 3;
|
||||
this.sectionWidth = 3;
|
||||
break;
|
||||
case Unspecified:
|
||||
default:
|
||||
this.size = 1;
|
||||
this.sectionHeight = 1;
|
||||
this.sectionWidth = 1;
|
||||
throw new IllegalArgumentException("GameType can not be unspecified.");
|
||||
}
|
||||
}
|
||||
|
||||
public void initCells(int[][] level) {
|
||||
// Initit the game field
|
||||
for(int i = 0; i < size; i++) {
|
||||
for(int j = 0; j < size; j++) {
|
||||
field[i][j] = new GameCell(i,j,size,level[i][j]);
|
||||
field[i][j] = new GameCell(i,j,size,placeholder[i][j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -102,7 +83,8 @@ public class GameField implements Cloneable {
|
|||
existing.add(gc);
|
||||
}
|
||||
return existing;
|
||||
}}, new LinkedList<GameCell>());
|
||||
}
|
||||
}, new LinkedList<GameCell>());
|
||||
}
|
||||
|
||||
public LinkedList<GameCell> getSection(int row, int col) {
|
||||
|
@ -123,6 +105,55 @@ public class GameField implements Cloneable {
|
|||
return existing;
|
||||
}
|
||||
|
||||
public boolean isSolved(final List<CellConflict> errorList) {
|
||||
boolean solved = true;
|
||||
|
||||
if(errorList == null) {
|
||||
throw new IllegalArgumentException("ErrorList may not be null.");
|
||||
}
|
||||
errorList.clear();
|
||||
|
||||
// this will automatically build the CellConflict list. so we reset it before we call the checks
|
||||
|
||||
for(int i = 0; i < size; i++) {
|
||||
if(!checkList(getRow(i), errorList)) solved = false;
|
||||
if(!checkList(getColumn(i), errorList)) solved = false;
|
||||
if(!checkList(getSection(i), errorList)) solved = false;
|
||||
}
|
||||
return solved;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the given list if every number occurs only once.
|
||||
* This method will automatically build the errorList.
|
||||
* @param list the list of {@link GameCell}s that is supposed to be tested.
|
||||
* @return true if every cell has a value and every value occurs only once
|
||||
*/
|
||||
private boolean checkList(final List<GameCell> list, final List<CellConflict> errorList) {
|
||||
boolean isNothingEmpty = true;
|
||||
CellConflict lastFound = null;
|
||||
|
||||
for(int i = 0; i < list.size(); i++) {
|
||||
for(int j = i + 1; j < list.size(); j++) {
|
||||
GameCell c1 = list.get(i);
|
||||
GameCell c2 = list.get(j);
|
||||
|
||||
if(c1.getValue() == 0 || c2.getValue() == 0) {
|
||||
isNothingEmpty = false;
|
||||
}
|
||||
|
||||
// Same value in one set should not exist
|
||||
if(c1.getValue() != 0 && c1.getValue() == c2.getValue()) {
|
||||
// we found an error..
|
||||
if(errorList != null) {
|
||||
errorList.add(new CellConflict(c1, c2));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return isNothingEmpty ? (errorList.size() == 0) : false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GameField clone() throws CloneNotSupportedException {
|
||||
GameField clone = (GameField) super.clone();
|
||||
|
|
|
@ -7,7 +7,7 @@ public enum GameType {
|
|||
Unspecified,
|
||||
Default_9x9,
|
||||
Default_9x6,
|
||||
Default_12x9,
|
||||
Default_12x12,
|
||||
Default_6x6
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
package tu_darmstadt.sudoku.game.solver;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
import tu_darmstadt.sudoku.game.CellConflict;
|
||||
import tu_darmstadt.sudoku.game.GameCell;
|
||||
import tu_darmstadt.sudoku.game.GameField;
|
||||
import tu_darmstadt.sudoku.game.ICellAction;
|
||||
|
@ -25,8 +28,12 @@ public class Default9x9Solver implements ISolver {
|
|||
|
||||
public boolean solve() {
|
||||
|
||||
if(gameField.isSolved(new LinkedList<CellConflict>())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
checkSolvedCells();
|
||||
/*
|
||||
|
||||
if(showPossibles()) return solve();
|
||||
|
||||
if(searchHiddenSingles()) return solve();
|
||||
|
@ -41,15 +48,7 @@ public class Default9x9Solver implements ISolver {
|
|||
|
||||
if(searchBoxLineReduction()) return solve();
|
||||
|
||||
selectBestCell();
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -61,6 +60,44 @@ public class Default9x9Solver implements ISolver {
|
|||
return gameField;
|
||||
}
|
||||
|
||||
public boolean showPossibles() {
|
||||
LinkedList<GameCell> list = new LinkedList<GameCell>();
|
||||
for(int i = 0; i < gameField.getSize(); i++) {
|
||||
for(int j = 0; j < gameField.getSize(); j++) {
|
||||
GameCell gc = gameField.getCell(i,j);
|
||||
if(!gc.hasValue()) {
|
||||
list.clear();
|
||||
list.addAll(gameField.getRow(i));
|
||||
list.addAll(gameField.getColumn(j));
|
||||
list.addAll(gameField.getSection(i,j));
|
||||
for(int k = 0; k < gameField.getSize(); k++) {
|
||||
for(GameCell c : list) {
|
||||
gc.deleteNote(c.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean searchNakedPairsTriples() {
|
||||
return false;
|
||||
}
|
||||
public boolean searchHiddenPairsTriples() {
|
||||
return false;
|
||||
}
|
||||
public boolean searchNakedQuads() {
|
||||
return false;
|
||||
}
|
||||
public boolean searchPointingPairs() {
|
||||
return false;
|
||||
}
|
||||
public boolean searchBoxLineReduction() {
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean checkSolvedCells() {
|
||||
return gameField.actionOnCells(new ICellAction<Boolean>() {
|
||||
@Override
|
||||
|
|
Loading…
Reference in a new issue