Example #1
0
		// *** CONSTRUCTOR ***

		/// <summary>
		/// Initializes a new instance of the Face3D class
		/// </summary>
		/// <param name="vertices">Vertices of the 3D face</param>
		/// <param name="color">Color</param>
		/// <param name="position">Position</param>
		/// <param name="masterPosition">Position of the parent 3D cube</param>
		public Face3D(IEnumerable<Point3D> vertices, Color color, FacePosition position, CubeFlag masterPosition)
		{
			this.Vertices = vertices;
			this.Color = color;
			this.Position = position;
			this.MasterPosition = masterPosition;
		}
 /// <summary>
 /// Initializes a new instance of the Cube3D class
 /// </summary>
 /// <param name="faces">Faces</param>
 /// <param name="position">Position</param>
 public Cube3D(IEnumerable<Face3D> faces, CubeFlag position, Point3D location, double scale)
 {
     this.Faces = faces;
     this.Position = position;
       this.Location = location;
       this.Scale = scale;
 }
        // **** METHODS ****

        /// <summary>
        /// Returns true if the given CubeFlag contains a valid move
        /// </summary>
        /// <param name="flags">Defines the CubeFlag to be analyzed</param>
        /// <returns></returns>
        public static bool IsPossibleMove(CubeFlag flags)
        {
            flags = ExceptFlag(flags, CubeFlag.None);
            return GetFlags(flags).All(f => IsXFlag((CubeFlag)f)) ||
              GetFlags(flags).All(f => IsYFlag((CubeFlag)f)) ||
              GetFlags(flags).All(f => IsZFlag((CubeFlag)f));
        }
    /// <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;
    }
Example #5
0
 /// <summary>
 /// Constructor with faces and position
 /// </summary>
 /// <param name="faces">Defines the faces where the cube belongs to</param>
 /// <param name="position">Defines the position of the cube</param>
 public Cube(IEnumerable<Face> faces, CubeFlag position)
 {
     this.Faces = faces;
     this.Position = new CubePosition(position);
     this.Colors = new List<Color>();
     this.Colors.Clear();
     this.Faces.ToList().ForEach(f => Colors.Add(f.Color));
 }
 /// <summary>
 /// Returns a collection with six entries containing the six Faces3D with a black color
 /// </summary>
 /// <param name="masterPosition">Defines the master position of the Faces3D</param>
 /// <returns></returns>
 public static IEnumerable<Face3D> GenFaces3D(CubeFlag masterPosition) => new[] {
                                                                                    new Face3D(new[] { new Point3D(-1, 1, -1), new Point3D(1, 1, -1), new Point3D(1, -1, -1), new Point3D(-1, -1, -1) }, Color.Black, FacePosition.Front, masterPosition),
                                                                                    new Face3D(new[] { new Point3D(-1, 1, 1), new Point3D(1, 1, 1), new Point3D(1, -1, 1), new Point3D(-1, -1, 1) }, Color.Black, FacePosition.Back, masterPosition),
                                                                                    new Face3D(new[] { new Point3D(-1, -1, -1), new Point3D(1, -1, -1), new Point3D(1, -1, 1), new Point3D(-1, -1, 1) }, Color.Black, FacePosition.Top, masterPosition),
                                                                                    new Face3D(new[] { new Point3D(-1, 1, -1), new Point3D(1, 1, -1), new Point3D(1, 1, 1), new Point3D(-1, 1, 1) }, Color.Black, FacePosition.Bottom, masterPosition),
                                                                                    new Face3D(new[] { new Point3D(1, 1, 1), new Point3D(1, 1, -1), new Point3D(1, -1, -1), new Point3D(1, -1, 1) }, Color.Black, FacePosition.Right, masterPosition),
                                                                                    new Face3D(new[] { new Point3D(-1, 1, 1), new Point3D(-1, 1, -1), new Point3D(-1, -1, -1), new Point3D(-1, -1, 1) }, Color.Black, FacePosition.Left, masterPosition)
                                                                                };
        // **** METHODS ****

        /// <summary>
        /// Returns true if the given CubeFlag describes a corner cube
        /// </summary>
        /// <param name="position">Defines the CubeFlag to be analyzed</param>
        /// <returns></returns>
        public static bool IsCorner(CubeFlag position) => ((position == (CubeFlag.TopLayer | CubeFlag.FrontSlice | CubeFlag.LeftSlice))
    || (position == (CubeFlag.TopLayer | CubeFlag.FrontSlice | CubeFlag.RightSlice))
    || (position == (CubeFlag.TopLayer | CubeFlag.BackSlice | CubeFlag.LeftSlice))
    || (position == (CubeFlag.TopLayer | CubeFlag.BackSlice | CubeFlag.RightSlice))
    || (position == (CubeFlag.BottomLayer | CubeFlag.FrontSlice | CubeFlag.LeftSlice))
    || (position == (CubeFlag.BottomLayer | CubeFlag.FrontSlice | CubeFlag.RightSlice))
    || (position == (CubeFlag.BottomLayer | CubeFlag.BackSlice | CubeFlag.LeftSlice))
    || (position == (CubeFlag.BottomLayer | CubeFlag.BackSlice | CubeFlag.RightSlice)));
 /// <summary>
 /// Returns the first flag in the first parameter which the second parameter does not contain
 /// </summary>
 /// <param name="flags">Defines the posiible flags to be returned</param>
 /// <param name="invalid">Defines the invalid flags</param>
 /// <returns></returns>
 public static CubeFlag FirstNotInvalidFlag(CubeFlag flags, CubeFlag invalid)
 {
     foreach (CubeFlag f in GetFlags(flags))
       {
     if (!invalid.HasFlag(f))
       return f;
       }
       return CubeFlag.None;
 }
Example #9
0
 /// <summary>
 /// Transforms the algorithm
 /// </summary>
 /// <param name="rotationLayer">Transformation layer</param>
 /// <returns>Transformed algorithm</returns>
 public Algorithm Transform(CubeFlag rotationLayer)
 {
   Algorithm newAlgorithm = new Algorithm();
   for (int i = 0; i < Moves.Count; i++)
   {
     newAlgorithm.Moves.Add(Moves[i].Transform(rotationLayer));
   }
   return newAlgorithm;
 }
Example #10
0
 public bool TestCubePosition(Cube c, CubeFlag endPos)
 {
   foreach(LayerMove move in Algorithm.Moves)
   {
     Rubik.RotateLayer(move);
   }
   bool result = RefreshCube(c).Position.HasFlag(endPos);
   return result;
 }
 /// <summary>
 /// Transforms the algorithm
 /// </summary>
 /// <param name="rotationLayer">Transformation layer</param>
 /// <returns>Transformed algorithm</returns>
 public Algorithm Transform(CubeFlag rotationLayer)
 {
     var newAlgorithm = new Algorithm();
     for (var i = 0; i < this.Moves.Count; i++)
     {
         newAlgorithm.Moves.Add(this.Moves[i].Transform(rotationLayer));
     }
     return newAlgorithm;
 }
 public bool TestCubePosition(Cube c, CubeFlag endPos)
 {
     foreach (var move in this.Algorithm.Moves.Cast<LayerMove>())
     {
         this.Rubik.RotateLayer(move);
     }
     var result = this.RefreshCube(c).Position.HasFlag(endPos);
     return result;
 }
 /// <summary>
 /// Returns a CubeFlag which contains all flags which exist in both the first and the second parameter
 /// </summary>
 /// <param name="first">Defines the first CubeFlag</param>
 /// <param name="second">Defines the second CubeFlag</param>
 /// <returns></returns>
 public static CubeFlag CommonFlags(CubeFlag first, CubeFlag second)
 {
     CubeFlag commonFlags = CubeFlag.None;
       foreach (CubeFlag flag in GetFlags(first))
       {
     if (second.HasFlag(flag))
       commonFlags |= flag;
       }
       return commonFlags;
 }
 /// <summary>
 /// Returns a ClubFlag which contains all single flags in the first parameter which don't exist in the second parameter
 /// </summary>
 /// <param name="flags">Defines all possible flags</param>
 /// <param name="invalid">Defines the flags to be filtered out of the first parameter</param>
 /// <returns></returns>
 public static CubeFlag ExceptFlag(CubeFlag flags, CubeFlag invalid)
 {
     CubeFlag pos = CubeFlag.None;
       foreach (CubeFlag p in GetFlags(flags))
       {
     if (!invalid.HasFlag(p))
       pos |= p;
       }
       return pos;
 }
Example #15
0
    // *** CONSTRUCTORS ***

    /// <summary>
    /// Constructor
    /// </summary>
    /// <param name="layer">Defines the layer to be moved</param>
    /// <param name="direction">Defines the direction (true == clockwise and false == counter-clockwise)</param>
    /// <param name="twice">Defines whether this layer will be turned twice or not</param>
    /// <exception cref="System.Exception">Thrown when layer contains more than one flag</exception>
    public LayerMove(CubeFlag layer, bool direction = true, bool twice = false)
    {
      if (CubeFlagService.CountFlags(layer) == 1)
      {
        this.Layer = layer;
        this.Direction = direction;
        this.Twice = twice;
      }
      else
        throw new Exception("Impossible movement");
    }
 /// <summary>
 /// Returns true if the given CubeFlag describes a edge cube
 /// </summary>
 /// <param name="position">Defines the CubeFlag to be analyzed</param>
 /// <returns></returns>
 public static bool IsEdge(CubeFlag position) => ((position == (CubeFlag.TopLayer | CubeFlag.FrontSlice | CubeFlag.MiddleSliceSides))
                                                  || (position == (CubeFlag.TopLayer | CubeFlag.BackSlice | CubeFlag.MiddleSliceSides))
                                                  || (position == (CubeFlag.TopLayer | CubeFlag.RightSlice | CubeFlag.MiddleSlice))
                                                  || (position == (CubeFlag.TopLayer | CubeFlag.LeftSlice | CubeFlag.MiddleSlice))
                                                  || (position == (CubeFlag.MiddleLayer | CubeFlag.FrontSlice | CubeFlag.RightSlice))
                                                  || (position == (CubeFlag.MiddleLayer | CubeFlag.FrontSlice | CubeFlag.LeftSlice))
                                                  || (position == (CubeFlag.MiddleLayer | CubeFlag.BackSlice | CubeFlag.RightSlice))
                                                  || (position == (CubeFlag.MiddleLayer | CubeFlag.BackSlice | CubeFlag.LeftSlice))
                                                  || (position == (CubeFlag.BottomLayer | CubeFlag.FrontSlice | CubeFlag.MiddleSliceSides))
                                                  || (position == (CubeFlag.BottomLayer | CubeFlag.BackSlice | CubeFlag.MiddleSliceSides))
                                                  || (position == (CubeFlag.BottomLayer | CubeFlag.RightSlice | CubeFlag.MiddleSlice))
                                                  || (position == (CubeFlag.BottomLayer | CubeFlag.LeftSlice | CubeFlag.MiddleSlice)));
        /// <summary>
        /// Parses a string to a pattern item
        /// </summary>
        /// <param name="s">The string to be parsed
        /// 1: "currentPos, targetPos, currentOrientation"
        /// 2: "currentPos, currentOrientation" => any target position
        /// 3: "currentPos, targetPos" => any orientation
        /// </param>
        public static PatternItem Parse(string s)
        {
            string[] split = s.Split(',');

            if (split.Length == 1)
            {
                CubeFlag currPos = CubeFlagService.Parse(split[0]);
                if (Pattern.Positions.Count(p => p.Flags == currPos) != 1)
                {
                    throw new Exception("At least one orientation or position is not possible");
                }
                return(new PatternItem(new CubePosition(currPos), 0, currPos));
            }

            else if (split.Length == 2)
            {
                CubeFlag currPos     = CubeFlagService.Parse(split[0]);
                CubeFlag pos         = CubeFlagService.Parse(split[1]);
                int      orientation = 0;
                if (Pattern.Positions.Count(p => p.Flags == currPos) != 1 || (!int.TryParse(split[1], out orientation) && Pattern.Positions.Count(p => p.Flags == pos) != 1))
                {
                    throw new Exception("At least one orientation or position is not possible");
                }
                return(new PatternItem(new CubePosition(currPos), (Orientation)orientation, pos));
            }

            else if (split.Length == 3)
            {
                // check valid cube position
                CubeFlag currPos   = CubeFlagService.Parse(split[0]);
                CubeFlag targetPos = CubeFlagService.Parse(split[1]);
                if (!Pattern.Positions.Contains(new CubePosition(currPos)) || !Pattern.Positions.Contains(new CubePosition(targetPos)))
                {
                    throw new Exception("At least one position does not exist");
                }

                // check valid orientation
                int orientation = 0;
                if (!int.TryParse(split[2], out orientation))
                {
                    throw new Exception("At least one orientation is not possible");
                }

                return(new PatternItem(new CubePosition(currPos), (Orientation)orientation, targetPos));
            }
            else
            {
                throw new Exception("Parsing error");
            }
        }
