Click here to Skip to main content
15,896,306 members
Articles / Desktop Programming / WPF

WPF: Rubik's Cube

Rate me:
Please Sign up or sign in to vote.
4.97/5 (112 votes)
24 Sep 2014CPOL3 min read 174.9K   10.2K   154  
A WPF 3D Rubik's Cube application
Imports System.Windows.Threading

Public Class Scrambler
    Private index As Integer
    Private isScrambling As Boolean

    Private Const CLOCKWISE As Double = -90
    Private Const ANTI_CLOCKWISE As Double = 90

    Private mainWin As MainWindow
    Private rnd As Random
    Private scrambleTimer As DispatcherTimer
    Private scramble As List(Of Notations)

    Public Sub New(ByRef win As MainWindow)
        mainWin = win
        rnd = New Random
        scramble = New List(Of Notations)
        scrambleTimer = New DispatcherTimer
        scrambleTimer.Interval = New TimeSpan(0, 0, 0, 0, 400)
        AddHandler scrambleTimer.Tick, AddressOf Timer_Tick
    End Sub

    Public Sub ScrambleCube()
        If isScrambling = False Then
            scramble.Clear()
            ' Create a scramble with 20 values
            For i As Integer = 0 To 19
                AddToScramble()
            Next
            isScrambling = True
            scrambleTimer.Start()
            mainWin.CubeGroupGrid.IsEnabled = False
        Else
            MessageBox.Show("Scrambling of cube already in progress", _
                            "WPF Rubiks", MessageBoxButton.OK, MessageBoxImage.Exclamation)
        End If
    End Sub

    ''' <summary>
    ''' Create scramble with dissimilar values following each other, and the new value 
    ''' in the List is not an inverse or double of the preceding value e.g.
    ''' F' does not come after F, or F2 after F.
    ''' </summary>
    Private Sub AddToScramble()
        Dim randomNum As Integer = rnd.Next(0, 18)
        Dim newNotation As String = [Enum].GetName(GetType(Notations), randomNum)
        Dim notation As Notations

        If (scramble.Count > 0) Then
            Dim lastItem As String = scramble(scramble.Count - 1).ToString

            If newNotation.Contains("F") AndAlso lastItem.Contains("F") Then
                AddToScramble()
            ElseIf newNotation.Contains("R") AndAlso lastItem.Contains("R") Then
                AddToScramble()
            ElseIf newNotation.Contains("B") AndAlso lastItem.Contains("B") Then
                AddToScramble()
            ElseIf newNotation.Contains("L") AndAlso lastItem.Contains("L") Then
                AddToScramble()
            ElseIf newNotation.Contains("U") AndAlso lastItem.Contains("U") Then
                AddToScramble()
            ElseIf newNotation.Contains("D") AndAlso lastItem.Contains("D") Then
                AddToScramble()
            Else
                notation = [Enum].Parse(GetType(Notations), newNotation)
                scramble.Add(notation)
            End If
        Else
            notation = [Enum].Parse(GetType(Notations), newNotation)
            scramble.Add(notation)
        End If
    End Sub

    Private Sub Timer_Tick(ByVal sender As Object, ByVal e As EventArgs)
        If (index < 19) Then
            RotateCubePieces(index)
            index += 1
        Else
            isScrambling = False
            scrambleTimer.Stop()
            index = 0
            mainWin.CubeGroupGrid.IsEnabled = True
        End If
    End Sub

    Private Sub RotateCubePieces(ByVal i As Integer)
        Select Case scramble(i)
            Case Notations.F
                mainWin.CubeRotater.Rotate_F_Layer(CLOCKWISE)
            Case Notations.F_prime
                mainWin.CubeRotater.Rotate_F_Layer(ANTI_CLOCKWISE)
            Case Notations.F2
                mainWin.CubeRotater.Rotate_F_Layer(CLOCKWISE)
                mainWin.CubeRotater.Rotate_F_Layer(CLOCKWISE)
            Case Notations.R
                mainWin.CubeRotater.Rotate_R_Layer(CLOCKWISE)
            Case Notations.R_prime
                mainWin.CubeRotater.Rotate_R_Layer(ANTI_CLOCKWISE)
            Case Notations.R2
                mainWin.CubeRotater.Rotate_R_Layer(CLOCKWISE)
                mainWin.CubeRotater.Rotate_R_Layer(CLOCKWISE)
            Case Notations.B
                mainWin.CubeRotater.Rotate_B_Layer(CLOCKWISE)
            Case Notations.B_prime
                mainWin.CubeRotater.Rotate_B_Layer(ANTI_CLOCKWISE)
            Case Notations.B2
                mainWin.CubeRotater.Rotate_B_Layer(CLOCKWISE)
                mainWin.CubeRotater.Rotate_B_Layer(CLOCKWISE)
            Case Notations.L
                mainWin.CubeRotater.Rotate_L_Layer(ANTI_CLOCKWISE)
            Case Notations.L_prime
                mainWin.CubeRotater.Rotate_L_Layer(CLOCKWISE)
            Case Notations.L2
                mainWin.CubeRotater.Rotate_L_Layer(ANTI_CLOCKWISE)
                mainWin.CubeRotater.Rotate_L_Layer(ANTI_CLOCKWISE)
            Case Notations.U
                mainWin.CubeRotater.Rotate_U_Layer(CLOCKWISE)
            Case Notations.U_prime
                mainWin.CubeRotater.Rotate_U_Layer(ANTI_CLOCKWISE)
            Case Notations.U2
                mainWin.CubeRotater.Rotate_U_Layer(CLOCKWISE)
                mainWin.CubeRotater.Rotate_U_Layer(CLOCKWISE)
            Case Notations.D
                mainWin.CubeRotater.Rotate_D_Layer(ANTI_CLOCKWISE)
            Case Notations.D_prime
                mainWin.CubeRotater.Rotate_D_Layer(CLOCKWISE)
            Case Notations.D2
                mainWin.CubeRotater.Rotate_D_Layer(ANTI_CLOCKWISE)
                mainWin.CubeRotater.Rotate_D_Layer(ANTI_CLOCKWISE)
        End Select
    End Sub

End Class

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Kenya Kenya
Experienced C# software developer with a passion for WPF.

Awards,
  • CodeProject MVP 2013
  • CodeProject MVP 2012
  • CodeProject MVP 2021

Comments and Discussions