void solver_OnSolutionStepCompleted(object sender, SolutionStepCompletedEventArgs e)
    {
      if (!e.Finished)
      {
        PictureBox currentStepImg = stepImgs[currentIndex];
        Label currentStep = stepLabels[currentIndex];
        if (currentStepImg.InvokeRequired) currentStepImg.Invoke((MethodInvoker)delegate() { currentStepImg.Image = Properties.Resources.ok; });
        if (currentStep.InvokeRequired) currentStep.Invoke((MethodInvoker)delegate() { currentStep.Text = e.Type == SolutionStepType.Standard ? string.Format("{0} moves", e.Algorithm.Moves.Count) : string.Empty; });
        currentIndex++;

        if (currentIndex < stepImgs.Count)
        {
          currentStepImg = stepImgs[currentIndex];
          currentStep = stepLabels[currentIndex];
          if (currentStepImg.InvokeRequired) currentStepImg.Invoke((MethodInvoker)delegate() { currentStepImg.Image = Properties.Resources.refresh; });
          if (currentStep.InvokeRequired) currentStep.Invoke((MethodInvoker)delegate() { currentStep.Text = "In progress ..."; });
        }
      }
      else
      {
        if (lblTimeHeader.InvokeRequired) lblTimeHeader.Invoke((MethodInvoker)delegate() { lblTime.Text = string.Format("{0:f2}s", e.Milliseconds / 1000.0); });
        if (lblMovesHeader.InvokeRequired) lblMovesHeader.Invoke((MethodInvoker)delegate() { lblMoves.Text = string.Format("{0} moves", e.Algorithm.Moves.Count); });
        if (lblHeader.InvokeRequired) lblHeader.Invoke((MethodInvoker)delegate() { lblHeader.Text = "Solution found."; });
        if (btnAdd.InvokeRequired) btnAdd.Invoke((MethodInvoker)delegate() { btnAdd.Enabled = true; });
        solver.OnSolutionStepCompleted -= solver_OnSolutionStepCompleted;
        this.Algorithm = e.Algorithm;
      }
    }
 /// <summary>
 /// Transforms the algorithm
 /// </summary>
 /// <param name="rotationLayer">Transformation layer</param>
 /// <returns>Transformed algorithm</returns>
 public Algorithm Transform(CubeFlag rotationLayer)
 {
     var newAlgorithm = new Algorithm();
     for (var i = 0; i < this.Moves.Count; i++)
     {
         newAlgorithm.Moves.Add(this.Moves[i].Transform(rotationLayer));
     }
     return newAlgorithm;
 }
