// *** METHODS ***

    /// <summary>
    /// Returns the solution for the transferred Rubik
    /// </summary>
    /// <param name="cube">Defines the Rubik to be solved</param>
    protected virtual void Solve(Rubik cube)
    {
      Rubik = cube.DeepClone();
      Algorithm = new Algorithm();
      InitStandardCube();

      GetSolution();
      RemoveUnnecessaryMoves();
    }
      protected override void Solve(Rubik cube)
      {
        Rubik = cube.DeepClone();
        _coordCube = ToCoordCube(cube);
        this.MaxDepth = 30;
        this.TimeOut = 10000;
        Algorithm = new Algorithm();
        InitStandardCube();

        GetSolution();
        RemoveUnnecessaryMoves();
      }
Exemple #3
0
        /// <summary>
        /// Returns a solved Rubik
        /// </summary>
        /// <returns></returns>
        public Rubik GenStandardCube()
        {
            Rubik standardCube = new Rubik();

            standardCube.SetFaceColor(CubeFlag.TopLayer, FacePosition.Top, TopColor);
            standardCube.SetFaceColor(CubeFlag.BottomLayer, FacePosition.Bottom, BottomColor);
            standardCube.SetFaceColor(CubeFlag.RightSlice, FacePosition.Right, RightColor);
            standardCube.SetFaceColor(CubeFlag.LeftSlice, FacePosition.Left, LeftColor);
            standardCube.SetFaceColor(CubeFlag.FrontSlice, FacePosition.Front, FrontColor);
            standardCube.SetFaceColor(CubeFlag.BackSlice, FacePosition.Back, BackColor);

            return(standardCube);
        }
        public static int GetOrientation(Rubik rubik, Cube c)
        {
            int orientation = 0;
            if (c.IsEdge)
            {
                CubeFlag targetFlags = rubik.GetTargetFlags(c);
                Rubik clone = rubik.DeepClone();

                if (!targetFlags.HasFlag(CubeFlag.MiddleLayer))
                {
                    while (RefreshCube(clone, c).Position.HasFlag(CubeFlag.MiddleLayer))
                        clone.RotateLayer(c.Position.X, true);

                    Cube clonedCube = RefreshCube(clone, c);
                    Face yFace = clonedCube.Faces.First(f => f.Color == rubik.TopColor || f.Color == rubik.BottomColor);
                    if (!FacePosition.YPos.HasFlag(yFace.Position))
                        orientation = 1;
                }
                else
                {
                    Face zFace = c.Faces.First(f => f.Color == rubik.FrontColor || f.Color == rubik.BackColor);
                    if (c.Position.HasFlag(CubeFlag.MiddleLayer))
                    {
                        if (!FacePosition.ZPos.HasFlag(zFace.Position))
                            orientation = 1;
                    }
                    else
                    {
                        if (!FacePosition.YPos.HasFlag(zFace.Position))
                            orientation = 1;
                    }
                }
            }
            else if (c.IsCorner)
            {
                Face face = c.Faces.First(f => f.Color == rubik.TopColor || f.Color == rubik.BottomColor);
                if (!FacePosition.YPos.HasFlag(face.Position))
                {
                    if (FacePosition.XPos.HasFlag(face.Position) ^ !((c.Position.HasFlag(CubeFlag.BottomLayer) ^ (c.Position.HasFlag(CubeFlag.FrontSlice) ^ c.Position.HasFlag(CubeFlag.RightSlice)))))
                    {
                        orientation = 1;
                    }
                    else
                        orientation = 2;
                }
            }

            return orientation;
        }
    public DialogParityCheckResult(Rubik rubik, Form parent = null)
    {
      InitializeComponent();
      this.ShowInTaskbar = false;
      if (parent != null)
      {
        this.Owner = parent;
        this.StartPosition = FormStartPosition.CenterParent;
      }

      // Color test
      bool colors = Solvability.CorrectColors(rubik);
      lblColorTest.Text = colors ? "Passed" : "Failed";
      pbColorTest.Image = colors ? Properties.Resources.ok : Properties.Resources.cross_icon;

      if (!colors)
      {
        lblPermutationTest.Text = "Not tested";
        lblCornerTest.Text = "Not tested";
        lblEdgeTest.Text = "Not tested";

        pbCornerTest.Image = Properties.Resources.questionmark;
        pbEdgeTest.Image = Properties.Resources.questionmark;
        pbPermutationTest.Image = Properties.Resources.questionmark;
        lblHeader.Text = "This cube is unsolvable.";
      }
      else
      {
        // Permutation parity test
        bool permutation = Solvability.PermutationParityTest(rubik);
        lblPermutationTest.Text = permutation ? "Passed" : "Failed";
        pbPermutationTest.Image = permutation ? Properties.Resources.ok : Properties.Resources.cross_icon;

        // Corner parity test
        bool corner = Solvability.CornerParityTest(rubik);
        lblCornerTest.Text = corner ? "Passed" : "Failed";
        pbCornerTest.Image = corner ? Properties.Resources.ok : Properties.Resources.cross_icon;

        // Edge parity test
        bool edge = Solvability.EdgeParityTest(rubik);
        lblEdgeTest.Text = edge ? "Passed" : "Failed";
        pbEdgeTest.Image = edge ? Properties.Resources.ok : Properties.Resources.cross_icon;

        lblHeader.Text = permutation && corner && edge && colors ? "This cube is solvable." : "This cube is unsolvable.";
      }

    }
        public DialogSolutionFinder(CubeSolver solver, Rubik rubik, Form parent = null)
        {
            this.solver = solver;
            this.InitializeComponent();
            if (parent != null)
            {
                this.Owner = parent;
                this.StartPosition = FormStartPosition.CenterParent;
            }
            this.ShowInTaskbar = false;

            this.AddStepLabels(solver);

            solver.TrySolveAsync(rubik);
            solver.OnSolutionStepCompleted += this.solver_OnSolutionStepCompleted;
            solver.OnSolutionError += this.solver_OnSolutionError;

            this.stepLabels[this.currentIndex].Text = "In progress ...";
            this.stepImgs[this.currentIndex].Image = Properties.Resources.refresh;
        }
        /// <summary>
        /// Returns the Orientation
        /// </summary>
        /// <param name="rubik"></param>
        /// <param name="c"></param>
        /// <returns></returns>
        public static Orientation GetOrientation(Rubik rubik, Cube c)
        {
            var orientation = Orientation.Correct;
            if (c.IsEdge)
            {
                var targetFlags = rubik.GetTargetFlags(c);
                var clone = rubik.DeepClone();

                if (!targetFlags.HasFlag(CubeFlag.MiddleLayer))
                {
                    while (RefreshCube(clone, c).Position.HasFlag(CubeFlag.MiddleLayer)) clone.RotateLayer(c.Position.X, true);

                    var clonedCube = RefreshCube(clone, c);
                    var yFace = clonedCube.Faces.First(f => f.Color == rubik.TopColor || f.Color == rubik.BottomColor);
                    if (!YPos.HasFlag(yFace.Position)) orientation = Orientation.Clockwise;
                }
                else
                {
                    var zFace = c.Faces.First(f => f.Color == rubik.FrontColor || f.Color == rubik.BackColor);
                    if (c.Position.HasFlag(CubeFlag.MiddleLayer))
                    {
                        if (!ZPos.HasFlag(zFace.Position)) orientation = Orientation.Clockwise;
                    }
                    else
                    {
                        if (!YPos.HasFlag(zFace.Position)) orientation = Orientation.Clockwise;
                    }
                }
            }
            else if (c.IsCorner)
            {
                var face = c.Faces.First(f => f.Color == rubik.TopColor || f.Color == rubik.BottomColor);
                if (YPos.HasFlag(face.Position))
                {
                    return orientation;
                }
                orientation = XPos.HasFlag(face.Position) ^ !(c.Position.HasFlag(CubeFlag.BottomLayer) ^ (c.Position.HasFlag(CubeFlag.FrontSlice) ^ c.Position.HasFlag(CubeFlag.RightSlice))) ? Orientation.CounterClockwise : Orientation.Clockwise;
            }

            return orientation;
        }
        /// <summary>
        /// Initializes a new instance of the CubeModel class
        /// </summary>
        /// <param name="rubik">Rubik's Cube that has to be drawn</param>
        public CubeModel(Rubik rubik)
        {
            this.Rubik = rubik;
              this.Rotation = new double[] { 0, 0, 0 };
              this.Moves = new Queue<RotationInfo>();
              this.MouseHandling = true;
              this.DrawingMode = RubiksCubeLib.CubeModel.DrawingMode.ThreeDimensional;
              this.State = "Ready";
              this.RotationSpeed = 250;

              InitColorPicker();
              ResetLayerRotation();
              InitSelection();
              InitRenderer();

              InitializeComponent();
              SetStyle(ControlStyles.AllPaintingInWmPaint, true);
              SetStyle(ControlStyles.DoubleBuffer, true);
              SetStyle(ControlStyles.SupportsTransparentBackColor, true);
              SetStyle(ControlStyles.UserPaint, true);
        }
    private CoordCube ToCoordCube(Rubik rubik)
    {
      // get corner perm and orientation
      string[] corners = new string[N_CORNER] { "UFR", "UFL", "UBL", "URB", "DFR", "DFL", "DBL", "DRB" };
      byte[] cornerPermutation = new byte[N_CORNER];
      byte[] cornerOrientation = new byte[N_CORNER];
      for (int i = 0; i < N_CORNER; i++)
      {
        CubeFlag pos = CubeFlagService.Parse(corners[i]);
        Cube matchingCube = rubik.Cubes.First(c => c.Position.Flags == pos);
        CubeFlag targetPos = rubik.GetTargetFlags(matchingCube);
        cornerOrientation[i] = (byte)Solvability.GetOrientation(rubik, matchingCube);

        for (int j = 0; j < N_CORNER; j++)
          if (corners[j] == CubeFlagService.ToNotationString(targetPos))
            cornerPermutation[i] = (byte)(j + 1);
      }

      // get edge perm and orientation
      string[] edges = new string[N_EDGE] { "UR", "UF", "UL", "UB", "DR", "DF", "DL", "DB", "FR", "FL", "BL", "RB" };
      byte[] edgePermutation = new byte[N_EDGE];
      byte[] edgeOrientation = new byte[N_EDGE];
      for (int i = 0; i < N_EDGE; i++)
      {
        CubeFlag pos = CubeFlagService.Parse(edges[i]);
        Cube matchingCube = rubik.Cubes.Where(c => c.IsEdge).First(c => c.Position.Flags.HasFlag(pos));
        CubeFlag targetPos = rubik.GetTargetFlags(matchingCube);
        edgeOrientation[i] = (byte)Solvability.GetOrientation(rubik, matchingCube);

        for (int j = 0; j < N_EDGE; j++)
          if (CubeFlagService.ToNotationString(targetPos).Contains(edges[j]))
            edgePermutation[i] = (byte)(j + 1);
      }

      byte[] cornerInv = CoordCube.ToInversions(cornerPermutation);
      byte[] edgeInv = CoordCube.ToInversions(edgePermutation);

      return new CoordCube(cornerPermutation, edgePermutation, cornerOrientation, edgeOrientation);
    }
        // **** METHODS ****
        public static Rubik FromPattern(Pattern pattern)
        {
            Rubik rubik = new Rubik();
              foreach (PatternItem item in pattern.Items)
              {
            if (CubePosition.IsCorner(item.CurrentPosition.Flags))
            {
              bool xyzCorrect = !((item.CurrentPosition.Y == CubeFlag.TopLayer ^ (item.CurrentPosition.X == CubeFlag.RightSlice ^ item.CurrentPosition.Z == CubeFlag.FrontSlice))
              ^ (CubeFlagService.FirstYFlag(item.TargetPosition) == CubeFlag.TopLayer ^ (CubeFlagService.FirstXFlag(item.TargetPosition) == CubeFlag.RightSlice ^ CubeFlagService.FirstZFlag(item.TargetPosition) == CubeFlag.FrontSlice)));

              if (item.CurrentOrientation == Orientation.Correct)
              {
            rubik.SetFaceColor(item.CurrentPosition.Flags, CubeFlagService.ToFacePosition(item.CurrentPosition.Y), rubik.GetSliceColor(CubeFlagService.FirstYFlag(item.TargetPosition)));

            FacePosition x = xyzCorrect ? CubeFlagService.ToFacePosition(item.CurrentPosition.X) : CubeFlagService.ToFacePosition(item.CurrentPosition.Z);
            FacePosition z = xyzCorrect ? CubeFlagService.ToFacePosition(item.CurrentPosition.Z) : CubeFlagService.ToFacePosition(item.CurrentPosition.X);

            rubik.SetFaceColor(item.CurrentPosition.Flags, x, rubik.GetSliceColor(CubeFlagService.FirstXFlag(item.TargetPosition)));
            rubik.SetFaceColor(item.CurrentPosition.Flags, z, rubik.GetSliceColor(CubeFlagService.FirstZFlag(item.TargetPosition)));
              }
              else
              {
            bool corr = (item.CurrentPosition.X == CubeFlag.RightSlice ^ item.CurrentPosition.Z == CubeFlag.BackSlice) ^ item.CurrentPosition.Y == CubeFlag.BottomLayer;
            FacePosition x = (corr ^ item.CurrentOrientation == Orientation.Clockwise) ? CubeFlagService.ToFacePosition(item.CurrentPosition.X) : CubeFlagService.ToFacePosition(item.CurrentPosition.Y);
            FacePosition y = (corr ^ item.CurrentOrientation == Orientation.Clockwise) ? CubeFlagService.ToFacePosition(item.CurrentPosition.Z) : CubeFlagService.ToFacePosition(item.CurrentPosition.X);
            FacePosition z = (corr ^ item.CurrentOrientation == Orientation.Clockwise) ? CubeFlagService.ToFacePosition(item.CurrentPosition.Y) : CubeFlagService.ToFacePosition(item.CurrentPosition.Z);

            rubik.SetFaceColor(item.CurrentPosition.Flags, x, rubik.GetSliceColor(CubeFlagService.FirstXFlag(item.TargetPosition)));
            rubik.SetFaceColor(item.CurrentPosition.Flags, y, rubik.GetSliceColor(CubeFlagService.FirstYFlag(item.TargetPosition)));
            rubik.SetFaceColor(item.CurrentPosition.Flags, z, rubik.GetSliceColor(CubeFlagService.FirstZFlag(item.TargetPosition)));
              }
            }

            if (CubePosition.IsEdge(item.CurrentPosition.Flags))
            {
              CubeFlag flagOne = CubeFlagService.FirstNotInvalidFlag(item.CurrentPosition.Flags, CubeFlag.MiddleLayer | CubeFlag.MiddleSlice | CubeFlag.MiddleSliceSides);
              FacePosition faceOne = CubeFlagService.ToFacePosition(flagOne);
              FacePosition faceTwo = CubeFlagService.ToFacePosition(CubeFlagService.FirstNotInvalidFlag(item.CurrentPosition.Flags, CubeFlag.MiddleLayer | CubeFlag.MiddleSlice | CubeFlag.MiddleSliceSides | flagOne));

              CubeFlag tFlagOne = CubeFlagService.FirstNotInvalidFlag(item.TargetPosition, CubeFlag.MiddleLayer | CubeFlag.MiddleSlice | CubeFlag.MiddleSliceSides);

              rubik.SetFaceColor(item.CurrentPosition.Flags, faceOne, rubik.GetSliceColor(tFlagOne));
              rubik.SetFaceColor(item.CurrentPosition.Flags, faceTwo, rubik.GetSliceColor(CubeFlagService.FirstNotInvalidFlag(item.TargetPosition, CubeFlag.MiddleLayer | CubeFlag.MiddleSlice | CubeFlag.MiddleSliceSides | tFlagOne)));

              if (Solvability.GetOrientation(rubik, rubik.Cubes.First(c => c.Position.Flags == item.CurrentPosition.Flags)) != item.CurrentOrientation)
              {
            rubik.SetFaceColor(item.CurrentPosition.Flags, faceTwo, rubik.GetSliceColor(tFlagOne));
            rubik.SetFaceColor(item.CurrentPosition.Flags, faceOne, rubik.GetSliceColor(CubeFlagService.FirstNotInvalidFlag(item.TargetPosition, CubeFlag.MiddleLayer | CubeFlag.MiddleSlice | CubeFlag.MiddleSliceSides | tFlagOne)));
              }
            }

            if (CubePosition.IsCenter(item.CurrentPosition.Flags))
            {
              CubeFlag flag = CubeFlagService.FirstNotInvalidFlag(item.CurrentPosition.Flags, CubeFlag.MiddleLayer | CubeFlag.MiddleSlice | CubeFlag.MiddleSliceSides);
              CubeFlag tFlag = CubeFlagService.FirstNotInvalidFlag(item.TargetPosition, CubeFlag.MiddleLayer | CubeFlag.MiddleSlice | CubeFlag.MiddleSliceSides);

              rubik.SetFaceColor(item.CurrentPosition.Flags, CubeFlagService.ToFacePosition(flag), rubik.GetSliceColor(tFlag));
            }
              }
              return rubik;
        }
 /// <summary>
 /// Initializes the StandardCube
 /// </summary>
 protected void InitStandardCube()
 {
     StandardCube = Rubik.GenStandardCube();
 }
 public void TrySolveAsync(Rubik rubik)
 {
   solvingThread = new Thread(() => SolveAsync(rubik));
   solvingThread.Start();
 }
 /// <summary>
 /// Converts a rubik to a pattern
 /// </summary>
 /// <param name="r">Rubik </param>
 /// <returns>The pattern of the given rubik</returns>
 public static Pattern FromRubik(Rubik r)
 {
     Pattern p = new Pattern();
       List<PatternItem> newItems = new List<PatternItem>();
       foreach (CubePosition pos in Positions)
       {
     Cube cube = r.Cubes.First(c => r.GetTargetFlags(c) == pos.Flags);
     newItems.Add(new PatternItem(cube.Position, Solvability.GetOrientation(r, cube), pos.Flags));
       }
       p.Items = newItems;
       return p;
 }
 private void SolveAsync(Rubik rubik)
 {
   bool solvable = Solvability.FullTest(rubik);
   if (solvable)
   {
     Stopwatch sw = new Stopwatch();
     sw.Start();
     Solve(rubik);
     sw.Stop();
     if (OnSolutionStepCompleted != null) OnSolutionStepCompleted(this, new SolutionStepCompletedEventArgs(this.Name, true, this.Algorithm, (int)sw.ElapsedMilliseconds));
     solvingThread.Abort();
   }
   else
   {
     this.BroadcastOnSolutionError(this.Name, "Unsolvable cube");
   }
 }
 public TestScenario(Rubik rubik) : this(rubik, new Algorithm()) { }
 public static bool FullTest(Rubik r)
 {
     return CorrectColors(r) && FullParityTest(r);
 }
 public static bool CorrectColors(Rubik r)
 {
     return r.GenStandardCube().Cubes.Count(sc => r.Cubes
     .Where(c => CollectionMethods.ScrambledEquals(c.Colors, sc.Colors)).Count() == 1) == r.Cubes.Count();
 }
 /// <summary>
 /// Edge parity test
 /// </summary>
 /// <param name="rubik">Rubik to be tested</param>
 /// <returns>True, if the given Rubik passes the edge parity test</returns>
 public static bool EdgeParityTest(Rubik rubik)
 {
     return rubik.Cubes.Where(c => c.IsEdge).Sum(c => (int)GetOrientation(rubik, c)) % 2 == 0;
 }
