Skip to content

Repository files navigation

Python based Rubics Cube solver with interactive UI

Description

Python program that models and solves a Rubik's cube using the CFOP method.
(CFOP : Cross, First two layers, Orientation of last layer, Permutation of last layer)

First checkout the notation to understand how rubik's cube notation (aka formulas) work and to understand the output.
To understand the code or to write your own version, read the brief explanation given below.

The code for cube manipulation can be found in cube.py.
The parsing, condenstion and validation for formulas can be found in helper.py.

🚀 Quick Start

Live Demo

Try the solver online: https://pycube-solver-394748284637.us-central1.run.app

  1. Install dependencies

    pip install -r requirements.txt
  2. Run the application

    python app.py
  3. Open your browser Navigate to http://localhost:8080

How to Use the Frontend

Interactive Cube Interface

  • 3D Cube Display: View your cube from all angles with smooth rotations
  • Click Controls: Click on any face sticker to change its color
  • Color Palette: Select colors from the sidebar palette (White, Yellow, Green, Blue, Red, Orange)
  • Cube Validation: The interface automatically checks if your cube configuration is valid

Solving Features

  • Scramble Button: Generate a random scramble to practice with
  • Solve Button: Get the complete CFOP solution with step-by-step breakdown
  • Animate moves: Get the moves applied to cube 3d display and see the final solution state
  • Solution Display: View moves in standard cube notation with phase separation

Advanced Options

  • Optimize Toggle: Enable to reduce move count by eliminating redundant rotations
  • Reset Button: Return to solved state
  • Manual Input: Enter cube state manually using the text input format

Programming Interface

You can create a cube object and move it by using the following code

from cube import Cube
cb = Cube()
cb.doMoves("RUR'U'")
# to automatically scramble the cube, use
from helper import getScramble
cb.doMoves(getScramble(10))

print(cb)

The code for solving the cube can be found in solver.py and its helper data objects in solver_data.py.

Notation

There are rules and methods that need to be followed in order to use the program.

  • The moves in a rubik's cube are defines as follows, (Note: The picture shows the front face as Blue, but the code uses Green as the front face. But the idea remains the same)
    Rubik's Cube Moves
    If you make the move anticlockwise (opposite to what has been shown in the image) then you "'" or "P" to the move.
    R in anticlockwise (opposite to image depiction) direction becomes R'.

  • The cube printing format is defined as

        YYY
        YYY
        YYY
    RRR GGG OOO BBB
    RRR GGG OOO BBB
    RRR GGG OOO BBB
        WWW
        WWW
        WWW
    
  • The cube front face is assumed as Green and the top face is assumed as Yellow (If input is given otherwise, it automatically reorients itself)

  • The cube face notation followed in this code,
    ThreeJS Coordinates

How does it work?

Creating this algorithm is not as hard as it sounds, but rather time taking and laborious. The entire task is of reducing cases and applying the appropriate formulas for those cases. If you know how to solve a cube, you should be able to follow my explanation.

  • The first part is to solve the white cross. This has no straight forward formulas to do it and is rather very intuitive. But for a program to solve it, we need to give explicit instructions. This is a major challenge as we need to figure out patterns in a place where intuition is required.

    One way to solve this is using 2 state algorithm where we convert all possible cases into a set of standard cases. Then for each of these standard cases we need can apply the corresponding formula. But doing this way is very inefficient as the average number of moves to solve the cross is around 25.

    Due to this, i needed to come up with a clever technique to tackle the inefficiency. One major upgrade is the changing of perspectives from global to local. This will save us a ton of code and will reduce the cases. The other is flexible base orientation, where we do not first fix the edge alignment but rather give importance to edge orientation. Depending on the best orientation and the corresponding slot available, we can use a predefined set of formulas to orient the edges and in the end align the edges. This method reduces the average number of moves to solve the cross to around 10.

  • The second part is to solve the first layer simulatenously along with the second layer, and hence is called the F2L (first two layers). This way of solving the two layers is complicated and requires a lot of intuition. One easy work around is to simply use the beginners method where we solve the two layers individually and the whole process is algorithmic. Hence it is much easier to code (with an added bonus that it has only 3 formulas to code up). But as you might have guessed, it is rather inefficient.

    So to reduce the number of steps, we use the concept of F2L. If we break down all the possible combinations with color variability, it turns out there are only 41 cases. In a real solve, we do not remember all the cases but rather intuitively reduce most cases to easily solvable ones. But if we do want, there are formulas for each of these cases. So, rather than intuition we can now use the formulas for each of these cases. Now the task is pattern recognition, meaning how to determine which formula to apply (given it is color variable). The simple method is to find some kind of orientation dependant hash and then compare the hashes to get the formula. Another challenge is the wide variety of cases and scenarios present. Once we figure out hashes for the many scenarios present, then its pretty straight forward to apply. The last problem is to fix non standard cases. I tackled this by using a scoring system, where the moves (to convert non standard to standard) which are shorter and pair up corner-edge are given more score. Watch this video [https://www.youtube.com/watch?v=Ar_Zit1VLG0] for the F2L cases and scenarios.

  • The third step is orientation of the last layer (OLL). At this point it is very straight forward and easy but labour intensive. The actual code to implement this takes 5 minutes but to write down formulas for each of the cases (and make it into a dictionary) takes a lot of time. Simply put, we convert the orientation of yellow positions on the top layer into a hash string and use that to look up in the oll dictionary that we made by hashing the standard cases similarly. Thats it!. for the OLL cases.

  • The fourth and final step is permutation of the last layer (PLL). This step is very similar to the previous step. I used a color independant orientation based technique to identify the cases. My method is brute force (to enable color independence) rather than implementing a color independent hash. Since the compare cases are few, this wont affect the speed much.

  • I tried to do this for 2x2 and 4x4 , but some more optimizations and moves are needed , hence they are disabled for now.

About

3x3 and 4x4 Rubik's cube solver with multiple solving algorithms and step-by-step visualisation.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages