/// <summary> /// Searches for the best algorithm for the given pattern /// </summary> /// <param name="p">Current rubik pattern</param> /// <param name="rotationLayer">Transformation layer</param> /// <returns>Returns the best match</returns> public Algorithm FindBestMatch(Pattern p, CubeFlag rotationLayer, PatternFilter filter) { Dictionary <Pattern, Algorithm> matches = FindMatches(p, rotationLayer, filter); Algorithm bestAlgo = matches.OrderByDescending(item => item.Key.Items.Count()).FirstOrDefault().Value; return(bestAlgo); }
/// <summary> /// Finds all possible algorithms for this pattern /// </summary> /// <param name="p">Current rubik pattern</param> /// <param name="rotationLayer">Transformation rotation</param> /// <returns>Returns all possible solutions for this pattern</returns> public Dictionary<Pattern, Algorithm> FindMatches(Pattern p, CubeFlag rotationLayer, PatternFilter filter) { Dictionary<Pattern, Algorithm> transformedPatterns = Patterns.ToDictionary(kvp => kvp.Key.DeepClone(), a => a.Value); // clone Dictionary<Pattern,Algorithm> filteredPatterns = transformedPatterns.Where(kvp => filter.Filter(p, kvp.Key)).ToDictionary(pa => pa.Key, a => a.Value); // filter filteredPatterns = filteredPatterns.OrderByDescending(k => k.Key.Probability).ToDictionary(pa => pa.Key.DeepClone(), a => a.Value); // order by probability Dictionary<Pattern, Algorithm> matches = new Dictionary<Pattern, Algorithm>(); // 4 possible standard transformations for (int i = 0; i < 4; i++) { // Get matches foreach (KeyValuePair<Pattern, Algorithm> kvp in filteredPatterns.Where(pa => p.IncludesAllPatternElements(pa.Key))) { matches.Add(kvp.Key, kvp.Value); // Add to matches } if (rotationLayer == CubeFlag.None) return matches; if (filter.OnlyAtBeginning) { transformedPatterns = filteredPatterns.Except(matches).ToDictionary(pa => pa.Key.Transform(rotationLayer), a => a.Value.Transform(rotationLayer)); filteredPatterns = transformedPatterns; } else { transformedPatterns = transformedPatterns.ToDictionary(pa => pa.Key.Transform(rotationLayer), a => a.Value.Transform(rotationLayer)); filteredPatterns = transformedPatterns.Where(kvp => filter.Filter(p, kvp.Key)).ToDictionary(pa => pa.Key, a => a.Value); } } return matches; }
private void CompleteF2L() { List<Tuple<Cube, Cube>> unsolvedPairs = GetPairs(this.Rubik).ToList(); while (unsolvedPairs.Count > 0) // 4 pairs { Tuple<Cube, Cube> currentPair = unsolvedPairs.First(); Cube edge = currentPair.Item1; Cube corner = currentPair.Item2; CubePosition target = new CubePosition(Rubik.GetTargetFlags(corner)); if (!corner.Position.HasFlag(CubeFlag.TopLayer) && Rubik.GetTargetFlags(corner) != corner.Position.Flags) { CubeFlag rotationLayer = CubeFlagService.FirstNotInvalidFlag(corner.Position.Flags, CubeFlag.BottomLayer); bool direction = new TestScenario(Rubik, new LayerMove(rotationLayer)).TestCubePosition(corner, CubeFlag.TopLayer); SolverMove(rotationLayer, direction); SolverMove(CubeFlag.TopLayer, true); SolverMove(rotationLayer, !direction); } // move edge to top position if necessary if (!edge.Position.HasFlag(CubeFlag.TopLayer) && Rubik.GetTargetFlags(edge) != edge.Position.Flags) { CubeFlag rotationLayer = CubeFlagService.FirstNotInvalidFlag(edge.Position.Flags, CubeFlag.MiddleLayer); bool direction = new TestScenario(Rubik, new LayerMove(rotationLayer)).TestCubePosition(edge, CubeFlag.TopLayer); SolverMove(rotationLayer, direction); while ((corner.Position.HasFlag(rotationLayer) && !corner.Position.HasFlag(CubeFlag.BottomLayer)) || edge.Position.HasFlag(rotationLayer)) SolverMove(CubeFlag.TopLayer, true); SolverMove(rotationLayer, !direction); } // detect right and front slice CubeFlag rightSlice = CubeFlagService.ToInt(target.X) == CubeFlagService.ToInt(target.Z) ? target.Z : target.X; CubeFlag frontSlice = CubeFlagService.FirstNotInvalidFlag(target.Flags, CubeFlag.YFlags | rightSlice); while (!corner.Position.HasFlag(target.Flags & ~CubeFlag.BottomLayer)) SolverMove(CubeFlag.TopLayer, true); PatternFilter filter = new PatternFilter(new Func<Pattern, Pattern, bool>(delegate(Pattern p1, Pattern p2) { PatternItem item = new PatternItem(corner.Position, Solvability.GetOrientation(this.Rubik, corner),target.Flags); return p2.Items.Any(i => i.Equals(item)); }), true); Algorithm algo = null; for (int i = 0; i < 4; i++) { F2LPattern pattern = new F2LPattern(Rubik.GetTargetFlags(edge), Rubik.GetTargetFlags(corner), rightSlice, frontSlice); algo = pattern.FindBestMatch(Pattern.FromRubik(Rubik), CubeFlag.None, filter); if (algo != null) { SolverAlgorithm(algo); break; } SolverMove(CubeFlag.TopLayer, true); } int count = unsolvedPairs.Count; unsolvedPairs = GetPairs(this.Rubik).ToList(); if (unsolvedPairs.Count == count) { this.BroadcastOnSolutionError("Complete first two layers", "Wrong algorithm"); return; } } }
/// <summary> /// Finds all possible algorithms for this pattern /// </summary> /// <param name="p">Current rubik pattern</param> /// <param name="rotationLayer">Transformation rotation</param> /// <returns>Returns all possible solutions for this pattern</returns> public Dictionary <Pattern, Algorithm> FindMatches(Pattern p, CubeFlag rotationLayer, PatternFilter filter) { Dictionary <Pattern, Algorithm> transformedPatterns = Patterns.ToDictionary(kvp => kvp.Key.DeepClone(), a => a.Value); // clone Dictionary <Pattern, Algorithm> filteredPatterns = transformedPatterns.Where(kvp => filter.Filter(p, kvp.Key)).ToDictionary(pa => pa.Key, a => a.Value); // filter filteredPatterns = filteredPatterns.OrderByDescending(k => k.Key.Probability).ToDictionary(pa => pa.Key.DeepClone(), a => a.Value); // order by probability Dictionary <Pattern, Algorithm> matches = new Dictionary <Pattern, Algorithm>(); // 4 possible standard transformations for (int i = 0; i < 4; i++) { // Get matches foreach (KeyValuePair <Pattern, Algorithm> kvp in filteredPatterns.Where(pa => p.IncludesAllPatternElements(pa.Key))) { matches.Add(kvp.Key, kvp.Value); // Add to matches } if (rotationLayer == CubeFlag.None) { return(matches); } if (filter.OnlyAtBeginning) { transformedPatterns = filteredPatterns.Except(matches).ToDictionary(pa => pa.Key.Transform(rotationLayer), a => a.Value.Transform(rotationLayer)); filteredPatterns = transformedPatterns; } else { transformedPatterns = transformedPatterns.ToDictionary(pa => pa.Key.Transform(rotationLayer), a => a.Value.Transform(rotationLayer)); filteredPatterns = transformedPatterns.Where(kvp => filter.Filter(p, kvp.Key)).ToDictionary(pa => pa.Key, a => a.Value); } } return(matches); }
/// <summary> /// Searches for the best algorithm for the given pattern /// </summary> /// <param name="p">Current rubik pattern</param> /// <param name="rotationLayer">Transformation layer</param> /// <returns>Returns the best match</returns> public Algorithm FindBestMatch(Pattern p, CubeFlag rotationLayer, PatternFilter filter) { Dictionary<Pattern, Algorithm> matches = FindMatches(p, rotationLayer, filter); Algorithm bestAlgo = matches.OrderByDescending(item => item.Key.Items.Count()).FirstOrDefault().Value; return bestAlgo; }
/// <summary> /// Searches for the best algorithm for the given pattern /// </summary> /// <param name="p">Current rubik pattern</param> /// <param name="rotationLayer">Transformation layer</param> /// <param name="filter"></param> /// <returns>Returns the best match</returns> public Algorithm FindBestMatch(Pattern p, CubeFlag rotationLayer, PatternFilter filter) { var matches = this.FindMatches(p, rotationLayer, filter); var bestAlgo = matches.OrderByDescending(item => item.Key.Items.Count).FirstOrDefault().Value; return bestAlgo; }