diff --git a/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/LayeredRandomizationCubePuzzle.java b/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/LayeredRandomizationCubePuzzle.java index d202374f..64022cb0 100644 --- a/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/LayeredRandomizationCubePuzzle.java +++ b/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/LayeredRandomizationCubePuzzle.java @@ -64,22 +64,7 @@ public PuzzleStateAndGenerator generateRandomMoves(Random r) { } } - // we take a "classic" big cube scramble sequence as reference - // because there is currently no API to generate N random moves directly - // (and I am too lazy to write one if we already have something that comes close) - PuzzleStateAndGenerator randomMovesPsag = super.generateRandomMoves(r); - String[] randomMoves = AlgorithmBuilder.splitAlgorithm(randomMovesPsag.generator); - - int remainingLength = this.getRandomMoveCount() - ab.getTotalCost(); - - for (int i = 0; i < remainingLength; i++) { - try { - ab.appendMove(randomMoves[i]); - } catch (InvalidMoveException e) { - l.log(Level.SEVERE, "", e); - throw new RuntimeException(e); - } - } + fillWithRandomMoves(ab, r, getRandomMoveCount()); return ab.getStateAndGenerator(); } diff --git a/scrambles/src/main/java/org/worldcubeassociation/tnoodle/scrambles/Puzzle.java b/scrambles/src/main/java/org/worldcubeassociation/tnoodle/scrambles/Puzzle.java index 1a0263fb..bb32cb81 100644 --- a/scrambles/src/main/java/org/worldcubeassociation/tnoodle/scrambles/Puzzle.java +++ b/scrambles/src/main/java/org/worldcubeassociation/tnoodle/scrambles/Puzzle.java @@ -837,26 +837,42 @@ boolean movesCommute(String move1, String move2) { */ @NoExport public PuzzleStateAndGenerator generateRandomMoves(Random r) { - AlgorithmBuilder ab = new AlgorithmBuilder( - this, MergingMode.NO_MERGING); - while(ab.getTotalCost() < getRandomMoveCount()) { - Map successors = - ab.getState().getScrambleSuccessors(); - String move; + AlgorithmBuilder ab = new AlgorithmBuilder(this, MergingMode.NO_MERGING); + fillWithRandomMoves(ab, r, getRandomMoveCount()); + return ab.getStateAndGenerator(); + } + + protected static void fillWithRandomMoves(AlgorithmBuilder ab, Random r, int targetCost) { + while(ab.getTotalCost() < targetCost) { + String move = chooseRandomSuccessorMove(ab, r); try { - do { - move = choose(r, successors.keySet()); - // If this move happens to be redundant, there is no - // reason to select this move again in vain. - successors.remove(move); - } while(ab.isRedundant(move)); ab.appendMove(move); } catch(InvalidMoveException e) { l.log(Level.SEVERE, "", e); throw new RuntimeException(e); } } - return ab.getStateAndGenerator(); + } + + protected static String chooseRandomSuccessorMove(AlgorithmBuilder ab, Random r) { + Map successors = + ab.getState().getScrambleSuccessors(); + Set moveSet = successors.keySet(); + + String move; + try { + do { + move = choose(r, moveSet); + // If this move happens to be redundant, there is no + // reason to select this move again in vain. + successors.remove(move); + } while(ab.isRedundant(move)); + } catch(InvalidMoveException e) { + l.log(Level.SEVERE, "", e); + throw new RuntimeException(e); + } + + return move; } public static int[] cloneArr(int[] src) {