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; } } }
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; } } }