Example #18
0
 /// <summary>
 /// Returns true if the given CubeFlag describes a edge cube
 /// </summary>
 /// <param name="position">Defines the CubeFlag to be analyzed</param>
 /// <returns></returns>
 public static bool IsEdge(CubeFlag position)
 {
     return((position == (CubeFlag.TopLayer | CubeFlag.FrontSlice | CubeFlag.MiddleSliceSides)) ||
            (position == (CubeFlag.TopLayer | CubeFlag.BackSlice | CubeFlag.MiddleSliceSides)) ||
            (position == (CubeFlag.TopLayer | CubeFlag.RightSlice | CubeFlag.MiddleSlice)) ||
            (position == (CubeFlag.TopLayer | CubeFlag.LeftSlice | CubeFlag.MiddleSlice)) ||
            (position == (CubeFlag.MiddleLayer | CubeFlag.FrontSlice | CubeFlag.RightSlice)) ||
            (position == (CubeFlag.MiddleLayer | CubeFlag.FrontSlice | CubeFlag.LeftSlice)) ||
            (position == (CubeFlag.MiddleLayer | CubeFlag.BackSlice | CubeFlag.RightSlice)) ||
            (position == (CubeFlag.MiddleLayer | CubeFlag.BackSlice | CubeFlag.LeftSlice)) ||
            (position == (CubeFlag.BottomLayer | CubeFlag.FrontSlice | CubeFlag.MiddleSliceSides)) ||
            (position == (CubeFlag.BottomLayer | CubeFlag.BackSlice | CubeFlag.MiddleSliceSides)) ||
            (position == (CubeFlag.BottomLayer | CubeFlag.RightSlice | CubeFlag.MiddleSlice)) ||
            (position == (CubeFlag.BottomLayer | CubeFlag.LeftSlice | CubeFlag.MiddleSlice)));
 }
Example #19
0
        /// <summary>
        /// Returns the CubeFlag of the Cube at the given 3D position
        /// </summary>
        /// <param name="i">Defines the XFlag (left to right)</param>
        /// <param name="j">Defines the YFlag (top to bottom)</param>
        /// <param name="k">Defines the ZFlag (front to back)</param>
        /// <returns></returns>
        public CubeFlag GenSideFlags(int i, int j, int k)
        {
            CubeFlag p = new CubeFlag();

            switch (i)
            {
            case -1:
                p |= CubeFlag.LeftSlice;
                break;

            case 0:
                p |= CubeFlag.MiddleSliceSides;
                break;

            case 1:
                p |= CubeFlag.RightSlice;
                break;
            }
            switch (j)
            {
            case -1:
                p |= CubeFlag.TopLayer;
                break;

            case 0:
                p |= CubeFlag.MiddleLayer;
                break;

            case 1:
                p |= CubeFlag.BottomLayer;
                break;
            }
            switch (k)
            {
            case -1:
                p |= CubeFlag.FrontSlice;
                break;

            case 0:
                p |= CubeFlag.MiddleSlice;
                break;

            case 1:
                p |= CubeFlag.BackSlice;
                break;
            }
            return(p);
        }
        /// <summary>
        /// Converts a CubeFlag into values from -1 to 1
        /// </summary>
        /// <param name="flag">todo: describe flag parameter on ToInt</param>
        /// <exception cref="Exception">Thrown when the CubeFlag is either invalid or has more than one flag</exception>
        public static int ToInt(CubeFlag flag)
        {
            if (IsXFlag(flag))
            {
                switch (flag)
                {
                    case CubeFlag.RightSlice:
                        return 1;

                    case CubeFlag.MiddleSliceSides:
                        return 0;

                    default:
                        return -1;
                }
            }
            if (IsYFlag(flag))
            {
                switch (flag)
                {
                    case CubeFlag.TopLayer:
                        return -1;

                    case CubeFlag.MiddleLayer:
                        return 0;

                    default:
                        return 1;
                }
            }
            if (IsZFlag(flag))
            {
                switch (flag)
                {
                    case CubeFlag.BackSlice:
                        return 1;

                    case CubeFlag.MiddleSlice:
                        return 0;

                    default:
                        return -1;
                }
            }
            if (flag == CubeFlag.None)
                return 0;
            throw new Exception("Flag can not be converted to an integer");
        }
Example #21
0
        /// <summary>
        /// Parses a notation into a collection of cube flags
        /// </summary>
        public static CubeFlag Parse(string notation)
        {
            CubeFlag flags = CubeFlag.None;

            for (int i = 0; i < notation.Length; i++)
            {
                switch (notation[i])
                {
                case 'R':
                    flags |= CubeFlag.RightSlice;
                    break;

                case 'L':
                    flags |= CubeFlag.LeftSlice;
                    break;

                case 'U':
                    flags |= CubeFlag.TopLayer;
                    break;

                case 'D':
                    flags |= CubeFlag.BottomLayer;
                    break;

                case 'F':
                    flags |= CubeFlag.FrontSlice;
                    break;

                case 'B':
                    flags |= CubeFlag.BackSlice;
                    break;

                case 'M':
                    flags |= CubeFlag.MiddleSliceSides;
                    break;

                case 'E':
                    flags |= CubeFlag.MiddleLayer;
                    break;

                case 'S':
                    flags |= CubeFlag.MiddleSlice;
                    break;
                }
            }
            return(flags);
        }
Example #22
0
        /// <summary>
        /// Adds an item at the end of the collection
        /// </summary>
        /// <param name="item">Defines the item which is meant to be added</param>
        /// <exception cref="System.Exception">Thrown if this movement would be impossible</exception>
        public void Add(LayerMove item)
        {
            CubeFlag flag = item.Layer;

            foreach (LayerMove m in _moves)
            {
                flag |= m.Layer;
            }
            if (CubeFlagService.IsPossibleMove(flag))
            {
                _moves.Add(item);
            }
            else
            {
                throw new Exception("Impossible movement");
            }
        }
Example #23
0
        /// <summary>
        /// Converts the given CubeFlag into a notation string
        /// </summary>
        public static string ToNotationString(CubeFlag flag)
        {
            string notation = string.Empty;

            if (flag.HasFlag(CubeFlag.TopLayer))
            {
                notation += "U";
            }
            if (flag.HasFlag(CubeFlag.BottomLayer))
            {
                notation += "D";
            }
            if (flag.HasFlag(CubeFlag.FrontSlice))
            {
                notation += "F";
            }
            if (flag.HasFlag(CubeFlag.RightSlice))
            {
                notation += "R";
            }
            if (flag.HasFlag(CubeFlag.BackSlice))
            {
                notation += "B";
            }
            if (flag.HasFlag(CubeFlag.LeftSlice))
            {
                notation += "L";
            }
            if (flag.HasFlag(CubeFlag.MiddleSlice))
            {
                notation += "S";
            }
            if (flag.HasFlag(CubeFlag.MiddleSliceSides))
            {
                notation += "M";
            }
            if (flag.HasFlag(CubeFlag.MiddleLayer))
            {
                notation += "E";
            }

            return(notation);
        }
Example #24
0
        /// <summary>
        /// Returns the center color of a slice
        /// </summary>
        /// <param name="slice">Defines the slice whose center color will be returned</param>
        public Color GetSliceColor(CubeFlag slice)
        {
            switch (slice)
            {
            case CubeFlag.TopLayer: return(this.TopColor);

            case CubeFlag.BottomLayer: return(this.BottomColor);

            case CubeFlag.FrontSlice: return(this.FrontColor);

            case CubeFlag.BackSlice: return(this.BackColor);

            case CubeFlag.LeftSlice: return(this.LeftColor);

            case CubeFlag.RightSlice: return(this.RightColor);

            default: return(Color.Black);
            }
        }
Example #25
0
        // *** CONSTRUCTOR ***

        /// <summary>
        /// Initializes a new instance of the Cube3D class
        /// </summary>
        /// <param name="location">Center point</param>
        /// <param name="scale">Scale</param>
        /// <param name="position">Position</param>
        /// <param name="faces">Faces</param>
        public Cube3D(Point3D location, double scale, CubeFlag position, IEnumerable <Face> faces)
        {
            this.Faces    = UniCube.GenFaces3D(position);
            this.Position = position;
            this.Location = location;
            this.Scale    = scale;
            this.Faces.ToList().ForEach(f =>
            {
                f.Color = faces.First(face => face.Position == f.Position).Color;
                f.Vertices.ToList().ForEach(e =>
                {
                    e.X *= scale;
                    e.Y *= scale;
                    e.Z *= scale;                     //scale
                    e.X += location.X;
                    e.Y += location.Y;
                    e.Z += location.Z;                     //translate
                });
            });
        }
 // *** CONSTRUCTOR ***
 /// <summary>
 /// Initializes a new instance of the Cube3D class
 /// </summary>
 /// <param name="location">Center point</param>
 /// <param name="scale">Scale</param>
 /// <param name="position">Position</param>
 /// <param name="faces">Faces</param>
 public Cube3D(Point3D location, double scale, CubeFlag position, IEnumerable<Face> faces)
 {
     this.Faces = UniCube.GenFaces3D(position);
     this.Position = position;
       this.Location = location;
       this.Scale = scale;
     this.Faces.ToList().ForEach(f =>
     {
         f.Color = faces.First(face => face.Position == f.Position).Color;
         f.Vertices.ToList().ForEach(e =>
         {
             e.X *= scale;
             e.Y *= scale;
             e.Z *= scale; //scale
             e.X += location.X;
             e.Y += location.Y;
             e.Z += location.Z; //translate
         });
     });
 }
Example #27
0
        /// <summary>
        /// Parses a notation string into a layer move
        /// </summary>
        /// <param name="notation">String to be parsed</param>
        /// <param name="move">The resulting layer move</param>
        /// <returns>True, if the string was successfully parsed into a layermove</returns>
        public static bool TryParse(string notation, out LayerMove move)
        {
            move = null;
            string   layer         = notation[0].ToString();
            CubeFlag rotationLayer = CubeFlagService.Parse(layer);

            char[] ccwChars  = new char[] { '\'', 'i' };
            bool   direction = !ccwChars.Any(c => notation.Contains(c));

            bool twice = notation.Contains("2");

            if (CubeFlagService.CountFlags(rotationLayer) == 1)
            {
                move = new LayerMove(rotationLayer, direction, twice);
                return(true);
            }
            else
            {
                return(false);
            }
        }
 /// <summary>
 /// Returns true if the flag is a ZFlag only
 /// </summary>
 /// <param name="flag">Defines the CubeFlag to be analyzed</param>
 /// <returns></returns>
 public static bool IsZFlag(CubeFlag flag) => CubeFlag.ZFlags.HasFlag(flag);
