private CoordCube ToCoordCube(Rubik rubik) { // get corner perm and orientation string[] corners = new string[N_CORNER] { "UFR", "UFL", "UBL", "URB", "DFR", "DFL", "DBL", "DRB" }; byte[] cornerPermutation = new byte[N_CORNER]; byte[] cornerOrientation = new byte[N_CORNER]; for (int i = 0; i < N_CORNER; i++) { CubeFlag pos = CubeFlagService.Parse(corners[i]); Cube matchingCube = rubik.Cubes.First(c => c.Position.Flags == pos); CubeFlag targetPos = rubik.GetTargetFlags(matchingCube); cornerOrientation[i] = (byte)Solvability.GetOrientation(rubik, matchingCube); for (int j = 0; j < N_CORNER; j++) if (corners[j] == CubeFlagService.ToNotationString(targetPos)) cornerPermutation[i] = (byte)(j + 1); } // get edge perm and orientation string[] edges = new string[N_EDGE] { "UR", "UF", "UL", "UB", "DR", "DF", "DL", "DB", "FR", "FL", "BL", "RB" }; byte[] edgePermutation = new byte[N_EDGE]; byte[] edgeOrientation = new byte[N_EDGE]; for (int i = 0; i < N_EDGE; i++) { CubeFlag pos = CubeFlagService.Parse(edges[i]); Cube matchingCube = rubik.Cubes.Where(c => c.IsEdge).First(c => c.Position.Flags.HasFlag(pos)); CubeFlag targetPos = rubik.GetTargetFlags(matchingCube); edgeOrientation[i] = (byte)Solvability.GetOrientation(rubik, matchingCube); for (int j = 0; j < N_EDGE; j++) if (CubeFlagService.ToNotationString(targetPos).Contains(edges[j])) edgePermutation[i] = (byte)(j + 1); } byte[] cornerInv = CoordCube.ToInversions(cornerPermutation); byte[] edgeInv = CoordCube.ToInversions(edgePermutation); return new CoordCube(cornerPermutation, edgePermutation, cornerOrientation, edgeOrientation); }
public static int GetOrientation(Rubik rubik, Cube c) { int orientation = 0; if (c.IsEdge) { CubeFlag targetFlags = rubik.GetTargetFlags(c); Rubik clone = rubik.DeepClone(); if (!targetFlags.HasFlag(CubeFlag.MiddleLayer)) { while (RefreshCube(clone, c).Position.HasFlag(CubeFlag.MiddleLayer)) clone.RotateLayer(c.Position.X, true); Cube clonedCube = RefreshCube(clone, c); Face yFace = clonedCube.Faces.First(f => f.Color == rubik.TopColor || f.Color == rubik.BottomColor); if (!FacePosition.YPos.HasFlag(yFace.Position)) orientation = 1; } else { Face zFace = c.Faces.First(f => f.Color == rubik.FrontColor || f.Color == rubik.BackColor); if (c.Position.HasFlag(CubeFlag.MiddleLayer)) { if (!FacePosition.ZPos.HasFlag(zFace.Position)) orientation = 1; } else { if (!FacePosition.YPos.HasFlag(zFace.Position)) orientation = 1; } } } else if (c.IsCorner) { Face face = c.Faces.First(f => f.Color == rubik.TopColor || f.Color == rubik.BottomColor); if (!FacePosition.YPos.HasFlag(face.Position)) { if (FacePosition.XPos.HasFlag(face.Position) ^ !((c.Position.HasFlag(CubeFlag.BottomLayer) ^ (c.Position.HasFlag(CubeFlag.FrontSlice) ^ c.Position.HasFlag(CubeFlag.RightSlice))))) { orientation = 1; } else orientation = 2; } } return orientation; }
/// <summary> /// Returns the Orientation /// </summary> /// <param name="rubik"></param> /// <param name="c"></param> /// <returns></returns> public static Orientation GetOrientation(Rubik rubik, Cube c) { var orientation = Orientation.Correct; if (c.IsEdge) { var targetFlags = rubik.GetTargetFlags(c); var clone = rubik.DeepClone(); if (!targetFlags.HasFlag(CubeFlag.MiddleLayer)) { while (RefreshCube(clone, c).Position.HasFlag(CubeFlag.MiddleLayer)) clone.RotateLayer(c.Position.X, true); var clonedCube = RefreshCube(clone, c); var yFace = clonedCube.Faces.First(f => f.Color == rubik.TopColor || f.Color == rubik.BottomColor); if (!YPos.HasFlag(yFace.Position)) orientation = Orientation.Clockwise; } else { var zFace = c.Faces.First(f => f.Color == rubik.FrontColor || f.Color == rubik.BackColor); if (c.Position.HasFlag(CubeFlag.MiddleLayer)) { if (!ZPos.HasFlag(zFace.Position)) orientation = Orientation.Clockwise; } else { if (!YPos.HasFlag(zFace.Position)) orientation = Orientation.Clockwise; } } } else if (c.IsCorner) { var face = c.Faces.First(f => f.Color == rubik.TopColor || f.Color == rubik.BottomColor); if (YPos.HasFlag(face.Position)) { return orientation; } orientation = XPos.HasFlag(face.Position) ^ !(c.Position.HasFlag(CubeFlag.BottomLayer) ^ (c.Position.HasFlag(CubeFlag.FrontSlice) ^ c.Position.HasFlag(CubeFlag.RightSlice))) ? Orientation.CounterClockwise : Orientation.Clockwise; } return orientation; }
/// <summary> /// Converts a rubik to a pattern /// </summary> /// <param name="r">Rubik </param> /// <returns>The pattern of the given rubik</returns> public static Pattern FromRubik(Rubik r) { Pattern p = new Pattern(); List<PatternItem> newItems = new List<PatternItem>(); foreach (CubePosition pos in Positions) { Cube cube = r.Cubes.First(c => r.GetTargetFlags(c) == pos.Flags); newItems.Add(new PatternItem(cube.Position, Solvability.GetOrientation(r, cube), pos.Flags)); } p.Items = newItems; return p; }
private IEnumerable<Tuple<Cube, Cube>> GetPairs(Rubik rubik) { foreach (Cube edge in rubik.Cubes.Where(c => c.IsEdge && Rubik.GetTargetFlags(c).HasFlag(CubeFlag.MiddleLayer))) { Cube corner = rubik.Cubes.First(c => c.IsCorner && (rubik.GetTargetFlags(c) & ~CubeFlag.BottomLayer) == (rubik.GetTargetFlags(edge) & ~CubeFlag.MiddleLayer)); if (!rubik.IsCorrect(corner) || !rubik.IsCorrect(edge)) yield return new Tuple<Cube, Cube>(edge, corner); } }