Exemple #19
0
        // **** METHODS ****

        public static Rubik FromPattern(Pattern pattern)
        {
            Rubik rubik = new Rubik();

            foreach (PatternItem item in pattern.Items)
            {
                if (CubePosition.IsCorner(item.CurrentPosition.Flags))
                {
                    bool xyzCorrect = !((item.CurrentPosition.Y == CubeFlag.TopLayer ^ (item.CurrentPosition.X == CubeFlag.RightSlice ^ item.CurrentPosition.Z == CubeFlag.FrontSlice))
                                        ^ (CubeFlagService.FirstYFlag(item.TargetPosition) == CubeFlag.TopLayer ^ (CubeFlagService.FirstXFlag(item.TargetPosition) == CubeFlag.RightSlice ^ CubeFlagService.FirstZFlag(item.TargetPosition) == CubeFlag.FrontSlice)));

                    if (item.CurrentOrientation == Orientation.Correct)
                    {
                        rubik.SetFaceColor(item.CurrentPosition.Flags, CubeFlagService.ToFacePosition(item.CurrentPosition.Y), rubik.GetSliceColor(CubeFlagService.FirstYFlag(item.TargetPosition)));

                        FacePosition x = xyzCorrect ? CubeFlagService.ToFacePosition(item.CurrentPosition.X) : CubeFlagService.ToFacePosition(item.CurrentPosition.Z);
                        FacePosition z = xyzCorrect ? CubeFlagService.ToFacePosition(item.CurrentPosition.Z) : CubeFlagService.ToFacePosition(item.CurrentPosition.X);

                        rubik.SetFaceColor(item.CurrentPosition.Flags, x, rubik.GetSliceColor(CubeFlagService.FirstXFlag(item.TargetPosition)));
                        rubik.SetFaceColor(item.CurrentPosition.Flags, z, rubik.GetSliceColor(CubeFlagService.FirstZFlag(item.TargetPosition)));
                    }
                    else
                    {
                        bool         corr = (item.CurrentPosition.X == CubeFlag.RightSlice ^ item.CurrentPosition.Z == CubeFlag.BackSlice) ^ item.CurrentPosition.Y == CubeFlag.BottomLayer;
                        FacePosition x    = (corr ^ item.CurrentOrientation == Orientation.Clockwise) ? CubeFlagService.ToFacePosition(item.CurrentPosition.X) : CubeFlagService.ToFacePosition(item.CurrentPosition.Y);
                        FacePosition y    = (corr ^ item.CurrentOrientation == Orientation.Clockwise) ? CubeFlagService.ToFacePosition(item.CurrentPosition.Z) : CubeFlagService.ToFacePosition(item.CurrentPosition.X);
                        FacePosition z    = (corr ^ item.CurrentOrientation == Orientation.Clockwise) ? CubeFlagService.ToFacePosition(item.CurrentPosition.Y) : CubeFlagService.ToFacePosition(item.CurrentPosition.Z);

                        rubik.SetFaceColor(item.CurrentPosition.Flags, x, rubik.GetSliceColor(CubeFlagService.FirstXFlag(item.TargetPosition)));
                        rubik.SetFaceColor(item.CurrentPosition.Flags, y, rubik.GetSliceColor(CubeFlagService.FirstYFlag(item.TargetPosition)));
                        rubik.SetFaceColor(item.CurrentPosition.Flags, z, rubik.GetSliceColor(CubeFlagService.FirstZFlag(item.TargetPosition)));
                    }
                }

                if (CubePosition.IsEdge(item.CurrentPosition.Flags))
                {
                    CubeFlag     flagOne = CubeFlagService.FirstNotInvalidFlag(item.CurrentPosition.Flags, CubeFlag.MiddleLayer | CubeFlag.MiddleSlice | CubeFlag.MiddleSliceSides);
                    FacePosition faceOne = CubeFlagService.ToFacePosition(flagOne);
                    FacePosition faceTwo = CubeFlagService.ToFacePosition(CubeFlagService.FirstNotInvalidFlag(item.CurrentPosition.Flags, CubeFlag.MiddleLayer | CubeFlag.MiddleSlice | CubeFlag.MiddleSliceSides | flagOne));

                    CubeFlag tFlagOne = CubeFlagService.FirstNotInvalidFlag(item.TargetPosition, CubeFlag.MiddleLayer | CubeFlag.MiddleSlice | CubeFlag.MiddleSliceSides);

                    rubik.SetFaceColor(item.CurrentPosition.Flags, faceOne, rubik.GetSliceColor(tFlagOne));
                    rubik.SetFaceColor(item.CurrentPosition.Flags, faceTwo, rubik.GetSliceColor(CubeFlagService.FirstNotInvalidFlag(item.TargetPosition, CubeFlag.MiddleLayer | CubeFlag.MiddleSlice | CubeFlag.MiddleSliceSides | tFlagOne)));

                    if (Solvability.GetOrientation(rubik, rubik.Cubes.First(c => c.Position.Flags == item.CurrentPosition.Flags)) != item.CurrentOrientation)
                    {
                        rubik.SetFaceColor(item.CurrentPosition.Flags, faceTwo, rubik.GetSliceColor(tFlagOne));
                        rubik.SetFaceColor(item.CurrentPosition.Flags, faceOne, rubik.GetSliceColor(CubeFlagService.FirstNotInvalidFlag(item.TargetPosition, CubeFlag.MiddleLayer | CubeFlag.MiddleSlice | CubeFlag.MiddleSliceSides | tFlagOne)));
                    }
                }

                if (CubePosition.IsCenter(item.CurrentPosition.Flags))
                {
                    CubeFlag flag  = CubeFlagService.FirstNotInvalidFlag(item.CurrentPosition.Flags, CubeFlag.MiddleLayer | CubeFlag.MiddleSlice | CubeFlag.MiddleSliceSides);
                    CubeFlag tFlag = CubeFlagService.FirstNotInvalidFlag(item.TargetPosition, CubeFlag.MiddleLayer | CubeFlag.MiddleSlice | CubeFlag.MiddleSliceSides);

                    rubik.SetFaceColor(item.CurrentPosition.Flags, CubeFlagService.ToFacePosition(flag), rubik.GetSliceColor(tFlag));
                }
            }
            return(rubik);
        }
 /// <summary>
 /// Corner parity test
 /// </summary>
 /// <param name="rubik">Rubik to be tested</param>
 /// <returns>True, if the given Rubik passes the corner parity test</returns>
 public static bool CornerParityTest(Rubik rubik)
 {
     return rubik.Cubes.Where(c => c.IsCorner).Sum(c => (int)GetOrientation(rubik,c)) % 3 == 0;
 }
 public void TrySolveAsync(Rubik rubik)
 {
     this.solvingThread = new Thread(() => this.SolveAsync(rubik));
     this.solvingThread.Start();
 }
 private IEnumerable<Tuple<Cube, Cube>> GetPairs(Rubik rubik)
 {
     foreach (Cube edge in rubik.Cubes.Where(c => c.IsEdge && Rubik.GetTargetFlags(c).HasFlag(CubeFlag.MiddleLayer)))
       {
     Cube corner = rubik.Cubes.First(c => c.IsCorner && (rubik.GetTargetFlags(c) & ~CubeFlag.BottomLayer) == (rubik.GetTargetFlags(edge) & ~CubeFlag.MiddleLayer));
     if (!rubik.IsCorrect(corner) || !rubik.IsCorrect(edge))
       yield return new Tuple<Cube, Cube>(edge, corner);
       }
 }
 public TestScenario(Rubik rubik, Algorithm moves)
 {
   Rubik = rubik.DeepClone();
   Algorithm = moves;
 }
        /// <summary>
        /// Returns a solved Rubik 
        /// </summary>
        /// <returns></returns>
        public Rubik GenStandardCube()
        {
            Rubik standardCube = new Rubik();
              standardCube.SetFaceColor(CubeFlag.TopLayer, FacePosition.Top, TopColor);
              standardCube.SetFaceColor(CubeFlag.BottomLayer, FacePosition.Bottom, BottomColor);
              standardCube.SetFaceColor(CubeFlag.RightSlice, FacePosition.Right, RightColor);
              standardCube.SetFaceColor(CubeFlag.LeftSlice, FacePosition.Left, LeftColor);
              standardCube.SetFaceColor(CubeFlag.FrontSlice, FacePosition.Front, FrontColor);
              standardCube.SetFaceColor(CubeFlag.BackSlice, FacePosition.Back, BackColor);

              return standardCube;
        }
 public static bool FullParityTest(Rubik r)
 {
     return PermutationParityTest(r) && CornerParityTest(r) && EdgeParityTest(r);
 }
 /// <summary>
 /// Permutation parity test
 /// </summary>
 /// <param name="rubik">Rubik to be tested</param>
 /// <returns>True, if the given Rubik passes the permutation parity test</returns>
 public static bool PermutationParityTest(Rubik rubik)
 {
     Pattern p = Pattern.FromRubik(rubik);
       return p.Inversions % 2 == 0;
 }
 public TestScenario(Rubik rubik, LayerMove move) : this(rubik, new Algorithm(move.ToString())) { }
 public BeginnerSolver(Rubik cube)
 {
     Rubik = cube.DeepClone();
       this.Algorithm = new Algorithm();
       InitStandardCube();
 }
 /// <summary>
 /// Refreshes the position of a cube
 /// </summary>
 /// <param name="r">Parent rubik of the cube</param>
 private static Cube RefreshCube(Rubik r, Cube c)
 {
     return r.Cubes.First(cu => CollectionMethods.ScrambledEquals(cu.Colors, c.Colors));
 }