Esempio n. 1
0
        /**
         * This function will generate getRandomTurnCount() number of non cancelling,
         * random turns. If a puzzle wants to provide custom scrambles
         * (for example: Pochmann style megaminx or MRSS), it should override this method.
         *
         * NOTE: It is assumed that this method is thread safe! That means that if you're
         * overriding this method and you don't know what you're doing,
         * use the synchronized keyword when implementing this method:<br>
         * <code>protected synchronized String generateScramble(Random r);</code>
         * @param r An instance of Random
         * @return A PuzzleStateAndGenerator that contains a scramble string, and the
         *         state achieved by applying that scramble.
         */

        public virtual PuzzleStateAndGenerator GenerateRandomMoves(Random r)
        {
            var ab = new AlgorithmBuilder(MergingMode.NoMerging, GetSolvedState());

            while (ab.GetTotalCost() < GetRandomMoveCount())
            {
                var successors = ab.GetState().GetScrambleSuccessors();
                try
                {
                    string move;
                    do
                    {
                        move = Functions.Choose(r, successors.Keys);
                        // 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)
                {
                    Assert(false, e.Message, e);
                    return(null);
                }
            }
            return(ab.GetStateAndGenerator());
        }
Esempio n. 2
0
        public static PuzzleStateAndGenerator ApplyOrientation(CubePuzzle puzzle, CubeMove[] randomOrientation,
                                                               PuzzleStateAndGenerator psag, bool discardRedundantMoves)
        {
            if (randomOrientation.Length == 0)
            {
                return(psag);
            }

            // Append reorientation to scramble.
            try
            {
                var ab = new AlgorithmBuilder(MergingMode.NoMerging, puzzle.GetSolvedState());
                ab.AppendAlgorithm(psag.Generator);
                // Check if our reorientation is going to cancel with the last
                // turn of our scramble. If it does, then we just discard
                // that last turn of our scramble. This ensures we have a scramble
                // with no redundant turns, and I can't see how it could hurt the
                // quality of our scrambles to do this.
                var firstReorientMove = randomOrientation[0].ToString();
                while (ab.IsRedundant(firstReorientMove))
                {
                    //azzert(discardRedundantMoves);
                    var im = ab.FindBestIndexForMove(firstReorientMove, MergingMode.CanonicalizeMoves);
                    ab.PopMove(im.Index);
                }
                foreach (var cm in randomOrientation)
                {
                    ab.AppendMove(cm.ToString());
                }

                psag = ab.GetStateAndGenerator();
                return(psag);
            }
            catch (InvalidMoveException e)
            {
                Assert(false, e.Message, e);
                return(null);
            }
        }