Example #29
0
 /// <summary>
 /// Returns true if the flag is a ZFlag only
 /// </summary>
 /// <param name="flag">Defines the CubeFlag to be analyzed</param>
 /// <returns></returns>
 public static bool IsZFlag(CubeFlag flag)
 {
     return(CubeFlag.ZFlags.HasFlag(flag));
 }
        /// <summary>
        /// Returns a CubeFlag which is the opposite of the parameter
        /// </summary>
        /// <param name="flag">Defines the parameter to be analyzed</param>
        /// <returns></returns>
        public static CubeFlag GetOppositeFlag(CubeFlag flag)
        {
            switch (flag)
            {
                case CubeFlag.TopLayer:
                    return CubeFlag.BottomLayer;

                case CubeFlag.BottomLayer:
                    return CubeFlag.TopLayer;

                case CubeFlag.FrontSlice:
                    return CubeFlag.BackSlice;

                case CubeFlag.BackSlice:
                    return CubeFlag.FrontSlice;

                case CubeFlag.LeftSlice:
                    return CubeFlag.RightSlice;

                case CubeFlag.RightSlice:
                    return CubeFlag.LeftSlice;

                case CubeFlag.MiddleLayer:
                case CubeFlag.MiddleSlice:
                case CubeFlag.MiddleSliceSides:
                    return flag;

                default:
                    return CubeFlag.None;
            }
        }
        /// <summary>
        /// Returns the next flag after a layer rotation
        /// </summary>
        /// <param name="rotationLayer">Rotation layer</param>
        /// <param name="direction">Rotation direction</param>
        /// <returns>Next cube flag</returns>
        public static CubeFlag NextCubeFlag(CubeFlag flag, CubeFlag rotationLayer, bool direction = true)
        {
            var nextFlag = CubeFlag.None;

            if (CountFlags(flag) != 1)
            {
                return ExceptFlag(nextFlag, CubeFlag.None);
            }
            if (IsXFlag(rotationLayer))
            {
                if (rotationLayer == CubeFlag.LeftSlice) direction = !direction;
                if (!direction && !IsXFlag(flag)) flag = GetOppositeFlag(flag);
                switch (flag)
                {
                    case CubeFlag.FrontSlice: nextFlag = CubeFlag.TopLayer; break;
                    case CubeFlag.MiddleSlice: nextFlag = CubeFlag.MiddleLayer; break;
                    case CubeFlag.BackSlice: nextFlag = CubeFlag.BottomLayer; break;
                    case CubeFlag.TopLayer: nextFlag = CubeFlag.BackSlice; break;
                    case CubeFlag.MiddleLayer: nextFlag = CubeFlag.MiddleSlice; break;
                    case CubeFlag.BottomLayer: nextFlag = CubeFlag.FrontSlice; break;
                    default: nextFlag = flag; break;
                }
            }
            else if (IsYFlag(rotationLayer))
            {
                if (rotationLayer == CubeFlag.BottomLayer) direction = !direction;
                if (!direction && !IsYFlag(flag)) flag = GetOppositeFlag(flag);
                switch (flag)
                {
                    case CubeFlag.FrontSlice: nextFlag = CubeFlag.LeftSlice; break;
                    case CubeFlag.MiddleSlice: nextFlag = CubeFlag.MiddleSliceSides; break;
                    case CubeFlag.BackSlice: nextFlag = CubeFlag.RightSlice; break;
                    case CubeFlag.LeftSlice: nextFlag = CubeFlag.BackSlice; break;
                    case CubeFlag.MiddleSliceSides: nextFlag = CubeFlag.MiddleSlice; break;
                    case CubeFlag.RightSlice: nextFlag = CubeFlag.FrontSlice; break;
                    default: nextFlag = flag; break;
                }
            }
            else if (IsZFlag(rotationLayer))
            {
                if (rotationLayer == CubeFlag.BackSlice) direction = !direction;
                if (!direction && !IsZFlag(flag)) flag = GetOppositeFlag(flag);
                switch (flag)
                {
                    case CubeFlag.TopLayer: nextFlag = CubeFlag.RightSlice; break;
                    case CubeFlag.MiddleLayer: nextFlag = CubeFlag.MiddleSliceSides; break;
                    case CubeFlag.BottomLayer: nextFlag = CubeFlag.LeftSlice; break;
                    case CubeFlag.LeftSlice: nextFlag = CubeFlag.TopLayer; break;
                    case CubeFlag.MiddleSliceSides: nextFlag = CubeFlag.MiddleLayer; break;
                    case CubeFlag.RightSlice: nextFlag = CubeFlag.BottomLayer; break;
                    default: nextFlag = flag; break;
                }
            }
            return ExceptFlag(nextFlag, CubeFlag.None);
        }
Example #32
0
 /// <summary>
 /// Returns the first ZFlag in the given CubeFlag
 /// </summary>
 /// <param name="flags">Defines the CubeFlag to be analyzed</param>
 /// <returns></returns>
 public static CubeFlag FirstZFlag(CubeFlag flags)
 {
     return(FirstNotInvalidFlag(flags, CubeFlag.XFlags | CubeFlag.YFlags));
 }
 /// <summary>
 /// Returns the first flag which exists in the first and second parameter but not in the third parameter
 /// </summary>
 /// <param name="a">Defines the first CubeFlag</param>
 /// <param name="b">Defines the second CubeFlag</param>
 /// <param name="exclude">Defines the CubeFlag which is not allowed</param>
 /// <returns></returns>
 public static CubeFlag GetFirstNotInvalidCommonFlag(CubeFlag a, CubeFlag b, CubeFlag exclude) => FirstNotInvalidFlag(CommonFlags(a, b), exclude);
        private void SolveCrossTopLayer()
        {
            // Step 1: Get edges with the color of the top face
            IEnumerable <Cube> topEdges = Rubik.Cubes.Where(c => c.IsEdge).Where(c => c.Position.HasFlag(CubeFlag.TopLayer));

            // Step 2: Check if the cube is insoluble
            if (topEdges.Count(tE => tE.Faces.First(f => f.Position == FacePosition.Top).Color == Rubik.TopColor) % 2 != 0)
            {
                return;
            }

            var correctEdges             = topEdges.Where(c => c.Faces.First(f => f.Position == FacePosition.Top).Color == Rubik.TopColor);
            var solveTopCrossAlgorithmI  = new Algorithm("F R U R' U' F'");
            var solveTopCrossAlgorithmII = new Algorithm("F S R U R' U' F' S'");

            // Step 3: Solve the cross on the top layer
            if (Rubik.CountEdgesWithCorrectOrientation() == 0)
            {
                SolverAlgorithm(solveTopCrossAlgorithmI);
                correctEdges = topEdges.Where(c => c.Faces.First(f => f.Position == FacePosition.Top).Color == Rubik.TopColor);
            }

            if (Rubik.CountEdgesWithCorrectOrientation() == 2)
            {
                var firstCorrect  = correctEdges.First();
                var secondCorrect = correctEdges.First(f => f != firstCorrect);

                bool opposite = false;

                foreach (CubeFlag flag in firstCorrect.Position.GetFlags())
                {
                    CubeFlag pos = CubeFlagService.GetOppositeFlag(flag);

                    if (secondCorrect.Position.HasFlag(pos) && pos != CubeFlag.None)
                    {
                        opposite = true;
                        break;
                    }
                }

                if (opposite)
                {
                    while (correctEdges.Count(c => c.Position.HasFlag(CubeFlag.RightSlice)) != 1)
                    {
                        SolverMove(CubeFlag.TopLayer, true);
                    }

                    SolverAlgorithm(solveTopCrossAlgorithmI);
                }
                else
                {
                    while (correctEdges.Count(c => c.Position.HasFlag(CubeFlag.RightSlice) || c.Position.HasFlag(CubeFlag.FrontSlice)) != 2)
                    {
                        SolverMove(CubeFlag.TopLayer, true);
                    }

                    SolverAlgorithm(solveTopCrossAlgorithmII);
                }
            }

            // Step 4: Move the edges of the cross to their target positions
            while (topEdges.Count(c => c.Position.Flags == GetTargetFlags(c)) < 4)
            {
                IEnumerable <Cube> correctEdges2 = topEdges.Where(c => c.Position.Flags == GetTargetFlags(c));
                while (correctEdges2.Count() < 2)
                {
                    SolverMove(CubeFlag.TopLayer, true);
                }

                CubeFlag rightSlice = CubeFlagService.FromFacePosition(correctEdges2.First().Faces
                                                                       .First(f => f.Position != FacePosition.Top && f.Color != Color.Black).Position);
                SolverMove(CubeFlag.TopLayer, false);

                if (correctEdges2.Count(c => c.Position.HasFlag(rightSlice)) == 0)
                {
                    SolverMove(CubeFlag.TopLayer, true);
                }
                else
                {
                    SolverMove(CubeFlag.TopLayer, true);

                    rightSlice =
                        CubeFlagService.FromFacePosition(
                            correctEdges2
                            .First(cE => !cE.Position.HasFlag(rightSlice))
                            .Faces
                            .First(f =>
                                   f.Position != FacePosition.Top &&
                                   f.Color != Color.Black
                                   )
                            .Position
                            );
                }

                // Algorithm: R U R' U R U U R'
                SolverAlgorithm(
                    "{0} U {0}' U {0} U U {0}'",
                    CubeFlagService.ToNotationString(rightSlice)
                    );

                while (correctEdges2.Count() < 2)
                {
                    SolverMove(CubeFlag.TopLayer, true);
                }
            }
        }
