/// <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 #2
0
        // **** METHODS ****
        public static Rubik FromPattern(Pattern pattern)
        {
            Rubik rubik = new Rubik();
              foreach (PatternItem item in pattern.Items)
              {
            if (CubePosition.IsCorner(item.CurrentPosition.Flags))
            {
              bool xyzCorrect = !((item.CurrentPosition.Y == CubeFlag.TopLayer ^ (item.CurrentPosition.X == CubeFlag.RightSlice ^ item.CurrentPosition.Z == CubeFlag.FrontSlice))
              ^ (CubeFlagService.FirstYFlag(item.TargetPosition) == CubeFlag.TopLayer ^ (CubeFlagService.FirstXFlag(item.TargetPosition) == CubeFlag.RightSlice ^ CubeFlagService.FirstZFlag(item.TargetPosition) == CubeFlag.FrontSlice)));

              if (item.CurrentOrientation == Orientation.Correct)
              {
            rubik.SetFaceColor(item.CurrentPosition.Flags, CubeFlagService.ToFacePosition(item.CurrentPosition.Y), rubik.GetSliceColor(CubeFlagService.FirstYFlag(item.TargetPosition)));

            FacePosition x = xyzCorrect ? CubeFlagService.ToFacePosition(item.CurrentPosition.X) : CubeFlagService.ToFacePosition(item.CurrentPosition.Z);
            FacePosition z = xyzCorrect ? CubeFlagService.ToFacePosition(item.CurrentPosition.Z) : CubeFlagService.ToFacePosition(item.CurrentPosition.X);

            rubik.SetFaceColor(item.CurrentPosition.Flags, x, rubik.GetSliceColor(CubeFlagService.FirstXFlag(item.TargetPosition)));
            rubik.SetFaceColor(item.CurrentPosition.Flags, z, rubik.GetSliceColor(CubeFlagService.FirstZFlag(item.TargetPosition)));
              }
              else
              {
            bool corr = (item.CurrentPosition.X == CubeFlag.RightSlice ^ item.CurrentPosition.Z == CubeFlag.BackSlice) ^ item.CurrentPosition.Y == CubeFlag.BottomLayer;
            FacePosition x = (corr ^ item.CurrentOrientation == Orientation.Clockwise) ? CubeFlagService.ToFacePosition(item.CurrentPosition.X) : CubeFlagService.ToFacePosition(item.CurrentPosition.Y);
            FacePosition y = (corr ^ item.CurrentOrientation == Orientation.Clockwise) ? CubeFlagService.ToFacePosition(item.CurrentPosition.Z) : CubeFlagService.ToFacePosition(item.CurrentPosition.X);
            FacePosition z = (corr ^ item.CurrentOrientation == Orientation.Clockwise) ? CubeFlagService.ToFacePosition(item.CurrentPosition.Y) : CubeFlagService.ToFacePosition(item.CurrentPosition.Z);

            rubik.SetFaceColor(item.CurrentPosition.Flags, x, rubik.GetSliceColor(CubeFlagService.FirstXFlag(item.TargetPosition)));
            rubik.SetFaceColor(item.CurrentPosition.Flags, y, rubik.GetSliceColor(CubeFlagService.FirstYFlag(item.TargetPosition)));
            rubik.SetFaceColor(item.CurrentPosition.Flags, z, rubik.GetSliceColor(CubeFlagService.FirstZFlag(item.TargetPosition)));
              }
            }

            if (CubePosition.IsEdge(item.CurrentPosition.Flags))
            {
              CubeFlag flagOne = CubeFlagService.FirstNotInvalidFlag(item.CurrentPosition.Flags, CubeFlag.MiddleLayer | CubeFlag.MiddleSlice | CubeFlag.MiddleSliceSides);
              FacePosition faceOne = CubeFlagService.ToFacePosition(flagOne);
              FacePosition faceTwo = CubeFlagService.ToFacePosition(CubeFlagService.FirstNotInvalidFlag(item.CurrentPosition.Flags, CubeFlag.MiddleLayer | CubeFlag.MiddleSlice | CubeFlag.MiddleSliceSides | flagOne));

              CubeFlag tFlagOne = CubeFlagService.FirstNotInvalidFlag(item.TargetPosition, CubeFlag.MiddleLayer | CubeFlag.MiddleSlice | CubeFlag.MiddleSliceSides);

              rubik.SetFaceColor(item.CurrentPosition.Flags, faceOne, rubik.GetSliceColor(tFlagOne));
              rubik.SetFaceColor(item.CurrentPosition.Flags, faceTwo, rubik.GetSliceColor(CubeFlagService.FirstNotInvalidFlag(item.TargetPosition, CubeFlag.MiddleLayer | CubeFlag.MiddleSlice | CubeFlag.MiddleSliceSides | tFlagOne)));

              if (Solvability.GetOrientation(rubik, rubik.Cubes.First(c => c.Position.Flags == item.CurrentPosition.Flags)) != item.CurrentOrientation)
              {
            rubik.SetFaceColor(item.CurrentPosition.Flags, faceTwo, rubik.GetSliceColor(tFlagOne));
            rubik.SetFaceColor(item.CurrentPosition.Flags, faceOne, rubik.GetSliceColor(CubeFlagService.FirstNotInvalidFlag(item.TargetPosition, CubeFlag.MiddleLayer | CubeFlag.MiddleSlice | CubeFlag.MiddleSliceSides | tFlagOne)));
              }
            }

            if (CubePosition.IsCenter(item.CurrentPosition.Flags))
            {
              CubeFlag flag = CubeFlagService.FirstNotInvalidFlag(item.CurrentPosition.Flags, CubeFlag.MiddleLayer | CubeFlag.MiddleSlice | CubeFlag.MiddleSliceSides);
              CubeFlag tFlag = CubeFlagService.FirstNotInvalidFlag(item.TargetPosition, CubeFlag.MiddleLayer | CubeFlag.MiddleSlice | CubeFlag.MiddleSliceSides);

              rubik.SetFaceColor(item.CurrentPosition.Flags, CubeFlagService.ToFacePosition(flag), rubik.GetSliceColor(tFlag));
            }
              }
              return rubik;
        }
 /// <summary>
 /// True, if this pattern includes all the pattern elements of another pattern
 /// </summary>
 /// <param name="pattern">Pattern to compare</param>
 public bool IncludesAllPatternElements(Pattern pattern)
 {
     foreach (PatternItem item in pattern.Items)
       {
     if (!Items.Any(i => i.Equals(item))) return false;
       }
       return true;
 }
 /// <summary>
 /// True, if this pattern has exactly the same pattern elemnts as the other pattern
 /// </summary>
 /// <param name="pattern">Pattern to compare</param>
 public bool Equals(Pattern pattern)
 {
     return CollectionMethods.ScrambledEquals(pattern.Items, Items);
 }
 /// <summary>
 /// Converts a rubik to a pattern
 /// </summary>
 /// <param name="r">Rubik </param>
 /// <returns>The pattern of the given rubik</returns>
 public static Pattern FromRubik(Rubik r)
 {
     Pattern p = new Pattern();
       List<PatternItem> newItems = new List<PatternItem>();
       foreach (CubePosition pos in Positions)
       {
     Cube cube = r.Cubes.First(c => r.GetTargetFlags(c) == pos.Flags);
     newItems.Add(new PatternItem(cube.Position, Solvability.GetOrientation(r, cube), pos.Flags));
       }
       p.Items = newItems;
       return p;
 }
 /// <summary>
 /// Searches for the best algorithm for the given pattern
 /// </summary>
 /// <param name="p">Current rubik pattern</param>
 /// <param name="rotationLayer">Transformation layer</param>
 /// <returns>Returns the best match</returns>
 public Algorithm FindBestMatch(Pattern p, CubeFlag rotationLayer, PatternFilter filter)
 {
   Dictionary<Pattern, Algorithm> matches = FindMatches(p, rotationLayer, filter);
   Algorithm bestAlgo = matches.OrderByDescending(item => item.Key.Items.Count()).FirstOrDefault().Value;
   return bestAlgo;
 }
   /// <summary>
   /// Searches for the best algorithm for the given pattern
   /// </summary>
   /// <param name="p">Current rubik pattern</param>
   /// <param name="rotationLayer">Transformation layer</param>
   /// <param name="filter"></param>
   /// <returns>Returns the best match</returns>
   public Algorithm FindBestMatch(Pattern p, CubeFlag rotationLayer, PatternFilter filter)
 {
   var matches = this.FindMatches(p, rotationLayer, filter);
   var bestAlgo = matches.OrderByDescending(item => item.Key.Items.Count).FirstOrDefault().Value;
   return bestAlgo;
 }