public override void Solve(Rubik cube)
        {
            this.Rubik    = cube.DeepClone();
            _coordCube    = TwoPhaseHelpers.ToCoordCube(cube);
            this.MaxDepth = 30;
            this.TimeOut  = 10000;
            Algorithm     = new Algorithm(null);
            InitStandardCube();

            GetSolution();
            Algorithm = Algorithm.RemoveUnnecessaryMoves(Algorithm);
        }
        public void Solution()
        {
            _power[0]  = 0;
            _axis[0]   = 0;
            _flip[0]   = CoordCubeGetters.GetFlip(_coordCube);
            _twist[0]  = CoordCubeGetters.GetTwist(_coordCube);
            _parity[0] = CoordCubeExtensionsModule.Parity(ref _coordCube);
            _slice[0]  = CoordCubeGetters.GetFRtoBR(_coordCube) / 24;
            _urfdlf[0] = CoordCubeGetters.GetURFtoDLF(_coordCube);
            _frbr[0]   = CoordCubeGetters.GetFRtoBR(_coordCube);
            _urul[0]   = CoordCubeGetters.GetURtoUL(_coordCube);
            _ubdf[0]   = CoordCubeGetters.GetUBtoDF(_coordCube);

            _minDistPhase1[1] = 1;
            int  n           = 0;
            bool busy        = false;
            int  depthPhase1 = 0;

            long tStart = DateTime.Now.Millisecond;

            do
            {
                do
                {
                    if ((depthPhase1 - n > _minDistPhase1[n + 1]) && !busy)
                    {
                        n = n + 1;

                        if (_axis[n] == 0 || _axis[n] == 3)
                        {
                            _axis[n] = 1;
                        }
                        else
                        {
                            _axis[n] = 0;
                        }

                        _power[n] = 1;
                    }
                    else
                    {
                        _power[n] = _power[n] + 1;

                        if (_power[n] > 3)
                        {
                            var escape15 = false;

                            do
                            {
                                // increment axis
                                _axis[n] = _axis[n] + 1;

                                if (_axis[n] > 5)
                                {
                                    if (n == 0)
                                    {
                                        depthPhase1 = depthPhase1 + 1;
                                        _axis[n]    = 0;
                                        _power[n]   = 1;
                                        busy        = false;
                                        escape15    = true;
                                    }
                                    else
                                    {
                                        n--;
                                        busy     = true;
                                        escape15 = true;
                                    }
                                }
                                else
                                {
                                    _power[n] = 1;
                                    busy      = false;
                                }
                            } while (!escape15 && (n != 0 && (_axis[n - 1] == _axis[n] || _axis[n - 1] - 3 == _axis[n])));
                        }
                        else
                        {
                            busy = false;
                        }
                    }
                } while (busy);

                var mv = 3 * _axis[n] + _power[n] - 1;

                _flip[n + 1]  = TwoPhaseMoveTables.Flip[_flip[n], mv];
                _twist[n + 1] = TwoPhaseMoveTables.Twist[_twist[n], mv];
                _slice[n + 1] = TwoPhaseMoveTables.FRtoBR[_slice[n] * 24, mv] / 24;

                _minDistPhase1[n + 1] =
                    Math.Max(
                        TwoPhasePruningTableModule.GetPruning(TwoPhasePruningTableModule.SliceFlip, TwoPhaseConstants.N_SLICE1 * _flip[n + 1] + _slice[n + 1]),
                        TwoPhasePruningTableModule.GetPruning(TwoPhasePruningTableModule.SliceTwist, TwoPhaseConstants.N_SLICE1 * _twist[n + 1] + _slice[n + 1])
                        );

                if (_minDistPhase1[n + 1] == 0 && n >= depthPhase1 - 5)
                {
                    _minDistPhase1[n + 1] = 10;// instead of 10 any value >5 is possible

                    var s = 0;

                    if (n == depthPhase1 - 1 && (s = TotalDepth(depthPhase1, this.MaxDepth)) >= 0)
                    {
                        // solution found
                        for (int i = 0; i < s; i++)
                        {
                            if (_power[i] == 0)
                            {
                                break;
                            }

                            this.SolverMove(TwoPhaseHelpers.IntsToLayerMove(_axis[i], _power[i]));
                        }

                        return;
                    }
                }
            } while (true);
        }