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); }
private int TotalDepth(int depthPhase1, int maxDepth) { int mv = 0, d1 = 0, d2 = 0; int maxDepthPhase2 = Math.Min(10, maxDepth - depthPhase1); for (int i = 0; i < depthPhase1; i++) { mv = 3 * _axis[i] + _power[i] - 1; _urfdlf[i + 1] = TwoPhaseMoveTables.URFtoDLF[_urfdlf[i], mv]; _frbr[i + 1] = TwoPhaseMoveTables.FRtoBR[_frbr[i], mv]; _parity[i + 1] = TwoPhaseMoveTables.ParityMove[_parity[i], mv]; } d1 = TwoPhasePruningTableModule.GetPruning( TwoPhasePruningTableModule.SliceURFtoDLF, (TwoPhaseConstants.N_SLICE2 * _urfdlf[depthPhase1] + _frbr[depthPhase1]) * 2 + _parity[depthPhase1] ); if (d1 > maxDepthPhase2) { return(-1); } for (int i = 0; i < depthPhase1; i++) { mv = 3 * _axis[i] + _power[i] - 1; _urul[i + 1] = TwoPhaseMoveTables.URtoUL[_urul[i], mv]; _ubdf[i + 1] = TwoPhaseMoveTables.UBtoDF[_ubdf[i], mv]; } _urdf[depthPhase1] = TwoPhaseMoveTables.URtoULandUBtoDF[_urul[depthPhase1], _ubdf[depthPhase1]]; d2 = TwoPhasePruningTableModule.GetPruning( TwoPhasePruningTableModule.SliceURtoDF, (TwoPhaseConstants.N_SLICE2 * _urdf[depthPhase1] + _frbr[depthPhase1]) * 2 + _parity[depthPhase1] ); if (d2 > maxDepthPhase2) { return(-1); } if ((_minDistPhase2[depthPhase1] = Math.Max(d1, d2)) == 0)// already solved { return(depthPhase1); } // now set up search int depthPhase2 = 1; int n = depthPhase1; bool busy = false; _power[depthPhase1] = 0; _axis[depthPhase1] = 0; _minDistPhase2[n + 1] = 1; // else failure for depthPhase2=1, n=0 // +++++++++++++++++++ end initialization +++++++++++++++++++++++++++++++++ do { do { if ((depthPhase1 + depthPhase2 - n > _minDistPhase2[n + 1]) && !busy) { if (_axis[n] == 0 || _axis[n] == 3)// Initialize next move { _axis[++n] = 1; _power[n] = 2; } else { _axis[++n] = 0; _power[n] = 1; } } else if ((_axis[n] == 0 || _axis[n] == 3) ? (++_power[n] > 3) : ((_power[n] = _power[n] + 2) > 3)) { do {// increment axis if (++_axis[n] > 5) { if (n == depthPhase1) { if (depthPhase2 >= maxDepthPhase2) { return(-1); } else { depthPhase2++; _axis[n] = 0; _power[n] = 1; busy = false; break; } } else { n--; busy = true; break; } } else { if (_axis[n] == 0 || _axis[n] == 3) { _power[n] = 1; } else { _power[n] = 2; } busy = false; } } while (n != depthPhase1 && (_axis[n - 1] == _axis[n] || _axis[n - 1] - 3 == _axis[n])); } else { busy = false; } } while (busy); // +++++++++++++ compute new coordinates and new minDist ++++++++++ mv = 3 * _axis[n] + _power[n] - 1; _urfdlf[n + 1] = TwoPhaseMoveTables.URFtoDLF[_urfdlf[n], mv]; _frbr[n + 1] = TwoPhaseMoveTables.FRtoBR[_frbr[n], mv]; _parity[n + 1] = TwoPhaseMoveTables.ParityMove[_parity[n], mv]; _urdf[n + 1] = TwoPhaseMoveTables.URtoDF[_urdf[n], mv]; _minDistPhase2[n + 1] = Math.Max( TwoPhasePruningTableModule.GetPruning( TwoPhasePruningTableModule.SliceURtoDF, (TwoPhaseConstants.N_SLICE2 * _urdf[n + 1] + _frbr[n + 1]) * 2 + _parity[n + 1] ), TwoPhasePruningTableModule.GetPruning( TwoPhasePruningTableModule.SliceURFtoDLF, (TwoPhaseConstants.N_SLICE2 * _urfdlf[n + 1] + _frbr[n + 1]) * 2 + _parity[n + 1] ) ); // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ } while (_minDistPhase2[n + 1] != 0); return(depthPhase1 + depthPhase2); }