Example #35
0
        private void InitPatterns(CubeFlag r, CubeFlag f)
        {
            CubeFlag l    = CubeFlagService.GetOppositeFlag(r);
            CubeFlag b    = CubeFlagService.GetOppositeFlag(f);
            bool     rIsX = CubeFlagService.IsXFlag(r);

            // edge orientation changes depending on the target slot
            Orientation correct = (r == CubeFlag.BackSlice && f == CubeFlag.RightSlice) || (f == CubeFlag.LeftSlice && r == CubeFlag.FrontSlice)
        ? Orientation.Correct : Orientation.Clockwise;
            Orientation clockwise = correct == Orientation.Correct ? Orientation.Clockwise : Orientation.Correct;

            patterns = new Dictionary <Pattern, Algorithm>()
            {
                #region Corner correct oriented at targetposition
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | f | (rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice)), correct, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos), Orientation.Correct, CornerTargetPos)
                    }),
                    new Algorithm("U {0} U {0}' U' {1}' U' {1}", CubeFlagService.ToNotationString(r), CubeFlagService.ToNotationString(f))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | r | (!rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice)), clockwise, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos), Orientation.Correct, CornerTargetPos)
                    }),
                    new Algorithm("U' {1}' U' {1} U {0} U {0}'", CubeFlagService.ToNotationString(r), CubeFlagService.ToNotationString(f))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(EdgeTargetPos), Orientation.Clockwise, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos), Orientation.Correct, CornerTargetPos)
                    }),
                    new Algorithm("{0}2 U2 {1} {0}2 {1}' U2 {0}' U {0}'", CubeFlagService.ToNotationString(r), CubeFlagService.ToNotationString(f))
                },
                #endregion

                #region Corner clockwise oriented at target position
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | f | (rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice)), correct, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos), Orientation.CounterClockwise, CornerTargetPos)
                    }),
                    new Algorithm("{0}' U {0} U' {0}' U {0}", CubeFlagService.ToNotationString(f))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | r | (!rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice)), clockwise, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos), Orientation.CounterClockwise, CornerTargetPos)
                    }),
                    new Algorithm("{0} U {0}' U' {0} U {0}'", CubeFlagService.ToNotationString(r))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(EdgeTargetPos), Orientation.Correct, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos), Orientation.CounterClockwise, CornerTargetPos)
                    }),
                    new Algorithm("{0} U2 {0} U {0}' U {0} U2 {0}2", CubeFlagService.ToNotationString(r))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(EdgeTargetPos), Orientation.Clockwise, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos), Orientation.CounterClockwise, CornerTargetPos)
                    }),
                    new Algorithm("{0} U {0}' U' {0} U' {0}' U2 {1}' U' {1}", CubeFlagService.ToNotationString(r), CubeFlagService.ToNotationString(f))
                },
                #endregion

                #region Corner counter-clockwise oriented at target position
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | f | (rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice)), correct, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos), Orientation.Clockwise, CornerTargetPos)
                    }),
                    new Algorithm("{0}' U' {0} U {0}' U' {0}", CubeFlagService.ToNotationString(f))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | r | (!rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice)), clockwise, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos), Orientation.Clockwise, CornerTargetPos)
                    }),
                    new Algorithm("{0} U' {0}' U {0} U' {0}'", CubeFlagService.ToNotationString(r))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(EdgeTargetPos), Orientation.Correct, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos), Orientation.Clockwise, CornerTargetPos)
                    }),
                    new Algorithm("{0}' U' {0} U2 {0}' U {0} U' {0}' U' {0}", CubeFlagService.ToNotationString(f))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(EdgeTargetPos), Orientation.Clockwise, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos), Orientation.Clockwise, CornerTargetPos)
                    }),
                    new Algorithm("{1}' U' {1} U {1}' U {1} U2 {0} U {0}'", CubeFlagService.ToNotationString(r), CubeFlagService.ToNotationString(f))
                },
                #endregion

                #region Corner correct oriented in top layer
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(EdgeTargetPos), Orientation.Correct, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Correct, CornerTargetPos)
                    }),
                    new Algorithm("{0} U {0}' U' {0} U {0}' U' {0} U {0}'", CubeFlagService.ToNotationString(r))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(EdgeTargetPos), Orientation.Clockwise, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Correct, CornerTargetPos)
                    }),
                    new Algorithm("{0} U' {0}' U {1}' U {1}", CubeFlagService.ToNotationString(r), CubeFlagService.ToNotationString(f))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | b), clockwise, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Correct, CornerTargetPos)
                    }),
                    new Algorithm("U {0} U2 {0}' U {0} U' {0}'", CubeFlagService.ToNotationString(r))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | b), correct, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Correct, CornerTargetPos)
                    }),
                    new Algorithm("{0}' U {0} U2 {0}' U' {0}", CubeFlagService.ToNotationString(f))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (!rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | l), clockwise, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Correct, CornerTargetPos)
                    }),
                    new Algorithm("{0} U' {0}' U2 {0} U {0}'", CubeFlagService.ToNotationString(r))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (!rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | l), correct, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Correct, CornerTargetPos)
                    }),
                    new Algorithm("U' {0}' U2 {0} U' {0}' U {0}", CubeFlagService.ToNotationString(f))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | f), correct, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Correct, CornerTargetPos)
                    }),
                    new Algorithm("{0}' U2 {0} U {0}' U' {0}", CubeFlagService.ToNotationString(f))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | f), clockwise, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Correct, CornerTargetPos)
                    }),
                    new Algorithm("{0}' U' {1}' U {1} {0} {1}' U {1}", CubeFlagService.ToNotationString(r), CubeFlagService.ToNotationString(f))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (!rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | r), correct, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Correct, CornerTargetPos)
                    }),
                    new Algorithm("{0} U2 {0}' U' {0} U {0}'", CubeFlagService.ToNotationString(r))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (!rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | r), clockwise, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Correct, CornerTargetPos)
                    }),
                    new Algorithm("{0} U {1} U' {1}' {0}' {1} U' {1}'", CubeFlagService.ToNotationString(f), CubeFlagService.ToNotationString(r))
                },
                #endregion

                #region Corner counter-clockwise oriented in top layer
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(EdgeTargetPos), Orientation.Correct, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.CounterClockwise, CornerTargetPos)
                    }),
                    new Algorithm("U' {0} U' {0}' U2 {0} U' {0}'", CubeFlagService.ToNotationString(r))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(EdgeTargetPos), Orientation.Clockwise, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.CounterClockwise, CornerTargetPos)
                    }),
                    new Algorithm("U' {0} U {0}' U {1}' U' {1}", CubeFlagService.ToNotationString(r), CubeFlagService.ToNotationString(f))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (!rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | r), clockwise, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.CounterClockwise, CornerTargetPos)
                    }),
                    new Algorithm("U {0} U' {0}'", CubeFlagService.ToNotationString(r))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (!rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | r), correct, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.CounterClockwise, CornerTargetPos)
                    }),
                    new Algorithm("{0} U2 {0}2 U' {0}2 U' {0}'", CubeFlagService.ToNotationString(f))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | b), clockwise, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.CounterClockwise, CornerTargetPos)
                    }),
                    new Algorithm("U' {0} U {0}' U2 {0} U' {0}'", CubeFlagService.ToNotationString(r))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | b), correct, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.CounterClockwise, CornerTargetPos)
                    }),
                    new Algorithm("U' {0} U' {0}' U {1}' U' {1}", CubeFlagService.ToNotationString(r), CubeFlagService.ToNotationString(f))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (!rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | l), correct, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.CounterClockwise, CornerTargetPos)
                    }),
                    new Algorithm("{0}' U' {0}", CubeFlagService.ToNotationString(f))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (!rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | l), clockwise, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.CounterClockwise, CornerTargetPos)
                    }),
                    new Algorithm("U' {0} U2 {0}' U2 {0} U' {0}'", CubeFlagService.ToNotationString(r))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | f), correct, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.CounterClockwise, CornerTargetPos)
                    }),
                    new Algorithm("d {0}' U {0} U' {0}' U' {0}", CubeFlagService.ToNotationString(r))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | f), clockwise, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.CounterClockwise, CornerTargetPos)
                    }),
                    new Algorithm("{0}' U {0} U2 {1} U {1}'", CubeFlagService.ToNotationString(f), CubeFlagService.ToNotationString(r))
                },
                #endregion

                #region Corner clockwise oriented in top layer
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(EdgeTargetPos), Orientation.Correct, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Clockwise, CornerTargetPos)
                    }),
                    new Algorithm("U {0} U {0}' U2 {0} U {0}'", CubeFlagService.ToNotationString(r))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(EdgeTargetPos), Orientation.Clockwise, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Clockwise, CornerTargetPos)
                    }),
                    new Algorithm("U2 {1}' U {1} U {0} U {0}'", CubeFlagService.ToNotationString(r), CubeFlagService.ToNotationString(f))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (!rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | r), clockwise, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Clockwise, CornerTargetPos)
                    }),
                    new Algorithm("U' {0} U' {0}' U {0} U {0}'", CubeFlagService.ToNotationString(r))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (!rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | r), correct, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Clockwise, CornerTargetPos)
                    }),
                    new Algorithm("{1} U' {1}' U2 {0}' U' {0}", CubeFlagService.ToNotationString(f), CubeFlagService.ToNotationString(r))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | b), correct, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Clockwise, CornerTargetPos)
                    }),
                    new Algorithm("d {0}' U2 {0} U2 {0}' U {0}", CubeFlagService.ToNotationString(r))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | b), clockwise, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Clockwise, CornerTargetPos)
                    }),
                    new Algorithm("{0} U {0}'", CubeFlagService.ToNotationString(r))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (!rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | l), correct, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Clockwise, CornerTargetPos)
                    }),
                    new Algorithm("d {0}' U' {0} U2 {0}' U {0}", CubeFlagService.ToNotationString(r))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (!rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | l), clockwise, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Clockwise, CornerTargetPos)
                    }),
                    new Algorithm("d {0}' U {0} d' {0} U {0}'", CubeFlagService.ToNotationString(r))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | f), clockwise, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Clockwise, CornerTargetPos)
                    }),
                    new Algorithm("{0}' U2 {0}2 U {0}2 U {0}", CubeFlagService.ToNotationString(r))
                },
                {
                    new Pattern(new List <PatternItem>()
                    {
                        new PatternItem(new CubePosition(CubeFlag.TopLayer | (rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | f), correct, EdgeTargetPos),
                        new PatternItem(new CubePosition(CornerTargetPos & ~CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Clockwise, CornerTargetPos)
                    }),
                    new Algorithm("U' {0}' U {0}", CubeFlagService.ToNotationString(f))
                }
                #endregion
            };
        }
Example #36
0
        // ** ENLARGE RENDER QUEUE **

        /// <summary>
        /// Registers a new animated rotation
        /// </summary>
        /// <param name="layer">Rotation layer</param>
        /// <param name="direction">Direction of rotation</param>
        public void RotateLayerAnimated(CubeFlag layer, bool direction)
        {
            RotateLayerAnimated(new LayerMove(layer, direction), this.RotationSpeed);
        }
        private void CompleteLastLayer()
        {
            // Step 1: Get edges with the color of the top face
            IEnumerable <Cube> topCorners =
                Rubik.Cubes
                .Where(c => c.IsCorner)
                .Where(c => c.Position.HasFlag(CubeFlag.TopLayer));

            // Step 2: Bring corners to their target position
            while (topCorners.Count(c => c.Position.Flags == GetTargetFlags(c)) < 4)
            {
                var correctCorners = topCorners.Where(c => c.Position.Flags == GetTargetFlags(c));

                CubeFlag rightSlice;
                if (correctCorners.Count() != 0)
                {
                    Cube firstCube = correctCorners.First();
                    Face rightFace = firstCube.Faces.First(f => f.Color != Color.Black && f.Position != FacePosition.Top);

                    rightSlice = CubeFlagService.FromFacePosition(rightFace.Position);

                    if (!new TestScenario(Rubik, new LayerMove(rightSlice, true, false)).TestCubePosition(firstCube, CubeFlag.TopLayer))
                    {
                        rightSlice =
                            CubeFlagService.FromFacePosition(
                                firstCube.Faces
                                .First(f =>
                                       f.Color != rightFace.Color &&
                                       f.Color != Color.Black &&
                                       f.Position != FacePosition.Top
                                       ).Position
                                );
                    }
                }
                else
                {
                    rightSlice = CubeFlag.RightSlice;
                }

                SolverAlgorithm(
                    "U {0} U' {1}' U {0}' U' {1}",
                    CubeFlagService.ToNotationString(rightSlice),
                    CubeFlagService.ToNotationString(CubeFlagService.GetOppositeFlag(rightSlice))
                    );
            }

            // Step 3: Orientation of the corners on the top layer
            Face rightFac = topCorners.First().Faces.First(f => f.Color != Color.Black && f.Position != FacePosition.Top);

            var scenario       = new TestScenario(this.Rubik, new LayerMove(CubeFlagService.FromFacePosition(rightFac.Position), true, false));
            var scenarioPassed = scenario.TestCubePosition(topCorners.First(), CubeFlag.TopLayer);

            var positionForRightSlic =
                !scenarioPassed
                    ? rightFac.Position
                    : topCorners.First().Faces.First(f => f.Color != rightFac.Color && f.Color != Color.Black && f.Position != FacePosition.Top).Position;

            CubeFlag rightSlic = CubeFlagService.FromFacePosition(positionForRightSlic);



            foreach (Cube c in topCorners)
            {
                while (!c.Position.HasFlag(rightSlic))
                {
                    SolverMove(CubeFlag.TopLayer, true);
                }

                if (!new TestScenario(Rubik, new LayerMove(rightSlic, true, false)).TestCubePosition(c, CubeFlag.TopLayer))
                {
                    SolverMove(CubeFlag.TopLayer, true);
                }

                // Algorithm: R' D' R D
                while (c.Faces.First(f => f.Position == FacePosition.Top).Color != Rubik.TopColor)
                {
                    SolverAlgorithm("{0}' D' {0} D", CubeFlagService.ToNotationString(rightSlic));
                }
            }

            while (topCorners.Count(tC => tC.Position.Flags == GetTargetFlags(tC)) != 4)
            {
                SolverMove(CubeFlag.TopLayer, true);
            }
        }
        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 SolveFirstCross()
        {
            // Step 1: Get the edges with target position on the bottom layer
            IEnumerable <Cube> bottomEdges = Rubik.Cubes.Where(c => c.IsEdge && GetTargetFlags(c).HasFlag(CubeFlag.BottomLayer));

            // Step 2: Rotate a correct orientated edge of the bottom layer to target position
            IEnumerable <Cube> solvedBottomEdges = bottomEdges.Where(bE => bE.Position.Flags == GetTargetFlags(bE) && bE.Faces.First(f => f.Color == Rubik.BottomColor).Position == FacePosition.Bottom);

            if (bottomEdges.Count(bE => bE.Position.HasFlag(CubeFlag.BottomLayer) && bE.Faces.First(f => f.Color == Rubik.BottomColor).Position == FacePosition.Bottom) > 0)
            {
                while (solvedBottomEdges.Count() < 1)
                {
                    SolverMove(CubeFlag.BottomLayer, true);
                    solvedBottomEdges = bottomEdges.Where(bE => bE.Position.Flags == GetTargetFlags(bE) && bE.Faces.First(f => f.Color == Rubik.BottomColor).Position == FacePosition.Bottom);
                }
            }

            // Step 3: Solve incorrect edges of the bottom layer
            while (solvedBottomEdges.Count() < 4)
            {
                IEnumerable <Cube> unsolvedBottomEdges = bottomEdges.Except(solvedBottomEdges);
                Cube e = (unsolvedBottomEdges.FirstOrDefault(c => c.Position.HasFlag(CubeFlag.TopLayer)) != null)
            ? unsolvedBottomEdges.FirstOrDefault(c => c.Position.HasFlag(CubeFlag.TopLayer)) : unsolvedBottomEdges.First();
                Color secondColor = e.Colors.First(co => co != Rubik.BottomColor && co != Color.Black);

                if (e.Position.Flags != GetTargetFlags(e))
                {
                    // Rotate to top layer
                    CubeFlag layer = CubeFlagService.FromFacePosition(e.Faces.First(f => (f.Color == Rubik.BottomColor || f.Color == secondColor) &&
                                                                                    f.Position != FacePosition.Top && f.Position != FacePosition.Bottom).Position);

                    CubeFlag targetLayer = CubeFlagService.FromFacePosition(StandardCube.Cubes.First(cu => CollectionMethods.ScrambledEquals(cu.Colors, e.Colors))
                                                                            .Faces.First(f => f.Color == secondColor).Position);

                    if (e.Position.HasFlag(CubeFlag.MiddleLayer))
                    {
                        if (layer == targetLayer)
                        {
                            while (!e.Position.HasFlag(CubeFlag.BottomLayer))
                            {
                                SolverMove(layer, true);
                            }
                        }
                        else
                        {
                            SolverMove(layer, true);
                            if (e.Position.HasFlag(CubeFlag.TopLayer))
                            {
                                SolverMove(CubeFlag.TopLayer, true);
                                SolverMove(layer, false);
                            }
                            else
                            {
                                for (int i = 0; i < 2; i++)
                                {
                                    SolverMove(layer, true);
                                }
                                SolverMove(CubeFlag.TopLayer, true);
                                SolverMove(layer, true);
                            }
                        }
                    }
                    if (e.Position.HasFlag(CubeFlag.BottomLayer))
                    {
                        for (int i = 0; i < 2; i++)
                        {
                            SolverMove(layer, true);
                        }
                    }

                    // Rotate over target position
                    while (!e.Position.HasFlag(targetLayer))
                    {
                        SolverMove(CubeFlag.TopLayer, true);
                    }

                    //Rotate to target position
                    for (int i = 0; i < 2; i++)
                    {
                        SolverMove(targetLayer, true);
                    }
                    CubeFlag targetPos = GetTargetFlags(e);
                }

                // Flip the incorrect orientated edges with the algorithm: Fi D Ri Di
                if (Solvability.GetOrientation(Rubik, e) != 0)
                {
                    CubeFlag frontSlice = CubeFlagService.FromFacePosition(e.Faces.First(f => f.Color == Rubik.BottomColor).Position);

                    SolverMove(frontSlice, false);
                    SolverMove(CubeFlag.BottomLayer, true);

                    CubeFlag rightSlice = CubeFlagService.FromFacePosition(e.Faces.First(f => f.Color == secondColor).Position);

                    SolverMove(rightSlice, false);
                    SolverMove(CubeFlag.BottomLayer, false);
                }
                List <Face> faces = e.Faces.ToList();
                solvedBottomEdges = bottomEdges.Where(bE => bE.Position.Flags == GetTargetFlags(bE) && bE.Faces.First(f => f.Color == Rubik.BottomColor).Position == FacePosition.Bottom);
            }
        }