Пример #3
0
 /// <summary>
 /// Transforms the algorithm
 /// </summary>
 /// <param name="rotationLayer">Transformation layer</param>
 /// <returns>Transformed algorithm</returns>
 public Algorithm Transform(CubeFlag rotationLayer)
 {
   Algorithm newAlgorithm = new Algorithm();
   for (int i = 0; i < Moves.Count; i++)
   {
     newAlgorithm.Moves.Add(Moves[i].Transform(rotationLayer));
   }
   return newAlgorithm;
 }
      protected override void Solve(Rubik cube)
      {
        Rubik = cube.DeepClone();
        _coordCube = ToCoordCube(cube);
        this.MaxDepth = 30;
        this.TimeOut = 10000;
        Algorithm = new Algorithm();
        InitStandardCube();

        GetSolution();
        RemoveUnnecessaryMoves();
      }
        private void SolveCrossTopLayer()
        {
            // Step 1: Get edges with the color of the top face
              IEnumerable<Cube> topEdges = Rubik.Cubes.Where(c => c.IsEdge).Where(c => c.Position.HasFlag(CubeFlag.TopLayer));

              // Step 2: Check if the cube is insoluble
              if (topEdges.Where(tE => tE.Faces.First(f => f.Position == FacePosition.Top).Color == Rubik.TopColor).Count() % 2 != 0) return;

              IEnumerable<Cube> correctEdges = topEdges.Where(c => c.Faces.First(f => f.Position == FacePosition.Top).Color == Rubik.TopColor);
              Algorithm solveTopCrossAlgorithmI = new Algorithm("F R U R' U' F'");
              Algorithm solveTopCrossAlgorithmII = new Algorithm("F S R U R' U' F' S'");

              // Step 3: Solve the cross on the top layer
              if (Rubik.CountEdgesWithCorrectOrientation() == 0)
              {
            SolverAlgorithm(solveTopCrossAlgorithmI);
            correctEdges = topEdges.Where(c => c.Faces.First(f => f.Position == FacePosition.Top).Color == Rubik.TopColor);
              }

              if (Rubik.CountEdgesWithCorrectOrientation() == 2)
              {
            Cube firstCorrect = correctEdges.First();
            Cube secondCorrect = correctEdges.First(f => f != firstCorrect);

            bool opposite = false;
            foreach (CubeFlag flag in firstCorrect.Position.GetFlags())
            {
              CubeFlag pos = CubeFlagService.GetOppositeFlag(flag);
              if (secondCorrect.Position.HasFlag(pos) && pos != CubeFlag.None)
              {
            opposite = true;
            break;
              }
            }

            if (opposite)
            {
              while (correctEdges.Count(c => c.Position.HasFlag(CubeFlag.RightSlice)) != 1) SolverMove(CubeFlag.TopLayer, true);
              SolverAlgorithm(solveTopCrossAlgorithmI);
            }
            else
            {
              while (correctEdges.Count(c => c.Position.HasFlag(CubeFlag.RightSlice) || c.Position.HasFlag(CubeFlag.FrontSlice)) != 2) SolverMove(CubeFlag.TopLayer, true);
              SolverAlgorithm(solveTopCrossAlgorithmII);
            }
              }

              // Step 4: Move the edges of the cross to their target positions
              while (topEdges.Where(c => c.Position.Flags == GetTargetFlags(c)).Count() < 4)
              {
            IEnumerable<Cube> CorrectEdges = topEdges.Where(c => c.Position.Flags == GetTargetFlags(c));
            while (CorrectEdges.Count() < 2) SolverMove(CubeFlag.TopLayer, true);

            CubeFlag rightSlice = CubeFlagService.FromFacePosition(CorrectEdges.First().Faces
              .First(f => f.Position != FacePosition.Top && f.Color != Color.Black).Position);
            SolverMove(CubeFlag.TopLayer, false);

            if (CorrectEdges.Count(c => c.Position.HasFlag(rightSlice)) == 0) SolverMove(CubeFlag.TopLayer, true);
            else
            {
              SolverMove(CubeFlag.TopLayer, true);
              rightSlice = CubeFlagService.FromFacePosition(CorrectEdges.First(cE => !cE.Position.HasFlag(rightSlice)).Faces
            .First(f => f.Position != FacePosition.Top && f.Color != Color.Black).Position);
            }

            // Algorithm: R U Ri U R U U Ri
            SolverAlgorithm("{0} U {0}' U {0} U U {0}'", CubeFlagService.ToNotationString(rightSlice));

            while (CorrectEdges.Count() < 2) SolverMove(CubeFlag.TopLayer, true);
              }
        }
    private void SolveCrossTopLayer()
    {
      // Step 1: Get edges with the color of the top face
      var topEdges = this.Rubik.Cubes.Where(c => c.IsEdge).Where(c => c.Position.HasFlag(CubeFlag.TopLayer));

      // Step 2: Check if the cube is insoluble
      if (topEdges.Count(tE => tE.Faces.First(f => f.Position == FacePosition.Top).Color == this.Rubik.TopColor) % 2 != 0) return;

      var correctEdges = topEdges.Where(c => c.Faces.First(f => f.Position == FacePosition.Top).Color == this.Rubik.TopColor);
      var solveTopCrossAlgorithmI = new Algorithm("F R U R' U' F'");
      var solveTopCrossAlgorithmII = new Algorithm("F S R U R' U' F' S'");

      // Step 3: Solve the cross on the top layer
      if (this.Rubik.CountEdgesWithCorrectOrientation() == 0)
      {
          this.SolverAlgorithm(solveTopCrossAlgorithmI);
        correctEdges = topEdges.Where(c => c.Faces.First(f => f.Position == FacePosition.Top).Color == this.Rubik.TopColor);
      }

      if (this.Rubik.CountEdgesWithCorrectOrientation() == 2)
      {
        var firstCorrect = correctEdges.First();
        var secondCorrect = correctEdges.First(f => f != firstCorrect);

        var opposite = (from CubeFlag flag in firstCorrect.Position.GetFlags() select CubeFlagService.GetOppositeFlag(flag)).Any(pos => secondCorrect.Position.HasFlag(pos) && pos != CubeFlag.None);

          if (opposite)
        {
          while (correctEdges.Count(c => c.Position.HasFlag(CubeFlag.RightSlice)) != 1) this.SolverMove(CubeFlag.TopLayer, true);
            this.SolverAlgorithm(solveTopCrossAlgorithmI);
        }
        else
        {
          while (correctEdges.Count(c => c.Position.HasFlag(CubeFlag.RightSlice) || c.Position.HasFlag(CubeFlag.FrontSlice)) != 2) this.SolverMove(CubeFlag.TopLayer, true);
            this.SolverAlgorithm(solveTopCrossAlgorithmII);
        }
      }

      // Step 4: Move the edges of the cross to their target positions
      while (topEdges.Count(c => c.Position.Flags == this.GetTargetFlags(c)) < 4)
      {
        var CorrectEdges = topEdges.Where(c => c.Position.Flags == this.GetTargetFlags(c));
        while (CorrectEdges.Count() < 2) this.SolverMove(CubeFlag.TopLayer, true);

        var rightSlice = CubeFlagService.FromFacePosition(CorrectEdges.First().Faces
          .First(f => f.Position != FacePosition.Top && f.Color != Color.Black).Position);
          this.SolverMove(CubeFlag.TopLayer, false);

        if (CorrectEdges.Count(c => c.Position.HasFlag(rightSlice)) == 0) this.SolverMove(CubeFlag.TopLayer, true);
        else
        {
            this.SolverMove(CubeFlag.TopLayer, true);
          rightSlice = CubeFlagService.FromFacePosition(CorrectEdges.First(cE => !cE.Position.HasFlag(rightSlice)).Faces
            .First(f => f.Position != FacePosition.Top && f.Color != Color.Black).Position);
        }

        // Algorithm: R U Ri U R U U Ri
          this.SolverAlgorithm("{0} U {0}' U {0} U U {0}'", CubeFlagService.ToNotationString(rightSlice));

        while (CorrectEdges.Count() < 2) this.SolverMove(CubeFlag.TopLayer, true);
      }
    }
        private void solver_OnSolutionStepCompleted(object sender, SolutionStepCompletedEventArgs e)
        {
            if (!e.Finished)
            {
                var currentStepImg = this.stepImgs[this.currentIndex];
                var currentStep = this.stepLabels[this.currentIndex];
                if (currentStepImg.InvokeRequired)
                {
                    var img = currentStepImg;
                    currentStepImg.Invoke((MethodInvoker)delegate { img.Image = Properties.Resources.ok; });
                }
                if (currentStep.InvokeRequired)
                {
                    var step = currentStep;
                    currentStep.Invoke((MethodInvoker)delegate
                        {
                            step.Text = e.Type == SolutionStepType.Standard
                                                   ? $"{e.Algorithm.Moves.Count} moves"
                                                   : string.Empty;
                        });
                }
                this.currentIndex++;

                if (this.currentIndex >= this.stepImgs.Count)
                {
                    return;
                }
                currentStepImg = this.stepImgs[this.currentIndex];
                currentStep = this.stepLabels[this.currentIndex];
                if (currentStepImg.InvokeRequired) currentStepImg.Invoke((MethodInvoker)delegate { currentStepImg.Image = Properties.Resources.refresh; });
                if (currentStep.InvokeRequired) currentStep.Invoke((MethodInvoker)delegate { currentStep.Text = "In progress ..."; });
            }
            else
            {
                if (this.lblTimeHeader.InvokeRequired)
                    this.lblTimeHeader.Invoke((MethodInvoker)delegate
                        {
                            lblTime.Text = $"{e.Milliseconds / 1000.0:f2}s";
                        });
                if (this.lblMovesHeader.InvokeRequired)
                    this.lblMovesHeader.Invoke((MethodInvoker)delegate
                        {
                            lblMoves.Text = $"{e.Algorithm.Moves.Count} moves";
                        });
                if (this.lblHeader.InvokeRequired) this.lblHeader.Invoke((MethodInvoker)delegate { lblHeader.Text = "Solution found."; });
                if (this.btnAdd.InvokeRequired) this.btnAdd.Invoke((MethodInvoker)delegate { btnAdd.Enabled = true; });
                this.solver.OnSolutionStepCompleted -= this.solver_OnSolutionStepCompleted;
                this.Algorithm = e.Algorithm;
            }
        }