Example #1
0
        private void FormCross()
        {
            while (!RubixCubeStatusEvaluator.CrossIsFormed(_cube, Side.Front))
            {
                var backEdges = _cube.GetBackEdges().Where(b => b.HasColour(Colour.White)).ToList();
                if (backEdges.Any())
                {
                    var backEdge = backEdges.First();
                    SolveBackEdge(backEdge);
                }

                var frontEdge = GetAnIncorrectFrontEdge();
                if (frontEdge != null)
                {
                    RotateFrontEdgeToBack(frontEdge);
                }

                var sideEdges = _cube.GetSideEdges().Where(b => b.HasColour(Colour.White)).ToList();
                if (sideEdges.Any())
                {
                    var sideEdge = sideEdges.First();
                    RotateSideEdgeToBack(sideEdge);
                }
            }
        }
        private void FormYellowCross()
        {
            while (!RubixCubeStatusEvaluator.CrossFaceIsFormed(_cube, Side.Back))
            {
                if (!CrossIsPartiallySolved())
                {
                    // Any rotation is fine here (providing the face matches the side)
                    PerformFruRufRotations(Side.Right, Side.Bottom);
                }

                var crossBlocks = _cube.GetBackFaceCrossBlocks().ToList();
                if (CrossIsCurrentlyAnArrow(crossBlocks))
                {
                    var sides        = GetIncorrectCrossBlockSides(crossBlocks);
                    var faceToRotate = GetFaceToRotate(sides);
                    var sideToRotate = GetSideToRotate(faceToRotate);

                    PerformFruRufRotations(faceToRotate, sideToRotate);
                }

                crossBlocks = _cube.GetBackFaceCrossBlocks().ToList();
                if (CrossIsCurrentlyALine(crossBlocks))
                {
                    var faceToRotate = GetIncorrectCrossBlockSides(crossBlocks).First();
                    var sideToRotate = GetSideToRotate(faceToRotate);

                    PerformFruRufRotations(faceToRotate, sideToRotate);
                }
            }
        }
        private void RotateIncorrectSideEdgeToBack()
        {
            var incorrectEdge = _cube.GetSideEdges().First(b => !RubixCubeStatusEvaluator.EdgeIsInCorrectPosition(b));
            var sides         = incorrectEdge.GetNonNullSides();

            if (sides.Contains(Side.Top) && sides.Contains(Side.Left))
            {
                PerformRightSwitch(Side.Left, Side.Top);
            }

            if (sides.Contains(Side.Right) && sides.Contains(Side.Top))
            {
                PerformRightSwitch(Side.Top, Side.Right);
            }

            if (sides.Contains(Side.Bottom) && sides.Contains(Side.Right))
            {
                PerformRightSwitch(Side.Right, Side.Bottom);
            }

            if (sides.Contains(Side.Left) && sides.Contains(Side.Bottom))
            {
                PerformRightSwitch(Side.Bottom, Side.Left);
            }
        }
Example #4
0
        private Block?GetAnIncorrectFrontEdge()
        {
            var blocks = _cube.GetFrontEdges().Where(b => b.HasColour(Colour.White));

            foreach (var block in blocks)
            {
                var nonFrontSide = GetSideToRotate(block, Side.Front);
                if (block.Front != Colour.White || !RubixCubeStatusEvaluator.SideIsCorrectColour(nonFrontSide, block))
                {
                    return(block);
                }
            }

            return(null);
        }
        private Block GetSolvableEdge()
        {
            var backEdges = _cube.GetBackEdges().Where(b => !b.HasColour(Colour.Yellow));

            foreach (var block in backEdges)
            {
                var sides       = block.GetNonNullSides();
                var nonBackSide = sides.Single(side => side != Side.Back);
                if (RubixCubeStatusEvaluator.SideIsCorrectColour(nonBackSide, block))
                {
                    return(block);
                }
            }

            return(null);
        }
        public void Solve()
        {
            while (!RubixCubeStatusEvaluator.SecondLayerIsSolved(_cube))
            {
                var backEdges = _cube.GetBackEdges();
                if (backEdges.All(b => b.HasColour(Colour.Yellow)))
                {
                    RotateIncorrectSideEdgeToBack();
                }

                while (GetSolvableEdge() == null)
                {
                    _cube.RotateClockwise(Side.Back);
                }

                SolveBackEdge(GetSolvableEdge());
            }
        }
