Programming a rubik's cube

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Avatar19
    New Member
    • Apr 2010
    • 43

    Programming a rubik's cube

    Hi there, I have undertaken a personal project of trying to write a program that can solve a rubik's cube by outputting a complete solution on all the movements that need to be made in order to solve a cube from any position. I am not looking for people to give me a solution so please don't, but \I would appreciate any cool ideas of how to progress through the problem.
    What I have started with is this:

    Code:
    White=['ww','1w','2w','3w','4w','5w','6w','7w','8w','9w']
    Orange=['oo','1o','2o','3o','4o','5o','6o','7o','8o','9o']
    Yellow=['yy','1y','2y','3y','4c','5y','6y','7y','8y','9y']
    Red=['rr','1r','2r','3r','4r','5r','6r','7r','8r','9r']
    Green=['gg','1g','2g','3g','4g','5g','6g','7g','8g','9g']
    Blue=['bb','1b','2b','3b','4b','5b','6b','7b','8b','9b']
    Master=[White,Orange,Red,Green,Blue,Yellow]
    I thought maybe setting up Lists in order to provide a base for which a solved rubik's cube will look like in program form and below is alil search program o check if any List is not what it should be, but I am not super sure of where to go from here.
    Code:
    k=0
    LEN=len(Master)
    while LEN!=0: 
        Word=Master[k][0]
        for i in Master[k]:
            if Master[k][0][1]!=i[1]:
                print "no",Master[0][0][1],i[1],Master[k].index(i)	
            else: print "yes"
             
        k+=1
        LEN-=1
    any suggestions welcome thanks
  • dwblas
    Recognized Expert Contributor
    • May 2008
    • 626

    #2
    Several of us started this on another forum but soon realized that none of us had the time to finish. I numbered every square and created a way to rotate it. The code will run as is and will print a cube and some moves as a test. Someone else did the Tkinter display, displaying the dictionary in the correct colors but I don't have that code now. Anyway, the code follows. Let us know how you are doing and post back if there are any questions about this code, and I assume that you already know about this link http://en.wikibooks.org/wiki/How_to_...Rubik%27s_Cube
    Code:
    import sys
    import os
    import random
    
    from collections import defaultdict
    
    class rubik_test():
       def __init__(self):
          self.testing=1
          self.row_x={}     ## x dimension in 3 dimensional space
          self.row_y={}     ## y dimension
          self.row_z={}     ## z dimension
          self.color_dic={} ## assigns a color to each square number
          self.populate_dic()
          self.populate_xyz()
    
    
       def count_colors(self):
          """return the color that shows up the greatest number of times
             on one face
          """
          dic_count = defaultdict(int)
          for key in self.color_dic.keys():
             dic_count[self.color_dic[key]] += 1
          max_key=""
          max_num=0
          for key in dic_count:
             if dic_count[key] > max_num:
                max_num = dic_count[key]
                max_key = key
          return max_key
    
    
       def populate_dic(self):
          """ populate the color dictionary by assigning a color 
              to each square number
          """
          colors_list=["white", "red", "blue", "green", "yellow", "orange"]
    
          for j in range(1, 55):
             idx = int(random.randrange(0,6))
             self.color_dic[j] = colors_list[idx]
          if self.testing:
             color_max=self.count_colors()
             print "color_dic =", self.color_dic
             import rubik2
             rubik2.print_cube(self.color_dic)
             print "color_max =", color_max
    
    
       def populate_xyz(self):
          """  add a unique number for each square
          3 dimensions of rows with 3 rows per dimension (3X3 cube)
          (9 per side) * (6 sides) = 54 squares
          """
          self.row_x[1]=(1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 31, 34)
          junk=[x+1 for x in self.row_x[1]]
          self.row_x[2]=tuple(junk)
          junk=[x+2 for x in self.row_x[1]]
          self.row_x[3]=tuple(junk)
    
          self.row_y[1]=(1, 2, 3, 48, 51, 54, 27, 26, 25, 43, 40, 37)
          self.row_y[2]=(4, 5, 6, 47, 50, 53, 24, 23, 22, 44, 41, 38)
          self.row_y[3]=(7, 8, 9, 46, 49, 52, 21, 20, 19, 45, 42, 39)
    
          self.row_z[1]=(10, 11, 12, 46, 47, 48, 36, 35, 34, 37, 38, 39)
          self.row_z[2]=(13, 14, 15, 49, 50, 51, 33, 32, 31, 40, 41, 42)
          self.row_z[3]=(16, 17, 18, 52, 53, 54, 30, 29, 28, 43, 44, 45)
    
    
       def rotate( self, row_list, direction ):
          stop=len(row_list)-1
          """ rotate the list passed to the function in forward or reverse 
          direction
          """
          if direction :             ## move forward
             hold_it=self.color_dic[row_list[0]]
             for j in range(0, stop):
                self.color_dic[row_list[j]] = self.color_dic[row_list[j+1]]
             self.color_dic[row_list[-1]] = hold_it
          else:                      ## move backward/reverse
             hold_it=self.color_dic[row_list[-1]]
             for j in range(stop, 0, -1):
                self.color_dic[row_list[j]] = self.color_dic[row_list[j-1]]
             self.color_dic[row_list[0]] = hold_it
    
    
       def rotate_x( self, row, direction ):
          """rotate row 1, 2, or 3 of the x dimension
          """
          update_list=list(self.row_x[row])
          if self.testing:
             print "\nbefore rotating", update_list
             for num in update_list:
                print "%2d %s,  " % (num, self.color_dic[num]),
             print
          self.rotate(update_list, direction)
          if self.testing:
             print "\nafter rotating ", update_list
             for num in update_list:
                print "%2d %s,  " % (num, self.color_dic[num]),
             print
    
    
    ##=====================================================================
    def test_routine(RT):
       RT.rotate_x(2, 1)
       RT.rotate_x(3, 0)
    
    
       ##  test that every square is in exactly two tuples
       test_d=defaultdict(int)
       for j in range( 1, 4 ):
          for num in RT.row_x[j]:     ## all 3 rows along the x dimension
                test_d[num] += 1
          for num in RT.row_y[j]:
                test_d[num] += 1
          for num in RT.row_z[j]:
                test_d[num] += 1
    
       for key in test_d.keys():
          if test_d[key] != 2:
                print key, "error --> number is", test_d[key]
    
    ##=====================================================================
    if __name__ == "__main__":
       RT=rubik_test()
       test_routine(RT)
    And this is rubik2.py that prints the dictionary.
    Code:
    import sys
    import os
    
    def print_cube(dic_in):
       print_list=[ [0, 0, 0, 1, 2, 3, 0, 0, 0], 
                 [0, 0, 0, 4, 5, 6, 0, 0, 0],
                 [0, 0, 0, 7, 8, 9, 0, 0, 0],
                 [37, 38, 39, 10, 11, 12, 46, 47, 48],
                 [40, 41, 42, 13, 14, 15, 49, 50, 51],
                 [43, 44, 45, 16, 17, 18, 52, 53, 54],
                 [0, 0, 0, 19, 20, 21, 0, 0, 0],
                 [0, 0, 0, 22, 23, 24, 0, 0, 0],
                 [0, 0, 0, 25, 26, 27, 0, 0, 0],
                 [0, 0, 0, 28, 29, 30, 0, 0, 0],
                 [0, 0, 0, 31, 32, 33, 0, 0, 0],
                 [0, 0, 0, 34, 35, 36, 0, 0, 0]]
    
       ctr = 3
       row_num=0
       print "                     -------------------"
       for row in print_list:
          if row_num == ctr:
             ctr += 3
          str_row=""
          color_row=""
          first = 1
          for el in row:
             if el:
                if first:
                   str_row += "   |"
                   color_row += "   |"
                   first = 0
                str_row += " %3d |" % (el)
                color = dic_in[el]
                color_row += "%5s|" % (color[:5])
             else:
                str_row += "      "
                color_row+="      "
          print str_row
          print color_row
          if 1 < row_num < 6:
             print "   -------------------------------------------------------"
          else:
             print "                     -------------------"
          row_num += 1
          if row_num == 9:
             print "                     -------------------"

    Comment

    • Avatar19
      New Member
      • Apr 2010
      • 43

      #3
      Cool thanks I'll keep you updated

      Comment

      • dwblas
        Recognized Expert Contributor
        • May 2008
        • 626

        #4
        Let me know if you want the Tkinter program to display the cube, and I will look further for it.

        Comment

        Working...