Example #40
0
 /// <summary>
 /// Returns true if this CubeFlag has the given CubeFlag
 /// </summary>
 /// <param name="flag">Defines the CubeFlag which will be checked</param>
 /// <returns></returns>
 public bool HasFlag(CubeFlag flag)
 {
     return(this.Flags.HasFlag(flag));
 }
 public F2LPattern(CubeFlag edgeTargetPos, CubeFlag cornerTargetPos, CubeFlag rightSlice, CubeFlag frontSlice)
 {
   this.CornerTargetPos = cornerTargetPos;
   this.EdgeTargetPos = edgeTargetPos;
     this.InitPatterns(rightSlice, frontSlice);
 }
Example #42
0
        // *** CONSTRUCTOR ***

        /// <summary>
        /// Initializes a new instance of the Face3D class
        /// </summary>
        /// <param name="vertices">Vertices of the 3D face</param>
        /// <param name="color">Color</param>
        /// <param name="position">Position</param>
        /// <param name="masterPosition">Position of the parent 3D cube</param>
        public Face3D(IEnumerable <Point3D> vertices, Color color, FacePosition position, CubeFlag masterPosition)
        {
            this.Vertices       = vertices;
            this.Color          = color;
            this.Position       = position;
            this.MasterPosition = masterPosition;
        }
