/// <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); }
// **** 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); }