Example #7
0
        private void SolveCorners()
        {
            while (!RubixCubeStatusEvaluator.FirstLayerIsSolved(_cube))
            {
                var frontCorners = _cube.GetFrontCornerBlocks().Where(c => !c.IsCorrectlyPositioned()).ToList();
                if (frontCorners.Select(c => c.Block.HasColour(Colour.White)).Any())
                {
                    var corner = frontCorners.First();
                    RotateCornerToBack(corner);
                }

                var backCorners = _cube.GetBackCornerBlocks().Where(c => c.IsCorrectlyPositioned()).ToList();
                if (backCorners.Select(c => c.Block.HasColour(Colour.White)).Any())
                {
                    var corner = backCorners.First();
                    RotateCornerToFront(corner);
                }
                else
                {
                    _cube.RotateClockwise(Side.Back);
                }
            }
        }
        private void ReorganiseMiddleEdges()
        {
            while (!RubixCubeStatusEvaluator.CrossIsFormed(_cube, Side.Back))
            {
                var middleEdges       = GetMiddleEdges();
                var numIncorrectEdges = middleEdges.Count(b => b.isCorrect);

                if (numIncorrectEdges == 2)
                {
                    var firstIncorrectEdge = middleEdges.First(b => !b.isCorrect);
                    var startNode          = middleEdges.Find(firstIncorrectEdge);
                    if (startNode == null)
                    {
                        throw new Exception("There should be an incorrect edge");
                    }

                    if (startNode.Next != null && !startNode.Next.Value.isCorrect) // TODO: managed to get a NullReferenceException here...
                    {
                        var sideToRotate = firstIncorrectEdge.index switch
                        {
                            (0, 1) => Side.Right,
                            (1, 2) => Side.Top,
                            (2, 1) => Side.Left,
                            (1, 0) => Side.Bottom,
                            _ => throw new Exception("The selected block is not a middle edge")
                        };

                        PerformRuRuRuuRuRotation(sideToRotate);
                    }
                    else if (startNode.Previous != null && !startNode.Previous.Value.isCorrect)
                    {
                        var sideToRotate = firstIncorrectEdge.index switch
                        {
                            (0, 1) => Side.Bottom,
                            (1, 2) => Side.Right,
                            (2, 1) => Side.Top,
                            (1, 0) => Side.Left,
                            _ => throw new Exception("The selected block is not a middle edge")
                        };

                        PerformRuRuRuuRuRotation(sideToRotate);
                    }
                    else
                    {
                        switch (firstIncorrectEdge.index)
                        {
                        case (0, 1):
                        case (2, 1):
                            PerformRuRuRuuRuRotation(Side.Bottom);
                            PerformRuRuRuuRuRotation(Side.Left);
                            PerformRuRuRuuRuRotation(Side.Bottom);
                            break;

                        case (1, 2):
                        case (1, 0):
                            PerformRuRuRuuRuRotation(Side.Right);
                            PerformRuRuRuuRuRotation(Side.Bottom);
                            PerformRuRuRuuRuRotation(Side.Right);
                            break;
                        }
                    }
                }
                else if (numIncorrectEdges == 3)
                {
                    var correctEdge  = middleEdges.First(b => b.isCorrect);
                    var sideToRotate = correctEdge.index switch
                    {
                        (0, 1) => Side.Left,
                        (1, 2) => Side.Bottom,
                        (2, 1) => Side.Right,
                        (1, 0) => Side.Top,
                        _ => throw new Exception("The selected block is not a middle edge")
                    };

                    PerformRuRuRuuRuRotation(sideToRotate);
                }
                else
                {
                    _cube.RotateClockwise(Side.Back);
                }
            }
        }
Example #9
0
        public void FirstLayerSolver_CorrectlySolvesCorners_GivenCornerBetweenWrongSidesOnFront()
        {
            var cube = new RubixCube(new[, , ]
            {
                {
                    {
                        new Block(Colour.Red, null, Colour.Green, null, Colour.White, null),
                        new Block(null, null, Colour.Green, null, Colour.White, null),
                        new Block(null, Colour.Blue, Colour.White, null, Colour.Red, null)
                    },
                    {
                        new Block(Colour.Red, null, null, null, Colour.White, null),
                        new Block(null, null, null, null, Colour.White, null),
                        new Block(null, Colour.Orange, null, null, Colour.White, null)
                    },
                    {
                        new Block(Colour.Orange, null, null, Colour.Green, Colour.White, null),
                        new Block(null, null, null, Colour.Blue, Colour.White, null),
                        new Block(null, Colour.Yellow, null, Colour.Orange, Colour.Green, null)
                    }
                },
                {
                    {
                        new Block(Colour.Yellow, null, Colour.Orange, null, null, null),
                        new Block(null, null, Colour.Green, null, null, null),
                        new Block(null, Colour.Yellow, Colour.Green, null, null, null)
                    },
                    {
                        new Block(Colour.Red, null, null, null, null, null),
                        new Block(null, null, null, null, null, null),
                        new Block(null, Colour.Orange, null, null, null, null)
                    },
                    {
                        new Block(Colour.Green, null, null, Colour.Orange, null, null),
                        new Block(null, null, null, Colour.Blue, null, null),
                        new Block(null, Colour.Yellow, null, Colour.Red, null, null)
                    }
                },
                {
                    {
                        new Block(Colour.Green, null, Colour.Yellow, null, null, Colour.Red),
                        new Block(null, null, Colour.Yellow, null, null, Colour.Blue),
                        new Block(null, Colour.Orange, Colour.Blue, null, null, Colour.White)
                    },
                    {
                        new Block(Colour.Blue, null, null, null, null, Colour.Red),
                        new Block(null, null, null, null, null, Colour.Yellow),
                        new Block(null, Colour.Orange, null, null, null, Colour.Blue)
                    },
                    {
                        new Block(Colour.Yellow, null, null, Colour.Blue, null, Colour.Orange),
                        new Block(null, null, null, Colour.Red, null, Colour.Green),
                        new Block(null, Colour.Yellow, null, Colour.Blue, null, Colour.Red)
                    }
                }
            });

            var solver = new FirstLayerSolver(cube);

            solver.Solve();

            Assert.That(RubixCubeStatusEvaluator.FirstLayerIsSolved(cube), Is.True);
        }
Example #10
0
        private static bool BackEdgeIsOnCorrectSide(Block block, Colour nonWhiteColour)
        {
            var layer = block.GetLayer(nonWhiteColour) ?? throw new ArgumentException("Cannot be null here");

            return(RubixCubeStatusEvaluator.SideIsCorrectColour(layer, block));
        }