Example #43
0
 /// <summary>
 /// Constructor with X-, Y- and ZFlag
 /// </summary>
 /// <param name="x">Defines the XFlag</param>
 /// <param name="y">Defines the YFlag</param>
 /// <param name="z">Defines the ZFlag</param>
 public CubePosition(CubeFlag x, CubeFlag y, CubeFlag z)
 {
     this.X = x;
     this.Y = y;
     this.Z = z;
 }
        private void CompleteMiddleLayer()
        {
            // Step 1: Get the egdes of the middle layer
            List <Cube> middleEdges =
                Rubik.Cubes
                .Where(c => c.IsEdge)
                .Where(c => GetTargetFlags(c).HasFlag(CubeFlag.MiddleLayer))
                .ToList();

            List <Face> coloredFaces = new List <Face>();

            Rubik.Cubes.Where(cu => cu.IsCenter)
            .ToList()
            .ForEach(cu =>
                     coloredFaces.Add(cu.Faces.First(f => f.Color != Color.Black))
                     );

            IEnumerable <Cube> solvedMiddleEdges =
                middleEdges
                .Where(mE =>
                       mE.Position.Flags == GetTargetFlags(mE) &&
                       mE.Faces.Count(f => coloredFaces.Count(cf => cf.Color == f.Color && cf.Position == f.Position) == 1) == 2
                       );

            // Step 2: solve incorrect middle edges
            while (solvedMiddleEdges.Count() < 4)
            {
                IEnumerable <Cube> unsolvedMiddleEdges = middleEdges.Except(solvedMiddleEdges);
                Cube c =
                    (unsolvedMiddleEdges.FirstOrDefault(cu => !cu.Position.HasFlag(CubeFlag.MiddleLayer)) != null)
                        ? unsolvedMiddleEdges.First(cu => !cu.Position.HasFlag(CubeFlag.MiddleLayer))
                        : unsolvedMiddleEdges.First();

                // Rotate to top layer
                if (!c.Position.HasFlag(CubeFlag.TopLayer))
                {
                    Face     frontFace  = c.Faces.First(f => f.Color != Color.Black);
                    CubeFlag frontSlice = CubeFlagService.FromFacePosition(frontFace.Position);
                    Face     face       = c.Faces.First(f => f.Color != Color.Black && f.Color != frontFace.Color);
                    CubeFlag slice      = CubeFlagService.FromFacePosition(face.Position);

                    if (new TestScenario(Rubik, new LayerMove(slice, true, false)).TestCubePosition(c, CubeFlag.TopLayer))
                    {
                        // Algorithm to the right: U R Ui Ri Ui Fi U F
                        SolverAlgorithm(
                            "U {0} U' {0}' U' {1}' U {1}",
                            CubeFlagService.ToNotationString(slice),
                            CubeFlagService.ToNotationString(frontSlice)
                            );
                    }
                    else
                    {
                        // Algorithm to the left: Ui Li U L U F Ui Fi
                        SolverAlgorithm(
                            "U' {0}' U {0} U {1} U' {1}'",
                            CubeFlagService.ToNotationString(slice),
                            CubeFlagService.ToNotationString(frontSlice)
                            );
                    }
                }

                // Rotate to start position for the algorithm
                List <Cube> centers =
                    Rubik.Cubes
                    .Where(m => m.IsCenter)
                    .Where(m =>
                {
                    var thing2 =
                        m.Colors.First(co => co != Color.Black) ==
                        c.Faces.First(f => f.Color != Color.Black && f.Position != FacePosition.Top).Color;

                    var thing3 =
                        (m.Position.Flags & ~CubeFlag.MiddleLayer) == (c.Position.Flags & ~CubeFlag.TopLayer);

                    return(thing2 && thing3);
                })
                    .ToList();

                while (!centers.Any())
                {
                    SolverMove(CubeFlag.TopLayer, true);

                    centers =
                        Rubik.Cubes
                        .Where(cu => cu.IsCenter)
                        .Where(m =>
                               m.Colors.First(co => co != Color.Black) == c.Faces.First(f => f.Color != Color.Black && f.Position != FacePosition.Top).Color &&
                               (m.Position.Flags & ~CubeFlag.MiddleLayer) == (c.Position.Flags & ~CubeFlag.TopLayer)
                               )
                        .ToList();
                }

                // Rotate to target position
                Face     frontFac  = c.Faces.First(f => f.Color != Color.Black && f.Position != FacePosition.Top);
                CubeFlag frontSlic = CubeFlagService.FromFacePosition(frontFac.Position);

                CubeFlag slic = CubeFlagService.FirstNotInvalidFlag(GetTargetFlags(c), CubeFlag.MiddleLayer | frontSlic);

                if (!new TestScenario(Rubik, new LayerMove(CubeFlag.TopLayer, true, false)).TestCubePosition(c, slic))
                {
                    // Algorithm to the right: U R Ui Ri Ui Fi U F
                    SolverAlgorithm(
                        "U {0} U' {0}' U' {1}' U {1}",
                        CubeFlagService.ToNotationString(slic),
                        CubeFlagService.ToNotationString(frontSlic)
                        );
                }
                else
                {
                    // Algorithm to the left: Ui Li U L U F Ui Fi
                    SolverAlgorithm(
                        "U' {0}' U {0} U {1} U' {1}'",
                        CubeFlagService.ToNotationString(slic),
                        CubeFlagService.ToNotationString(frontSlic)
                        );
                }

                solvedMiddleEdges =
                    middleEdges.Where(mE =>
                                      mE.Faces.Count(f =>
                                                     coloredFaces.Count(cf => cf.Color == f.Color && cf.Position == f.Position) == 1
                                                     ) == 2
                                      );
            }
        }
 /// <summary>
 /// Returns a CubeFlag which contains all flags which exist in both the first and the second parameter
 /// </summary>
 /// <param name="first">Defines the first CubeFlag</param>
 /// <param name="second">Defines the second CubeFlag</param>
 /// <returns></returns>
 public static CubeFlag CommonFlags(CubeFlag first, CubeFlag second) => GetFlags(first).Cast<CubeFlag>().Where(flag => second.HasFlag(flag)).Aggregate(CubeFlag.None, (current, flag) => current | flag);
 /// <summary>
 /// Initializes a new instance of the PatternItem class
 /// </summary>
 /// <param name="currPos">Current position</param>
 /// <param name="currOrientation">
 /// Current orientation
 /// Corner: Correct = 0, Clockwise = 1, Counter-Clockwise = 2
 /// Edge: Correct = 0, Flipped = 1
 /// Center always 0
 /// </param>
 /// <param name="targetPos">Target position</param>
 public PatternItem(CubePosition currPos, Orientation currOrientation, CubeFlag targetPos)
 {
     this.CurrentPosition    = currPos;
     this.CurrentOrientation = currOrientation;
     this.TargetPosition     = targetPos;
 }
        /// <summary>
        /// Converts a CubeFlag into a FacePosition
        /// </summary>
        /// <param name="cubePos">Defines the CubeFlag to be converted</param>
        /// <returns></returns>
        public static FacePosition ToFacePosition(CubeFlag cubePos)
        {
            switch (cubePos)
            {
                case CubeFlag.TopLayer:
                    return FacePosition.Top;

                case CubeFlag.BottomLayer:
                    return FacePosition.Bottom;

                case CubeFlag.LeftSlice:
                    return FacePosition.Left;

                case CubeFlag.RightSlice:
                    return FacePosition.Right;

                case CubeFlag.BackSlice:
                    return FacePosition.Back;

                case CubeFlag.FrontSlice:
                    return FacePosition.Front;

                default:
                    return FacePosition.None;
            }
        }
        private void SolveFirstCross()
        {
            // Step 1: Get the edges with target position on the bottom layer
            IEnumerable <Cube> bottomEdges =
                Rubik.Cubes.Where(c =>
                                  c.IsEdge

                                  // target position on bottom layer
                                  && GetTargetFlags(c).HasFlag(CubeFlag.BottomLayer)
                                  );

            // Step 2: Rotate a correct orientated edge of the bottom layer to target position
            IEnumerable <Cube> bottomEdgesInBottomLayerCorrectlyOriented =
                bottomEdges.Where(bottomEdge =>
                                  // is in bottom layer
                                  bottomEdge.Position.Flags == GetTargetFlags(bottomEdge)

                                  // is oriented correctly
                                  && bottomEdge.Faces.First(f => f.Color == Rubik.BottomColor).Position == FacePosition.Bottom
                                  );

            var anyEdgesAreSolvableWithDMoves =
                bottomEdges.Count(bE =>
                                  bE.Position.HasFlag(CubeFlag.BottomLayer) &&
                                  bE.Faces.First(f => f.Color == Rubik.BottomColor).Position == FacePosition.Bottom
                                  ) > 0;

            if (anyEdgesAreSolvableWithDMoves)
            {
                while (!bottomEdgesInBottomLayerCorrectlyOriented.Any())
                {
                    // turn the bottom layer until at least one is
                    SolverMove(CubeFlag.BottomLayer, true);

                    bottomEdgesInBottomLayerCorrectlyOriented =
                        bottomEdges.Where(bE =>
                                          bE.Position.Flags == GetTargetFlags(bE) &&
                                          bE.Faces.First(f => f.Color == Rubik.BottomColor).Position == FacePosition.Bottom
                                          );
                }
            }

            // Step 3: Solve incorrect edges of the bottom layer
            while (bottomEdgesInBottomLayerCorrectlyOriented.Count() < 4)
            {
                IEnumerable <Cube> unsolvedBottomEdges = bottomEdges.Except(bottomEdgesInBottomLayerCorrectlyOriented);

                Cube e =
                    unsolvedBottomEdges.FirstOrDefault(c => c.Position.HasFlag(CubeFlag.TopLayer))
                    ?? unsolvedBottomEdges.First();

                Color secondColor =
                    e.Colors.First(co =>
                                   co != Rubik.BottomColor &&
                                   co != Color.Black
                                   );

                if (e.Position.Flags != GetTargetFlags(e))
                {
                    // Rotate to top layer
                    CubeFlag layer =
                        CubeFlagService.FromFacePosition(
                            e.Faces.First(f =>
                                          (f.Color == Rubik.BottomColor || f.Color == secondColor) &&
                                          f.Position != FacePosition.Top && f.Position != FacePosition.Bottom
                                          ).Position
                            );

                    CubeFlag targetLayer =
                        CubeFlagService.FromFacePosition(
                            StandardCube.Cubes.First(cu =>
                                                     CollectionMethods.ScrambledEquals(cu.Colors, e.Colors)
                                                     )
                            .Faces
                            .First(f => f.Color == secondColor)
                            .Position
                            );

                    if (e.Position.HasFlag(CubeFlag.MiddleLayer))
                    {
                        if (layer == targetLayer)
                        {
                            while (!e.Position.HasFlag(CubeFlag.BottomLayer))
                            {
                                SolverMove(layer, true);
                            }
                        }
                        else
                        {
                            SolverMove(layer, true);
                            if (e.Position.HasFlag(CubeFlag.TopLayer))
                            {
                                SolverMove(CubeFlag.TopLayer, true);
                                SolverMove(layer, false);
                            }
                            else
                            {
                                for (int i = 0; i < 2; i++)
                                {
                                    SolverMove(layer, true);
                                }

                                SolverMove(CubeFlag.TopLayer, true);
                                SolverMove(layer, true);
                            }
                        }
                    }

                    if (e.Position.HasFlag(CubeFlag.BottomLayer))
                    {
                        for (int i = 0; i < 2; i++)
                        {
                            SolverMove(layer, true);
                        }
                    }

                    // Rotate over target position
                    while (!e.Position.HasFlag(targetLayer))
                    {
                        SolverMove(CubeFlag.TopLayer, true);
                    }

                    //Rotate to target position
                    for (int i = 0; i < 2; i++)
                    {
                        SolverMove(targetLayer, true);
                    }
                }

                // Flip the incorrect orientated edges with the algorithm: F' D R' D'
                if (Solvability.GetOrientation(Rubik, e) != 0)
                {
                    CubeFlag frontSlice = CubeFlagService.FromFacePosition(e.Faces.First(f => f.Color == Rubik.BottomColor).Position);

                    SolverMove(frontSlice, false);
                    SolverMove(CubeFlag.BottomLayer, true);

                    CubeFlag rightSlice = CubeFlagService.FromFacePosition(e.Faces.First(f => f.Color == secondColor).Position);

                    SolverMove(rightSlice, false);
                    SolverMove(CubeFlag.BottomLayer, false);
                }

                bottomEdgesInBottomLayerCorrectlyOriented =
                    bottomEdges.Where(bE =>
                                      bE.Position.Flags == GetTargetFlags(bE) &&
                                      bE.Faces.First(f => f.Color == Rubik.BottomColor).Position == FacePosition.Bottom
                                      );
            }
        }
 /// <summary>
 /// Returns a CubeFlag which contains all flags of the first parameter except the ones of the second one
 /// </summary>
 /// <param name="flags">Defines all flags</param>
 /// <param name="flagToRemove">Defines the flags to be removed</param>
 /// <returns></returns>
 public static CubeFlag RemoveFlag(CubeFlag flags, CubeFlag flagToRemove) => flags &= ~flagToRemove;
        private void CompleteFirstLayer()
        {
            // Step 1: Get the corners with target position on bottom layer
            IEnumerable <Cube> bottomCorners =
                Rubik.Cubes.Where(c =>
                                  c.IsCorner &&
                                  GetTargetFlags(c).HasFlag(CubeFlag.BottomLayer)
                                  );

            IEnumerable <Cube> solvedBottomCorners =
                bottomCorners.Where(bC =>
                                    bC.Position.Flags == GetTargetFlags(bC) &&
                                    bC.Faces.First(f => f.Color == Rubik.BottomColor).Position == FacePosition.Bottom
                                    );

            // Step 2: Solve incorrect edges
            while (solvedBottomCorners.Count() < 4)
            {
                IEnumerable <Cube> unsolvedBottomCorners = bottomCorners.Except(solvedBottomCorners);

                // here.
                Cube c =
                    (unsolvedBottomCorners.FirstOrDefault(bC => bC.Position.HasFlag(CubeFlag.TopLayer)) != null)
                          ? unsolvedBottomCorners.First(bC => bC.Position.HasFlag(CubeFlag.TopLayer))
                          : unsolvedBottomCorners.First();

                if (c.Position.Flags != GetTargetFlags(c))
                {
                    // Rotate to top layer
                    if (c.Position.HasFlag(CubeFlag.BottomLayer))
                    {
                        Face     leftFace  = c.Faces.First(f => f.Position != FacePosition.Bottom && f.Color != Color.Black);
                        CubeFlag leftSlice = CubeFlagService.FromFacePosition(leftFace.Position);

                        SolverMove(leftSlice, false);

                        if (c.Position.HasFlag(CubeFlag.BottomLayer))
                        {
                            SolverMove(leftSlice, true);

                            leftFace =
                                c.Faces.First(f =>
                                              f.Position != FacePosition.Bottom &&
                                              f.Color != leftFace.Color &&
                                              f.Color != Color.Black
                                              );

                            leftSlice = CubeFlagService.FromFacePosition(leftFace.Position);

                            SolverMove(leftSlice, false);
                        }

                        SolverAlgorithm("U' {0} U", CubeFlagService.ToNotationString(leftSlice));
                    }

                    // Rotate over target position
                    CubeFlag targetPos = CubeFlagService.ExceptFlag(GetTargetFlags(c), CubeFlag.BottomLayer);

                    while (!c.Position.HasFlag(targetPos))
                    {
                        SolverMove(CubeFlag.TopLayer, true);
                    }
                }

                // Rotate to target position with the algorithm: Li Ui L U
                Face leftFac =
                    c.Faces.First(f =>
                                  f.Position != FacePosition.Top &&
                                  f.Position != FacePosition.Bottom &&
                                  f.Color != Color.Black
                                  );

                CubeFlag leftSlic = CubeFlagService.FromFacePosition(leftFac.Position);

                SolverMove(leftSlic, false);
                if (!c.Position.HasFlag(CubeFlag.TopLayer))
                {
                    SolverMove(leftSlic, true);

                    leftFac =
                        c.Faces.First(f =>
                                      f.Position != FacePosition.Top &&
                                      f.Position != FacePosition.Bottom &&
                                      f.Color != leftFac.Color &&
                                      f.Color != Color.Black
                                      );

                    leftSlic = CubeFlagService.FromFacePosition(leftFac.Position);
                }
                else
                {
                    SolverMove(leftSlic, true);
                }

                while (c.Faces.First(f => f.Color == Rubik.BottomColor).Position != FacePosition.Bottom)
                {
                    if (c.Faces.First(f => f.Color == Rubik.BottomColor).Position == FacePosition.Top)
                    {
                        SolverAlgorithm("{0}' U U {0} U", CubeFlagService.ToNotationString(leftSlic));
                    }
                    else
                    {
                        Face frontFac =
                            c.Faces.First(f =>
                                          f.Position != FacePosition.Top &&
                                          f.Position != FacePosition.Bottom &&
                                          f.Color != Color.Black &&
                                          f.Position != CubeFlagService.ToFacePosition(leftSlic)
                                          );

                        var thingA = c.Faces.First(f => f.Color == Rubik.BottomColor).Position == frontFac.Position;
                        var thingB = !c.Position.HasFlag(CubeFlag.BottomLayer);

                        if (thingA && thingB)
                        {
                            SolverAlgorithm("U' {0}' U {0}", CubeFlagService.ToNotationString(leftSlic));
                        }
                        else
                        {
                            SolverAlgorithm("{0}' U' {0} U", CubeFlagService.ToNotationString(leftSlic));
                        }
                    }
                }

                solvedBottomCorners =
                    bottomCorners.Where(bC =>
                                        bC.Position.Flags == GetTargetFlags(bC) &&
                                        bC.Faces.First(f => f.Color == Rubik.BottomColor).Position == FacePosition.Bottom
                                        );
            }
        }
        /// <summary>
        /// Converts the given CubeFlag into a notation string
        /// </summary>
        public static string ToNotationString(CubeFlag flag)
        {
            var notation = string.Empty;

            if (flag.HasFlag(CubeFlag.TopLayer)) notation += "U";
            if (flag.HasFlag(CubeFlag.BottomLayer)) notation += "D";
            if (flag.HasFlag(CubeFlag.FrontSlice)) notation += "F";
            if (flag.HasFlag(CubeFlag.RightSlice)) notation += "R";
            if (flag.HasFlag(CubeFlag.BackSlice)) notation += "B";
            if (flag.HasFlag(CubeFlag.LeftSlice)) notation += "L";
            if (flag.HasFlag(CubeFlag.MiddleSlice)) notation += "S";
            if (flag.HasFlag(CubeFlag.MiddleSliceSides)) notation += "M";
            if (flag.HasFlag(CubeFlag.MiddleLayer)) notation += "E";

            return notation;
        }
        /// <summary>
        /// Detection and execution of mouse-controlled layer rotations
        /// </summary>
        protected override void OnMouseClick(MouseEventArgs e)
        {
            if (this.MouseHandling)
            {
                if (e.Button == System.Windows.Forms.MouseButtons.Left)
                {
                    if (_oldSelection.IsDefault)
                    {
                        if (_currentSelection.IsDefault)
                        {
                            _selections.Reset();
                            _oldSelection     = PositionSpec.Default;
                            _currentSelection = PositionSpec.Default;
                        }
                        else
                        {
                            if (!CubePosition.IsCorner(_currentSelection.CubePosition))
                            {
                                _oldSelection = _currentSelection;
                                this.Rubik.Cubes.ForEach(c => c.Faces.Where(f => f.Color != Color.Black).ToList().ForEach(f =>
                                {
                                    PositionSpec pos = new PositionSpec()
                                    {
                                        CubePosition = c.Position.Flags, FacePosition = f.Position
                                    };

                                    if (_currentSelection.CubePosition != c.Position.Flags && !CubePosition.IsCenter(c.Position.Flags) && _currentSelection.FacePosition == f.Position)
                                    {
                                        CubeFlag assocLayer  = CubeFlagService.FromFacePosition(_currentSelection.FacePosition);
                                        CubeFlag commonLayer = CubeFlagService.GetFirstNotInvalidCommonFlag(_currentSelection.CubePosition, c.Position.Flags, assocLayer);

                                        if (commonLayer != CubeFlag.None && c.Position.HasFlag(commonLayer))
                                        {
                                            _selections[pos] |= Selection.Possible;
                                        }
                                        else
                                        {
                                            _selections[pos] |= Selection.NotPossible;
                                        }
                                    }
                                    else
                                    {
                                        _selections[pos] |= Selection.NotPossible;
                                    }
                                }));
                                this.State = string.Format("First selection [{0}] | {1}", _currentSelection.CubePosition, _currentSelection.FacePosition);
                            }
                            else
                            {
                                _selections.Reset();
                                this.State = "Error: Invalid first selection, must not be a corner";
                            }
                        }
                    }
                    else
                    {
                        if (_currentSelection.IsDefault)
                        {
                            this.State = "Ready";
                        }
                        else
                        {
                            if (_currentSelection.CubePosition != _oldSelection.CubePosition)
                            {
                                if (!CubePosition.IsCenter(_currentSelection.CubePosition))
                                {
                                    if (_oldSelection.FacePosition == _currentSelection.FacePosition)
                                    {
                                        CubeFlag assocLayer  = CubeFlagService.FromFacePosition(_oldSelection.FacePosition);
                                        CubeFlag commonLayer = CubeFlagService.GetFirstNotInvalidCommonFlag(_oldSelection.CubePosition, _currentSelection.CubePosition, assocLayer);
                                        bool     direction   = true;

                                        if (commonLayer == CubeFlag.TopLayer || commonLayer == CubeFlag.MiddleLayer || commonLayer == CubeFlag.BottomLayer)
                                        {
                                            if (((_oldSelection.FacePosition == FacePosition.Back) && _currentSelection.CubePosition.HasFlag(CubeFlag.RightSlice)) ||
                                                ((_oldSelection.FacePosition == FacePosition.Left) && _currentSelection.CubePosition.HasFlag(CubeFlag.BackSlice)) ||
                                                ((_oldSelection.FacePosition == FacePosition.Front) && _currentSelection.CubePosition.HasFlag(CubeFlag.LeftSlice)) ||
                                                ((_oldSelection.FacePosition == FacePosition.Right) && _currentSelection.CubePosition.HasFlag(CubeFlag.FrontSlice)))
                                            {
                                                direction = false;
                                            }
                                            if (commonLayer == CubeFlag.TopLayer || commonLayer == CubeFlag.MiddleLayer)
                                            {
                                                direction = !direction;
                                            }
                                        }

                                        if (commonLayer == CubeFlag.LeftSlice || commonLayer == CubeFlag.MiddleSliceSides || commonLayer == CubeFlag.RightSlice)
                                        {
                                            if (((_oldSelection.FacePosition == FacePosition.Bottom) && _currentSelection.CubePosition.HasFlag(CubeFlag.BackSlice)) ||
                                                ((_oldSelection.FacePosition == FacePosition.Back) && _currentSelection.CubePosition.HasFlag(CubeFlag.TopLayer)) ||
                                                ((_oldSelection.FacePosition == FacePosition.Top) && _currentSelection.CubePosition.HasFlag(CubeFlag.FrontSlice)) ||
                                                ((_oldSelection.FacePosition == FacePosition.Front) && _currentSelection.CubePosition.HasFlag(CubeFlag.BottomLayer)))
                                            {
                                                direction = false;
                                            }
                                            if (commonLayer == CubeFlag.LeftSlice)
                                            {
                                                direction = !direction;
                                            }
                                        }

                                        if (commonLayer == CubeFlag.BackSlice || commonLayer == CubeFlag.MiddleSlice || commonLayer == CubeFlag.FrontSlice)
                                        {
                                            if (((_oldSelection.FacePosition == FacePosition.Top) && _currentSelection.CubePosition.HasFlag(CubeFlag.RightSlice)) ||
                                                ((_oldSelection.FacePosition == FacePosition.Right) && _currentSelection.CubePosition.HasFlag(CubeFlag.BottomLayer)) ||
                                                ((_oldSelection.FacePosition == FacePosition.Bottom) && _currentSelection.CubePosition.HasFlag(CubeFlag.LeftSlice)) ||
                                                ((_oldSelection.FacePosition == FacePosition.Left) && _currentSelection.CubePosition.HasFlag(CubeFlag.TopLayer)))
                                            {
                                                direction = false;
                                            }
                                            if (commonLayer == CubeFlag.FrontSlice || commonLayer == CubeFlag.MiddleSlice)
                                            {
                                                direction = !direction;
                                            }
                                        }

                                        if (commonLayer != CubeFlag.None)
                                        {
                                            RotateLayerAnimated(commonLayer, direction);
                                        }
                                        else
                                        {
                                            this.State = "Error: Invalid second selection, does not specify distinct layer";
                                        }
                                    }
                                    else
                                    {
                                        this.State = "Error: Invalid second selection, must match orientation of first selection";
                                    }
                                }
                                else
                                {
                                    this.State = "Error: Invalid second selection, must not be a center";
                                }
                            }
                            else
                            {
                                this.State = "Error: Invalid second selection, must not be first selection";
                            }
                        }
                        _selections.Reset();
                        _oldSelection     = PositionSpec.Default;
                        _currentSelection = PositionSpec.Default;
                    }
                }
            }

            base.OnMouseClick(e);
        }
        /// <summary>
        /// Returns the next flags of the old flags after a layer rotation
        /// </summary>
        /// <param name="rotationLayer">Rotation layer</param>
        /// <param name="direction">Rotation direction</param>
        /// <returns>Next cube flags</returns>
        public static CubeFlag NextFlags(CubeFlag flags, CubeFlag rotationLayer, bool direction = true)
        {
            var lstFlags = GetFlags(flags);

            return lstFlags.Cast<CubeFlag>().Aggregate(CubeFlag.None, (current, flag) => current | NextCubeFlag(flag, rotationLayer, direction));
        }
