Пример #1
0
        static TurnSequenceMove[] CalculatedAllowedMovesForSlot(FtlSlot slot)
        {
            Turn u0              = new Turn(Side.Up, Rotation.Clockwise);
            Turn u1              = new Turn(Side.Up, Rotation.CounterClockwise);
            Turn u2              = new Turn(Side.Up, Rotation.Twice);
            Turn leftOfSlotUp    = new Turn(slot.LeftOf, Rotation.CounterClockwise);
            Turn leftOfSlotDown  = new Turn(slot.LeftOf, Rotation.Clockwise);
            Turn rightOfSlotUp   = new Turn(slot.RightOf, Rotation.Clockwise);
            Turn rightOfSlotDown = new Turn(slot.RightOf, Rotation.CounterClockwise);

            var allowedMoves = new TurnSequence[] {
                new TurnSequence(u0),
                new TurnSequence(u1),
                new TurnSequence(u2),
                new TurnSequence(rightOfSlotUp, u0, rightOfSlotDown),
                new TurnSequence(rightOfSlotUp, u1, rightOfSlotDown),
                new TurnSequence(rightOfSlotUp, u2, rightOfSlotDown),
                new TurnSequence(leftOfSlotUp, u0, leftOfSlotDown),
                new TurnSequence(leftOfSlotUp, u1, leftOfSlotDown),
                new TurnSequence(leftOfSlotUp, u2, leftOfSlotDown),
            }.Select(x => new TurnSequenceMove(x))
            .ToArray();

            return(allowedMoves);
        }
Пример #2
0
        static public CubeConstraint OtherSlotsConstraint(FtlSlot movingSlot)
        {
            var slotsToNotMove = AllFtlSlots
                                 .Where(x => !x.Home.Edge.InSameSpace(movingSlot.Home.Edge));

            return(new CompoundConstraint(slotsToNotMove.Select(x => x.Home.Stationary)));
        }
Пример #3
0
        static TurnSequenceMove[] CalculateMovesForPoppingCubeIntoTopRow(FtlSlot slot)
        {
            // !!! if there is already a cube in the top,
            // we might want to include the top turns, so cube currently in top, doesn't go into bottom.

            // !!! option: instead of adding this on, to SlotTurnGenerator,
            // just have extra step in solver to pop cube up,
            // then filter out any first moves that don't have both cubes in top

            // !!! also, when picking best move, perhaps secondary criteria is
            // to not put any other slot cubes in the slot we just vacated.

            Turn u0              = new Turn(Side.Up, Rotation.Clockwise);
            Turn u1              = new Turn(Side.Up, Rotation.CounterClockwise);
            Turn u2              = new Turn(Side.Up, Rotation.Twice);
            Turn leftOfSlotUp    = new Turn(slot.LeftOf, Rotation.CounterClockwise);
            Turn leftOfSlotDown  = new Turn(slot.LeftOf, Rotation.Clockwise);
            Turn rightOfSlotUp   = new Turn(slot.RightOf, Rotation.Clockwise);
            Turn rightOfSlotDown = new Turn(slot.RightOf, Rotation.CounterClockwise);

            var allowedMoves = new TurnSequence[] {
                new TurnSequence(u0),
                new TurnSequence(u1),
                new TurnSequence(u2),
                new TurnSequence(rightOfSlotUp, u0, rightOfSlotDown),
                new TurnSequence(rightOfSlotUp, u1, rightOfSlotDown),
                new TurnSequence(rightOfSlotUp, u2, rightOfSlotDown),
                new TurnSequence(leftOfSlotUp, u0, leftOfSlotDown),
                new TurnSequence(leftOfSlotUp, u1, leftOfSlotDown),
                new TurnSequence(leftOfSlotUp, u2, leftOfSlotDown),
            }.Select(x => new TurnSequenceMove(x))
            .ToArray();

            return(allowedMoves);
        }
Пример #4
0
        public SlotTurnGenerator(FtlSlot slot)
        {
            // Alternative to explicitly listing 9 valid moves
            // Have solver calculate subset of moves that don't violate constraints

            _defaultAllowedTurns = CalculatedAllowedMovesForSlot(slot);
        }
Пример #5
0
        public void MustSolveCrossBeforePlacingFtl()
        {
            var nonSolvedCrossCube = new Cube().Apply(Turn.Parse("R"));
            var slot = new FtlSlot(Side.Front, Side.Right);

            Assert.Throws <System.InvalidOperationException>(() => Solver.PlaceSingleFtlPairFromTop(slot, nonSolvedCrossCube));
        }
