diff --git a/app/src/main/java/tu_darmstadt/sudoku/controller/QQWingController.java b/app/src/main/java/tu_darmstadt/sudoku/controller/QQWingController.java index 3230d10..30e612b 100644 --- a/app/src/main/java/tu_darmstadt/sudoku/controller/QQWingController.java +++ b/app/src/main/java/tu_darmstadt/sudoku/controller/QQWingController.java @@ -20,8 +20,6 @@ import tu_darmstadt.sudoku.game.GameType; */ public class QQWingController { - private static final String NL = System.getProperties().getProperty("line.separator"); - final QQWingOptions opts = new QQWingOptions(); private int[] level; @@ -30,11 +28,12 @@ public class QQWingController { private boolean solveImpossible = false; public int[] generate(GameType type, GameDifficulty difficulty) { - // TODO: GameType options. opts.gameDifficulty = difficulty; opts.action = Action.GENERATE; + opts.printSolution = false; opts.threads = Runtime.getRuntime().availableProcessors(); - doAction(type); + opts.gameType = type; + doAction(); return generated; } @@ -54,7 +53,8 @@ public class QQWingController { opts.action = Action.SOLVE; opts.printSolution = true; opts.threads = 1; - doAction(gameBoard.getGameType()); + opts.gameType = gameBoard.getGameType(); + doAction(); if(solveImpossible) { // TODO: do something else. @@ -62,11 +62,10 @@ public class QQWingController { return solution; } - private void doAction(final GameType gameType) { + private void doAction() { // The number of puzzles solved or generated. final AtomicInteger puzzleCount = new AtomicInteger(0); final AtomicBoolean done = new AtomicBoolean(false); - final AtomicIntegerArray result = new AtomicIntegerArray(new int[gameType.getSize()*gameType.getSize()]); Thread[] threads = new Thread[opts.threads]; for (int threadCount = 0; threadCount < threads.length; threadCount++) { @@ -78,7 +77,7 @@ public class QQWingController { private QQWing ss = createQQWing(); private QQWing createQQWing() { - QQWing ss = new QQWing(gameType); + QQWing ss = new QQWing(opts.gameType, opts.gameDifficulty); ss.setRecordHistory(opts.printHistory || opts.printInstructions || opts.printStats || opts.gameDifficulty != GameDifficulty.Unspecified); ss.setLogHistory(opts.logHistory); ss.setPrintStyle(opts.printStyle); @@ -94,15 +93,11 @@ public class QQWingController { // until we have generated the specified number. while (!done.get()) { - // iff something has been printed for this - // particular puzzle - StringBuilder output = new StringBuilder(); - // Record whether the puzzle was possible or // not, // so that we don't try to solve impossible // givens. - boolean havePuzzle = false; + boolean havePuzzle; if (opts.action == Action.GENERATE) { // Generate a puzzle @@ -135,9 +130,9 @@ public class QQWingController { // Count the solutions if requested. // (Must be done before solving, as it would // mess up the stats.) - if (opts.countSolutions) { - solutions = ss.countSolutions(); - } + //if (opts.countSolutions) { + // solutions = ss.countSolutions(); + //} // Solve the puzzle if (opts.printSolution || opts.printHistory || opts.printStats || opts.printInstructions || opts.gameDifficulty != GameDifficulty.Unspecified) { @@ -148,22 +143,9 @@ public class QQWingController { // Bail out if it didn't meet the gameDifficulty // standards for generation if (opts.action == Action.GENERATE) { - if (opts.gameDifficulty != GameDifficulty.Unspecified && opts.gameDifficulty != ss.getDifficulty()) { - havePuzzle = false; - // check if other threads have - // finished the job - if (puzzleCount.get() >= opts.numberToGenerate) { - done.set(true); - generated = ss.getPuzzle(); - } - } else { - int numDone = puzzleCount.incrementAndGet(); - if (numDone >= opts.numberToGenerate) { - done.set(true); - generated = ss.getPuzzle(); - } - if (numDone > opts.numberToGenerate) - havePuzzle = false; + if (opts.gameDifficulty != GameDifficulty.Unspecified && opts.gameDifficulty == ss.getDifficulty()) { + done.set(true); + generated = ss.getPuzzle(); } } } @@ -202,6 +184,7 @@ public class QQWingController { int numberToGenerate = 1; boolean printStats = false; GameDifficulty gameDifficulty = GameDifficulty.Unspecified; + GameType gameType = GameType.Unspecified; Symmetry symmetry = Symmetry.NONE; int threads = Runtime.getRuntime().availableProcessors(); } diff --git a/app/src/main/java/tu_darmstadt/sudoku/controller/qqwing/QQWing.java b/app/src/main/java/tu_darmstadt/sudoku/controller/qqwing/QQWing.java index 34fdf08..d16f0ea 100644 --- a/app/src/main/java/tu_darmstadt/sudoku/controller/qqwing/QQWing.java +++ b/app/src/main/java/tu_darmstadt/sudoku/controller/qqwing/QQWing.java @@ -132,10 +132,16 @@ public class QQWing { */ private PrintStyle printStyle = PrintStyle.READABLE; + private GameType gameType = GameType.Unspecified; + private GameDifficulty difficulty = GameDifficulty.Unspecified; + /** * Create a new Sudoku board */ - public QQWing(GameType type) { + public QQWing(GameType type, GameDifficulty difficulty) { + gameType = type; + this.difficulty = difficulty; + GRID_SIZE_ROW = type.getSectionHeight(); // 3 // 2 GRID_SIZE_COL = type.getSectionWidth(); // 3 // 3 @@ -221,13 +227,21 @@ public class QQWing { * Get the gameDifficulty rating. */ public GameDifficulty getDifficulty() { - if (getGuessCount() > 0) return GameDifficulty.Hard; - if (getBoxLineReductionCount() > 0) return GameDifficulty.Moderate; - if (getPointingPairTripleCount() > 0) return GameDifficulty.Moderate; - if (getHiddenPairCount() > 0) return GameDifficulty.Moderate; - if (getNakedPairCount() > 0) return GameDifficulty.Moderate; - if (getHiddenSingleCount() > 0) return GameDifficulty.Easy; - if (getSingleCount() > 0) return GameDifficulty.Easy; + if (getGuessCount() > 0) + return GameDifficulty.Hard; + if (getBoxLineReductionCount() > 0) + return GameDifficulty.Moderate; + if (getPointingPairTripleCount() > 0) + return GameDifficulty.Moderate; + if (getHiddenPairCount() > 0) + return GameDifficulty.Moderate; + if (getNakedPairCount() > 0) + return GameDifficulty.Moderate; + if (getHiddenSingleCount() > 0) + return GameDifficulty.Easy; + if (getSingleCount() > 0) + return GameDifficulty.Easy; + return GameDifficulty.Unspecified; } @@ -434,7 +448,12 @@ public class QQWing { // Non-guesses are even rounds for (int i = 2; i <= lastSolveRound; i += 2) { rollbackRound(i); - } + + // Some hack to make easy levels on 12x12 .. because the generator wasn't able to create some + if(gameType == GameType.Default_12x12 && difficulty == GameDifficulty.Easy ) { + i += 4; // skip every 2nd round + } + } } public void setPrintStyle(PrintStyle ps) { @@ -667,7 +686,7 @@ public class QQWing { } private int findPositionWithFewestPossibilities() { - int minPossibilities = 10; + int minPossibilities = ROW_COL_SEC_SIZE+1; int bestPosition = 0; for (int i = 0; i < BOARD_SIZE; i++) { int position = randomBoardArray[i]; 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 34eee7b..8c6f84e 100644 --- a/app/src/main/java/tu_darmstadt/sudoku/ui/GameActivity.java +++ b/app/src/main/java/tu_darmstadt/sudoku/ui/GameActivity.java @@ -46,7 +46,7 @@ public class GameActivity extends AppCompatActivity implements NavigationView.On super.onCreate(savedInstanceState); GameType gameType = GameType.Unspecified; - int gameDifficulty = 0; + GameDifficulty gameDifficulty = GameDifficulty.Unspecified; int loadLevelID = 0; boolean loadLevel = false; @@ -56,7 +56,7 @@ public class GameActivity extends AppCompatActivity implements NavigationView.On if(o instanceof GameType) { gameType = (GameType)extras.get("gameType"); } - gameDifficulty = extras.getInt("gameDifficulty"); + gameDifficulty = (GameDifficulty)(extras.get("gameDifficulty")); loadLevel = extras.getBoolean("loadLevel"); if(loadLevel) { loadLevelID = extras.getInt("loadLevelID"); @@ -83,7 +83,7 @@ public class GameActivity extends AppCompatActivity implements NavigationView.On gameController.loadLevel(loadableGames.get(loadLevelID)); } else { // load a new level - gameController.loadNewLevel(gameType, GameDifficulty.getValidDifficultyList().get(gameDifficulty)); + gameController.loadNewLevel(gameType, gameDifficulty); } layout.setGame(gameController); diff --git a/app/src/main/java/tu_darmstadt/sudoku/ui/MainActivity.java b/app/src/main/java/tu_darmstadt/sudoku/ui/MainActivity.java index 24f44ec..e7ccbe0 100644 --- a/app/src/main/java/tu_darmstadt/sudoku/ui/MainActivity.java +++ b/app/src/main/java/tu_darmstadt/sudoku/ui/MainActivity.java @@ -12,7 +12,6 @@ import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.view.ViewPager; import android.os.Bundle; import android.view.LayoutInflater; -import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; @@ -23,8 +22,6 @@ import android.widget.TextView; import java.util.LinkedList; import java.util.List; -import java.util.Timer; -import java.util.TimerTask; import tu_darmstadt.sudoku.controller.SaveLoadController; import tu_darmstadt.sudoku.controller.helper.GameInfoContainer; @@ -37,17 +34,6 @@ public class MainActivity extends AppCompatActivity { RatingBar difficultyBar; TextView difficultyText; SharedPreferences settings; - Timer t = new Timer(); - - /** - * The {@link android.support.v4.view.PagerAdapter} that will provide - * fragments for each of the sections. We use a - * {@link FragmentPagerAdapter} derivative, which will keep every - * loaded fragment in memory. If this becomes too memory intensive, it - * may be best to switch to a - * {@link android.support.v4.app.FragmentStatePagerAdapter}. - */ - private SectionsPagerAdapter mSectionsPagerAdapter; /** * The {@link ViewPager} that will host the section contents. @@ -67,7 +53,15 @@ public class MainActivity extends AppCompatActivity { // Create the adapter that will return a fragment for each of the three // primary sections of the activity. - mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager()); + /* + The {@link android.support.v4.view.PagerAdapter} that will provide + fragments for each of the sections. We use a + {@link FragmentPagerAdapter} derivative, which will keep every + loaded fragment in memory. If this becomes too memory intensive, it + may be best to switch to a + {@link android.support.v4.app.FragmentStatePagerAdapter}. + */ + SectionsPagerAdapter mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager()); // Set up the ViewPager with the sections adapter. @@ -92,16 +86,16 @@ public class MainActivity extends AppCompatActivity { if (rating < 1) { ratingBar.setRating(1); } - difficultyText.setText(getString(difficultyList.get((int)ratingBar.getRating()-1).getStringResID())); + difficultyText.setText(getString(difficultyList.get((int) ratingBar.getRating() - 1).getStringResID())); } }); - int lastChosenDifficulty = settings.getInt("lastChosenDifficulty", 1); - difficultyBar.setRating(lastChosenDifficulty); + GameDifficulty lastChosenDifficulty = GameDifficulty.valueOf(settings.getString("lastChosenDifficulty", "Easy")); + difficultyBar.setRating(GameDifficulty.getValidDifficultyList().indexOf(lastChosenDifficulty)+1); // on first create always check for loadable levels! SharedPreferences.Editor editor = settings.edit(); editor.putBoolean("savesChanged", true); - editor.commit(); + editor.apply(); refreshContinueButton(); } @@ -129,13 +123,14 @@ public class MainActivity extends AppCompatActivity { break; case R.id.playButton: GameType gameType = GameType.getValidGameTypes().get(mViewPager.getCurrentItem()); - int gameDifficulty = difficultyBar.getProgress()-1; + int index = difficultyBar.getProgress()-1; + GameDifficulty gameDifficulty = GameDifficulty.getValidDifficultyList().get(index < 0 ? 0 : index); // save current setting for later SharedPreferences.Editor editor = settings.edit(); editor.putString("lastChosenGameType", gameType.name()); - editor.putInt("lastChosenDifficulty", gameDifficulty); - editor.commit(); + editor.putString("lastChosenDifficulty", gameDifficulty.name()); + editor.apply(); // send everything to game activity i = new Intent(this, GameActivity.class); @@ -169,7 +164,7 @@ public class MainActivity extends AppCompatActivity { } } - @Override + /*@Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long @@ -177,7 +172,7 @@ public class MainActivity extends AppCompatActivity { int id = item.getItemId(); return super.onOptionsItemSelected(item); - } + }*/ /** diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 696aca6..8ec1f76 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -43,6 +43,7 @@ Christopher Beckmann, Timm Lippert In affiliation with: This application belongs to the Privacy Friendly Apps. + This application uses a modified version of QQWing v1.3.4 More information can be found on: https://www.secuso.org