Example #54
0
        private void btnRotate_Click(object sender, EventArgs e)
        {
            CubeFlag layer = (CubeFlag)Enum.Parse(typeof(CubeFlag), comboBoxLayers.SelectedItem.ToString());

            cubeModel.RotateLayerAnimated(layer, checkBoxDirection.Checked);
        }
 /// <summary>
 /// Returns the first ZFlag in the given CubeFlag
 /// </summary>
 /// <param name="flags">Defines the CubeFlag to be analyzed</param>
 /// <returns></returns>
 public static CubeFlag FirstZFlag(CubeFlag flags) => FirstNotInvalidFlag(flags, CubeFlag.XFlags | CubeFlag.YFlags);
Example #56
0
        private void btnAddToQueue_Click(object sender, EventArgs e)
        {
            CubeFlag layer = (CubeFlag)Enum.Parse(typeof(CubeFlag), comboBoxLayers.SelectedItem.ToString());

            this.rotations.Add(new LayerMove(layer, checkBoxDirection.Checked));
        }
Example #57
0
 /// <summary>
 /// Adds n move to the solution and executes it on the Rubik
 /// </summary>
 /// <param name="layer">Defines the layer to be rotated</param>
 /// <param name="direction">Defines the direction of the rotation</param>
 protected void SolverMove(CubeFlag layer, bool direction)
 {
     Rubik.RotateLayer(layer, direction);
     Algorithm.Moves.Add(new LayerMove(layer, direction));
     _movesOfStep.Add(new LayerMove(layer, direction));
 }