Пример #6
0
        static public CompoundConstraint FindFtlPairAndSolveIt(FtlSlot slot, Cube cube)
        {
            CornerEdgePair src = slot.Home.Locate(cube);

            return(new CompoundConstraint(
                       new CornerConstraint(src.Corner, slot.Home.Corner),
                       new EdgeConstraint(src.Edge, slot.Home.Edge)
                       ));
        }
Пример #7
0
        [InlineData("RU'R'UF'U2FUF'U2F")]          // RU'R'dR'U2RUR'U2R
        public void F2L(string knownSolution)
        {
            var solveTurns = TurnSequence.Parse(knownSolution);
            var cube       = new Cube().Apply(solveTurns.Reverse());

            Assert.True(cube.Apply(solveTurns).IsSolved, "not solved");

            var pair = new FtlSlot(Side.Front, Side.Right);

            var prepSolution = Solver.PlaceSingleFtlPairFromTop(pair, cube);

            cube = cube.Apply(prepSolution);

            Assert_F2LSolved(cube);
            Assert_CrossSolved(cube);
        }
Пример #8
0
        static public TurnSequence PlaceFtlPairs(Cube cube)
        {
            Constraints.VerifyConstraint(cube, Constraints.CrossConstraint, "Cross not solved");

            var cur = cube;

            var turns = new List <Turn>();

            FtlSlot easiestSlotToSolve = FindEasiestSlotToSolve(cur);

            while (easiestSlotToSolve != null)
            {
                int    num   = HoldingSlotCount(easiestSlotToSolve, cur);
                string debug = string.Join("\r\n", Constraints.AllFtlSlots.Select(slot => slot.Home.Examine(cur)));
                try{
                    var move = PlaceSingleFtlPairFromTop(easiestSlotToSolve, cur);
                    turns.AddRange(move._turns);
                    cur = cur.Apply(move);
                }catch (MoveNotFoundExcpetion) {
                    string location = easiestSlotToSolve.Home.Locate(cur).ToString();
                    int    i        = 0;
                }

                easiestSlotToSolve = FindEasiestSlotToSolve(cur);
            }

            return(new TurnSequence(turns.ToArray()));

            // if parts of cube are in different slots
            // there are 2 options as to which cube you pop-up first

            // to move 1 slot up where there are no pairs in upper
            // there are only 6 option (3 leftish + 3 rightish)

            // to move 1 slot up where one of the pairs is already in upper
            // there are 4 Upper turns * (3 leftish + 3 rightish) = 24 options

            // Also 24 happens to be the Least Common Multiple of 8 edge positions & 12 corner positions

            // If we evaluate all of them, 2*6*24 ==> 288 positions we have to solve
            // but there are essenially only 12 possibilities (white-up:4 + white-to-theside:8)
            // knowledge:
            // white-on-the-side is better than white-up -> reduces possibility from 12 to 8
            // case 1 or 2 (joined or side-op) are better than case 3 or 4
            // joined incorrectly is the worse.
        }
Пример #9
0
        static public TurnSequence PlaceSingleFtlPairFromTop(FtlSlot slot, Cube cube)
        {
            Constraints.VerifyConstraint(cube, Constraints.CrossConstraint, "Cross not solved");

            var pair          = slot.Home.Locate(cube);
            var holdingSlots  = HoldingSlots(pair);
            var moveGenerator = new SlotTurnGenerator(slot);

            if (holdingSlots.Length == 1)
            {
                moveGenerator.SetFirstSlot(holdingSlots[0]);
            }

            // these are constraints to apply move to a solved cube, so constraints don't work on messed up cube
            return(Solver.GetStepsToAcheiveMatch(6, new CompoundConstraint(
                                                     FindFtlPairAndSolveIt(slot, cube),
                                                     Constraints.CrossConstraint,
                                                     Constraints.OtherSlotsConstraint(slot)
                                                     ), moveGenerator
                                                 ));
        }
Пример #10
0
 static int HoldingSlotCount(FtlSlot slot, Cube cube) => HoldingSlots(slot.Home.Locate(cube)).Length;
Пример #11
0
 public void SetFirstSlot(FtlSlot firstSlot)
 {
     _firstMoveAllowedTurns = CalculateMovesForPoppingCubeIntoTopRow(firstSlot);
 }