/// <summary>
        /// Transforms the pattern item
        /// </summary>
        /// <param name="type">Transformation axis</param>
        public void Transform(CubeFlag rotationLayer)
        {
            if (CurrentPosition.HasFlag(rotationLayer))
            {
                CubeFlag oldFlags = this.CurrentPosition.Flags;
                CurrentPosition.NextFlag(rotationLayer, true);


                Orientation newOrientation = this.CurrentOrientation;
                if (CubePosition.IsCorner(CurrentPosition.Flags) && !CubeFlagService.IsYFlag(rotationLayer))
                {
                    if (new CubePosition(oldFlags).Y == new CubePosition(CurrentPosition.Flags).Y)
                    {
                        newOrientation = (Orientation)(((int)newOrientation + 2) % 3);
                    }
                    else
                    {
                        newOrientation = (Orientation)(((int)newOrientation + 1) % 3);
                    }
                }
                else if (CubePosition.IsEdge(CurrentPosition.Flags) && CubeFlagService.IsZFlag(rotationLayer))
                {
                    newOrientation = (Orientation)((int)newOrientation ^ 0x1);
                }

                this.CurrentOrientation = newOrientation;
            }
            if (TargetPosition.HasFlag(rotationLayer))
            {
                TargetPosition = CubeFlagService.NextFlags(TargetPosition, rotationLayer, true);
            }
        }
        /// <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);
        }
Exemple #3
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);
        }