Example #58
0
 public F2LPattern(CubeFlag edgeTargetPos, CubeFlag cornerTargetPos, CubeFlag rightSlice, CubeFlag frontSlice)
 {
     this.CornerTargetPos = cornerTargetPos;
     this.EdgeTargetPos   = edgeTargetPos;
     InitPatterns(rightSlice, frontSlice);
 }
    private void InitPatterns(CubeFlag r, CubeFlag f)
    {
      var l = CubeFlagService.GetOppositeFlag(r);
      var b = CubeFlagService.GetOppositeFlag(f);
      var rIsX = CubeFlagService.IsXFlag(r);

      // edge orientation changes depending on the target slot
      var correct = (r == CubeFlag.BackSlice && f == CubeFlag.RightSlice) || (f == CubeFlag.LeftSlice && r == CubeFlag.FrontSlice)
        ? Orientation.Correct : Orientation.Clockwise;
      var clockwise = correct == Orientation.Correct ? Orientation.Clockwise : Orientation.Correct;

        this.patterns = new Dictionary<Pattern, Algorithm> {
        #region Corner correct oriented at targetposition 
        {
          new Pattern(new List<PatternItem> {
              new PatternItem(new CubePosition(CubeFlag.TopLayer | f | (rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice)), correct, this.EdgeTargetPos),
              new PatternItem(new CubePosition(this.CornerTargetPos), Orientation.Correct, this.CornerTargetPos)
            }),
          new Algorithm("U {0} U {0}' U' {1}' U' {1}",CubeFlagService.ToNotationString(r), CubeFlagService.ToNotationString(f))
        },
        {
          new Pattern(new List<PatternItem> {
              new PatternItem(new CubePosition(CubeFlag.TopLayer | r | (!rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice)), clockwise, this.EdgeTargetPos),
              new PatternItem(new CubePosition(this.CornerTargetPos), Orientation.Correct, this.CornerTargetPos)
            }),
          new Algorithm("U' {1}' U' {1} U {0} U {0}'",CubeFlagService.ToNotationString(r), CubeFlagService.ToNotationString(f))
        },
        {
          new Pattern(new List<PatternItem> {
              new PatternItem(new CubePosition(this.EdgeTargetPos), Orientation.Clockwise, this.EdgeTargetPos),
              new PatternItem(new CubePosition(this.CornerTargetPos), Orientation.Correct, this.CornerTargetPos)
            }),
          new Algorithm("{0}2 U2 {1} {0}2 {1}' U2 {0}' U {0}'",CubeFlagService.ToNotationString(r), CubeFlagService.ToNotationString(f))
        },
        #endregion

        #region Corner clockwise oriented at target position
        {
          new Pattern(new List<PatternItem> {
              new PatternItem(new CubePosition(CubeFlag.TopLayer | f | (rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice)), correct, this.EdgeTargetPos),
              new PatternItem(new CubePosition(this.CornerTargetPos), Orientation.CounterClockwise, this.CornerTargetPos)
            }),
          new Algorithm("{0}' U {0} U' {0}' U {0}",CubeFlagService.ToNotationString(f))
        },
        {
          new Pattern(new List<PatternItem> {
              new PatternItem(new CubePosition(CubeFlag.TopLayer | r | (!rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice)), clockwise, this.EdgeTargetPos),
              new PatternItem(new CubePosition(this.CornerTargetPos), Orientation.CounterClockwise, this.CornerTargetPos)
            }),
          new Algorithm("{0} U {0}' U' {0} U {0}'",CubeFlagService.ToNotationString(r))
        },
        {
          new Pattern(new List<PatternItem> {
              new PatternItem(new CubePosition(this.EdgeTargetPos), Orientation.Correct, this.EdgeTargetPos),
              new PatternItem(new CubePosition(this.CornerTargetPos), Orientation.CounterClockwise, this.CornerTargetPos)
            }),
          new Algorithm("{0} U2 {0} U {0}' U {0} U2 {0}2",CubeFlagService.ToNotationString(r))
        },
        {
          new Pattern(new List<PatternItem> {
              new PatternItem(new CubePosition(this.EdgeTargetPos), Orientation.Clockwise, this.EdgeTargetPos),
              new PatternItem(new CubePosition(this.CornerTargetPos), Orientation.CounterClockwise, this.CornerTargetPos)
            }),
          new Algorithm("{0} U {0}' U' {0} U' {0}' U2 {1}' U' {1}",CubeFlagService.ToNotationString(r), CubeFlagService.ToNotationString(f))
        },
        #endregion

        #region Corner counter-clockwise oriented at target position
        {
          new Pattern(new List<PatternItem> {
              new PatternItem(new CubePosition(CubeFlag.TopLayer | f | (rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice)), correct, this.EdgeTargetPos),
              new PatternItem(new CubePosition(this.CornerTargetPos), Orientation.Clockwise, this.CornerTargetPos)
            }),
          new Algorithm("{0}' U' {0} U {0}' U' {0}",CubeFlagService.ToNotationString(f))
        },
        {
          new Pattern(new List<PatternItem> {
              new PatternItem(new CubePosition(CubeFlag.TopLayer | r | (!rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice)), clockwise, this.EdgeTargetPos),
              new PatternItem(new CubePosition(this.CornerTargetPos), Orientation.Clockwise, this.CornerTargetPos)
            }),
          new Algorithm("{0} U' {0}' U {0} U' {0}'",CubeFlagService.ToNotationString(r))
        },
        {
          new Pattern(new List<PatternItem> {
              new PatternItem(new CubePosition(this.EdgeTargetPos), Orientation.Correct, this.EdgeTargetPos),
              new PatternItem(new CubePosition(this.CornerTargetPos), Orientation.Clockwise, this.CornerTargetPos)
            }),
          new Algorithm("{0}' U' {0} U2 {0}' U {0} U' {0}' U' {0}",CubeFlagService.ToNotationString(f))
        },
        {
          new Pattern(new List<PatternItem> {
              new PatternItem(new CubePosition(this.EdgeTargetPos), Orientation.Clockwise, this.EdgeTargetPos),
              new PatternItem(new CubePosition(this.CornerTargetPos), Orientation.Clockwise, this.CornerTargetPos)
            }),
          new Algorithm("{1}' U' {1} U {1}' U {1} U2 {0} U {0}'",CubeFlagService.ToNotationString(r), CubeFlagService.ToNotationString(f))
        },
        #endregion

        #region Corner correct oriented in top layer
        {
          new Pattern(new List<PatternItem> {
              new PatternItem(new CubePosition(this.EdgeTargetPos), Orientation.Correct, this.EdgeTargetPos),
              new PatternItem(new CubePosition(this.CornerTargetPos &~ CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Correct, this.CornerTargetPos)
            }),
          new Algorithm("{0} U {0}' U' {0} U {0}' U' {0} U {0}'",CubeFlagService.ToNotationString(r))
        },
        {
          new Pattern(new List<PatternItem> {
              new PatternItem(new CubePosition(this.EdgeTargetPos), Orientation.Clockwise, this.EdgeTargetPos),
              new PatternItem(new CubePosition(this.CornerTargetPos &~ CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Correct, this.CornerTargetPos)
            }),
          new Algorithm("{0} U' {0}' U {1}' U {1}",CubeFlagService.ToNotationString(r), CubeFlagService.ToNotationString(f))
        },
        {
          new Pattern(new List<PatternItem> {
              new PatternItem(new CubePosition(CubeFlag.TopLayer | (rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | b), clockwise, this.EdgeTargetPos),
              new PatternItem(new CubePosition(this.CornerTargetPos &~ CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Correct, this.CornerTargetPos)
            }),
          new Algorithm("U {0} U2 {0}' U {0} U' {0}'",CubeFlagService.ToNotationString(r))
        },
        {
          new Pattern(new List<PatternItem> {
              new PatternItem(new CubePosition(CubeFlag.TopLayer | (rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | b), correct, this.EdgeTargetPos),
              new PatternItem(new CubePosition(this.CornerTargetPos &~ CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Correct, this.CornerTargetPos)
            }),
          new Algorithm("{0}' U {0} U2 {0}' U' {0}",CubeFlagService.ToNotationString(f))
        },
        {
          new Pattern(new List<PatternItem> {
              new PatternItem(new CubePosition(CubeFlag.TopLayer | (!rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | l), clockwise, this.EdgeTargetPos),
              new PatternItem(new CubePosition(this.CornerTargetPos &~ CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Correct, this.CornerTargetPos)
            }),
          new Algorithm("{0} U' {0}' U2 {0} U {0}'",CubeFlagService.ToNotationString(r))
        },
        {
          new Pattern(new List<PatternItem> {
              new PatternItem(new CubePosition(CubeFlag.TopLayer | (!rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | l), correct, this.EdgeTargetPos),
              new PatternItem(new CubePosition(this.CornerTargetPos &~ CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Correct, this.CornerTargetPos)
            }),
          new Algorithm("U' {0}' U2 {0} U' {0}' U {0}",CubeFlagService.ToNotationString(f))
        },
        {
          new Pattern(new List<PatternItem> {
              new PatternItem(new CubePosition(CubeFlag.TopLayer | (rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | f), correct, this.EdgeTargetPos),
              new PatternItem(new CubePosition(this.CornerTargetPos &~ CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Correct, this.CornerTargetPos)
            }),
          new Algorithm("{0}' U2 {0} U {0}' U' {0}",CubeFlagService.ToNotationString(f))
        },
        {
          new Pattern(new List<PatternItem> {
              new PatternItem(new CubePosition(CubeFlag.TopLayer | (rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | f), clockwise, this.EdgeTargetPos),
              new PatternItem(new CubePosition(this.CornerTargetPos &~ CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Correct, this.CornerTargetPos)
            }),
          new Algorithm("{0}' U' {1}' U {1} {0} {1}' U {1}",CubeFlagService.ToNotationString(r), CubeFlagService.ToNotationString(f))
        },
        {
          new Pattern(new List<PatternItem> {
              new PatternItem(new CubePosition(CubeFlag.TopLayer | (!rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | r), correct, this.EdgeTargetPos),
              new PatternItem(new CubePosition(this.CornerTargetPos &~ CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Correct, this.CornerTargetPos)
            }),
          new Algorithm("{0} U2 {0}' U' {0} U {0}'",CubeFlagService.ToNotationString(r))
        },
        {
          new Pattern(new List<PatternItem> {
              new PatternItem(new CubePosition(CubeFlag.TopLayer | (!rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | r), clockwise, this.EdgeTargetPos),
              new PatternItem(new CubePosition(this.CornerTargetPos &~ CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Correct, this.CornerTargetPos)
            }),
          new Algorithm("{0} U {1} U' {1}' {0}' {1} U' {1}'",CubeFlagService.ToNotationString(f), CubeFlagService.ToNotationString(r))
        },
        #endregion

        #region Corner counter-clockwise oriented in top layer
        {
          new Pattern(new List<PatternItem> {
              new PatternItem(new CubePosition(this.EdgeTargetPos), Orientation.Correct, this.EdgeTargetPos),
              new PatternItem(new CubePosition(this.CornerTargetPos &~ CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.CounterClockwise, this.CornerTargetPos)
            }),
          new Algorithm("U' {0} U' {0}' U2 {0} U' {0}'",CubeFlagService.ToNotationString(r))
        },
        {
          new Pattern(new List<PatternItem> {
              new PatternItem(new CubePosition(this.EdgeTargetPos), Orientation.Clockwise, this.EdgeTargetPos),
              new PatternItem(new CubePosition(this.CornerTargetPos &~ CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.CounterClockwise, this.CornerTargetPos)
            }),
          new Algorithm("U' {0} U {0}' U {1}' U' {1}",CubeFlagService.ToNotationString(r), CubeFlagService.ToNotationString(f))
        },
        {
          new Pattern(new List<PatternItem> {
              new PatternItem(new CubePosition(CubeFlag.TopLayer | (!rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | r), clockwise, this.EdgeTargetPos),
              new PatternItem(new CubePosition(this.CornerTargetPos &~ CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.CounterClockwise, this.CornerTargetPos)
            }),
          new Algorithm("U {0} U' {0}'",CubeFlagService.ToNotationString(r))
        },
        {
          new Pattern(new List<PatternItem> {
              new PatternItem(new CubePosition(CubeFlag.TopLayer | (!rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | r), correct, this.EdgeTargetPos),
              new PatternItem(new CubePosition(this.CornerTargetPos &~ CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.CounterClockwise, this.CornerTargetPos)
            }),
          new Algorithm("{0} U2 {0}2 U' {0}2 U' {0}'",CubeFlagService.ToNotationString(f))
        },
        {
          new Pattern(new List<PatternItem> {
              new PatternItem(new CubePosition(CubeFlag.TopLayer | (rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | b), clockwise, this.EdgeTargetPos),
              new PatternItem(new CubePosition(this.CornerTargetPos &~ CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.CounterClockwise, this.CornerTargetPos)
            }),
          new Algorithm("U' {0} U {0}' U2 {0} U' {0}'",CubeFlagService.ToNotationString(r))
        },
        {
          new Pattern(new List<PatternItem> {
              new PatternItem(new CubePosition(CubeFlag.TopLayer | (rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | b), correct, this.EdgeTargetPos),
              new PatternItem(new CubePosition(this.CornerTargetPos &~ CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.CounterClockwise, this.CornerTargetPos)
            }),
          new Algorithm("U' {0} U' {0}' U {1}' U' {1}",CubeFlagService.ToNotationString(r), CubeFlagService.ToNotationString(f))
        },
        {
          new Pattern(new List<PatternItem> {
              new PatternItem(new CubePosition(CubeFlag.TopLayer | (!rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | l), correct, this.EdgeTargetPos),
              new PatternItem(new CubePosition(this.CornerTargetPos &~ CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.CounterClockwise, this.CornerTargetPos)
            }),
          new Algorithm("{0}' U' {0}",CubeFlagService.ToNotationString(f))
        },
        {
          new Pattern(new List<PatternItem> {
              new PatternItem(new CubePosition(CubeFlag.TopLayer | (!rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | l), clockwise, this.EdgeTargetPos),
              new PatternItem(new CubePosition(this.CornerTargetPos &~ CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.CounterClockwise, this.CornerTargetPos)
            }),
          new Algorithm("U' {0} U2 {0}' U2 {0} U' {0}'",CubeFlagService.ToNotationString(r))
        },
        {
          new Pattern(new List<PatternItem> {
              new PatternItem(new CubePosition(CubeFlag.TopLayer | (rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | f), correct, this.EdgeTargetPos),
              new PatternItem(new CubePosition(this.CornerTargetPos &~ CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.CounterClockwise, this.CornerTargetPos)
            }),
          new Algorithm("d {0}' U {0} U' {0}' U' {0}",CubeFlagService.ToNotationString(r))
        },
        {
          new Pattern(new List<PatternItem> {
              new PatternItem(new CubePosition(CubeFlag.TopLayer | (rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | f), clockwise, this.EdgeTargetPos),
              new PatternItem(new CubePosition(this.CornerTargetPos &~ CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.CounterClockwise, this.CornerTargetPos)
            }),
          new Algorithm("{0}' U {0} U2 {1} U {1}'",CubeFlagService.ToNotationString(f), CubeFlagService.ToNotationString(r))
        },
        #endregion

        #region Corner clockwise oriented in top layer
        {
          new Pattern(new List<PatternItem> {
              new PatternItem(new CubePosition(this.EdgeTargetPos), Orientation.Correct, this.EdgeTargetPos),
              new PatternItem(new CubePosition(this.CornerTargetPos &~ CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Clockwise, this.CornerTargetPos)
            }),
          new Algorithm("U {0} U {0}' U2 {0} U {0}'",CubeFlagService.ToNotationString(r))
        },
        {
          new Pattern(new List<PatternItem> {
              new PatternItem(new CubePosition(this.EdgeTargetPos), Orientation.Clockwise, this.EdgeTargetPos),
              new PatternItem(new CubePosition(this.CornerTargetPos &~ CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Clockwise, this.CornerTargetPos)
            }),
          new Algorithm("U2 {1}' U {1} U {0} U {0}'",CubeFlagService.ToNotationString(r), CubeFlagService.ToNotationString(f))
        },
        {
          new Pattern(new List<PatternItem> {
              new PatternItem(new CubePosition(CubeFlag.TopLayer | (!rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | r), clockwise, this.EdgeTargetPos),
              new PatternItem(new CubePosition(this.CornerTargetPos &~ CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Clockwise, this.CornerTargetPos)
            }),
          new Algorithm("U' {0} U' {0}' U {0} U {0}'",CubeFlagService.ToNotationString(r))
        },
        {
          new Pattern(new List<PatternItem> {
              new PatternItem(new CubePosition(CubeFlag.TopLayer | (!rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | r), correct, this.EdgeTargetPos),
              new PatternItem(new CubePosition(this.CornerTargetPos &~ CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Clockwise, this.CornerTargetPos)
            }),
          new Algorithm("{1} U' {1}' U2 {0}' U' {0}",CubeFlagService.ToNotationString(f), CubeFlagService.ToNotationString(r))
        },
        {
          new Pattern(new List<PatternItem> {
              new PatternItem(new CubePosition(CubeFlag.TopLayer | (rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | b), correct, this.EdgeTargetPos),
              new PatternItem(new CubePosition(this.CornerTargetPos &~ CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Clockwise, this.CornerTargetPos)
            }),
          new Algorithm("d {0}' U2 {0} U2 {0}' U {0}",CubeFlagService.ToNotationString(r))
        },
        {
          new Pattern(new List<PatternItem> {
              new PatternItem(new CubePosition(CubeFlag.TopLayer | (rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | b), clockwise, this.EdgeTargetPos),
              new PatternItem(new CubePosition(this.CornerTargetPos &~ CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Clockwise, this.CornerTargetPos)
            }),
          new Algorithm("{0} U {0}'",CubeFlagService.ToNotationString(r))
        },
        {
          new Pattern(new List<PatternItem> {
              new PatternItem(new CubePosition(CubeFlag.TopLayer | (!rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | l), correct, this.EdgeTargetPos),
              new PatternItem(new CubePosition(this.CornerTargetPos &~ CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Clockwise, this.CornerTargetPos)
            }),
          new Algorithm("d {0}' U' {0} U2 {0}' U {0}",CubeFlagService.ToNotationString(r))
        },
        {
          new Pattern(new List<PatternItem> {
              new PatternItem(new CubePosition(CubeFlag.TopLayer | (!rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | l), clockwise, this.EdgeTargetPos),
              new PatternItem(new CubePosition(this.CornerTargetPos &~ CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Clockwise, this.CornerTargetPos)
            }),
          new Algorithm("d {0}' U {0} d' {0} U {0}'",CubeFlagService.ToNotationString(r))
        },
        {
          new Pattern(new List<PatternItem> {
              new PatternItem(new CubePosition(CubeFlag.TopLayer | (rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | f), clockwise, this.EdgeTargetPos),
              new PatternItem(new CubePosition(this.CornerTargetPos &~ CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Clockwise, this.CornerTargetPos)
            }),
          new Algorithm("{0}' U2 {0}2 U {0}2 U {0}",CubeFlagService.ToNotationString(r))
        },
        {
          new Pattern(new List<PatternItem> {
              new PatternItem(new CubePosition(CubeFlag.TopLayer | (rIsX ? CubeFlag.MiddleSliceSides : CubeFlag.MiddleSlice) | f), correct, this.EdgeTargetPos),
              new PatternItem(new CubePosition(this.CornerTargetPos &~ CubeFlag.BottomLayer | CubeFlag.TopLayer), Orientation.Clockwise, this.CornerTargetPos)
            }),
          new Algorithm("U' {0}' U {0}",CubeFlagService.ToNotationString(f))
        }
        #endregion
      };
    }
Example #60
0
 /// <summary>
 /// Constructor with one CubeFlag
 /// </summary>
 /// <param name="flags">Defines the CubeFlag where the X-, Y- and ZFlag are filtered out</param>
 public CubePosition(CubeFlag flags) : this(CubeFlagService.FirstXFlag(flags), CubeFlagService.FirstYFlag(flags), CubeFlagService.FirstZFlag(flags))
 {
 }