But as I'm thinking about this, I'm somewhat worried that I'm going to need to rewrite the program a bit. I think some of the pieces have become too spread out and disorganized for me to go to the next step (the solving step). Also, while I have definitely liked the graphical representation as I've been double checking the various permutations corresponding to the moves, Pygame just takes so much time to load and running the program in IDLE instead of in a terminal just feels so much slower.
So I'm about to embark on a rewriting of the program. I've built all of the bits and pieces, but I need to pull it apart and reorganize it a bit so that I can call the things I want to call when I want to call them. I've got the ability to run long processes and then dump the results into a file (pickling), which means that I don't need to rerun those processes again and again.
So the way I see it, I need to create the following functions:
- Reset the cube
- Perform a sequence of moves to the cube
- Compare the current state of the cube with one from a list, including the ability to ignore gray pieces
- Find the "next" sequence to check given a maximum move depth and the current sequence.
import pygame
import pickle
import time
# Global Variables
sGap = 5
bGap = 10
boxSize = 30
def posCalc(bS, sG, bG):
return bS*boxSize + sG*sGap + bG*bGap
# Define drawing data
sqPos = [ [ [posCalc(3,3,1), posCalc(0,1,0)],
[posCalc(4,4,1), posCalc(0,1,0)],
[posCalc(5,5,1), posCalc(0,1,0)],
[posCalc(3,3,1), posCalc(1,2,0)],
[posCalc(4,4,1), posCalc(1,2,0)],
[posCalc(5,5,1), posCalc(1,2,0)],
[posCalc(3,3,1), posCalc(2,3,0)],
[posCalc(4,4,1), posCalc(2,3,0)],
[posCalc(5,5,1), posCalc(2,3,0)] ],
[ [posCalc(0,1,0), posCalc(3,3,1)],
[posCalc(1,2,0), posCalc(3,3,1)],
[posCalc(2,3,0), posCalc(3,3,1)],
[posCalc(0,1,0), posCalc(4,4,1)],
[posCalc(1,2,0), posCalc(4,4,1)],
[posCalc(2,3,0), posCalc(4,4,1)],
[posCalc(0,1,0), posCalc(5,5,1)],
[posCalc(1,2,0), posCalc(5,5,1)],
[posCalc(2,3,0), posCalc(5,5,1)] ],
[ [posCalc(3,3,1), posCalc(3,3,1)],
[posCalc(4,4,1), posCalc(3,3,1)],
[posCalc(5,5,1), posCalc(3,3,1)],
[posCalc(3,3,1), posCalc(4,4,1)],
[posCalc(4,4,1), posCalc(4,4,1)],
[posCalc(5,5,1), posCalc(4,4,1)],
[posCalc(3,3,1), posCalc(5,5,1)],
[posCalc(4,4,1), posCalc(5,5,1)],
[posCalc(5,5,1), posCalc(5,5,1)] ],
[ [posCalc(6,5,2), posCalc(3,3,1)],
[posCalc(7,6,2), posCalc(3,3,1)],
[posCalc(8,7,2), posCalc(3,3,1)],
[posCalc(6,5,2), posCalc(4,4,1)],
[posCalc(7,6,2), posCalc(4,4,1)],
[posCalc(8,7,2), posCalc(4,4,1)],
[posCalc(6,5,2), posCalc(5,5,1)],
[posCalc(7,6,2), posCalc(5,5,1)],
[posCalc(8,7,2), posCalc(5,5,1)] ],
[ [posCalc(9,7,3), posCalc(3,3,1)],
[posCalc(10,8,3), posCalc(3,3,1)],
[posCalc(11,9,3), posCalc(3,3,1)],
[posCalc(9,7,3), posCalc(4,4,1)],
[posCalc(10,8,3), posCalc(4,4,1)],
[posCalc(11,9,3), posCalc(4,4,1)],
[posCalc(9,7,3), posCalc(5,5,1)],
[posCalc(10,8,3), posCalc(5,5,1)],
[posCalc(11,9,3), posCalc(5,5,1)] ],
[ [posCalc(3,3,1), posCalc(6,5,2)],
[posCalc(4,4,1), posCalc(6,5,2)],
[posCalc(5,5,1), posCalc(6,5,2)],
[posCalc(3,3,1), posCalc(7,6,2)],
[posCalc(4,4,1), posCalc(7,6,2)],
[posCalc(5,5,1), posCalc(7,6,2)],
[posCalc(3,3,1), posCalc(8,7,2)],
[posCalc(4,4,1), posCalc(8,7,2)],
[posCalc(5,5,1), posCalc(8,7,2)] ]
]
sqColor = [ [ i for ii in range(9) ] for i in range(6) ]
drawColor = [ pygame.Color(0,0,255),
pygame.Color(255,0,0),
pygame.Color(255,255,0),
pygame.Color(255,100,0),
pygame.Color(255,255,255),
pygame.Color(0,255,0),
pygame.Color(100,100,100) ]
# Initialize
pygame.init()
window1Width = posCalc(12,10,3)
window1Height = posCalc(9,8,2)
window1 = pygame.display.set_mode((window1Width,window1Height))
# Functions
def menu():
menuSelect = 0
while menuSelect == 0:
print('''
Main Menu:
(1) Free Play
(2) Set up Cube
(6) Generate Position Lookup
(7) Generate Solution Lookup Move List
(8) Reset Cube
(9) Quit
''')
comm = input('Select Menu Option: ')
if comm in ['1', '2', '6', '7', '8', '9']:
menuSelect = 1
return int(comm)
def drawIt1(window, sqPos, sqColor, drawColor):
for i in range(6):
for ii in range(9):
pygame.draw.rect(window,
drawColor[sqColor[i][ii]],
( sqPos[i][ii][0], sqPos[i][ii][1], boxSize, boxSize ),
0)
pygame.display.update()
return
def playCube(sqColor):
commands = ["U", "U2", "U'",
"L", "L2", "L'",
"F", "F2", "F'",
"R", "R2", "R'",
"B", "B2", "B'",
"D", "D2", "D'"]
commList = "U, U2, U', L, L2, L', F, F2, F', R, R2, R', B, B2, B', D, D2, D'"
comm = ""
while comm != "Q":
print("Execute which command?")
print(commList)
comm = input('Enter a squence of moves separated by spaces or Q to quit: ' )
validComm = 1
commSeq = comm.split()
for move in commSeq:
if move not in commList:
validComm = 0
if validComm == 1:
for move in commSeq:
sqColor = permute(move, sqColor)
elif validComm == 0 and comm != "Q":
print("Invalid move sequence.")
drawIt1(window1, sqPos, sqColor, drawColor)
return
def permute(comm, sqColor):
if comm == "U":
swap4(sqColor, [0,0], [0,2], [0,8], [0,6])
swap4(sqColor, [0,1], [0,5], [0,7], [0,3])
swap4(sqColor, [4,0], [3,0], [2,0], [1,0])
swap4(sqColor, [4,1], [3,1], [2,1], [1,1])
swap4(sqColor, [4,2], [3,2], [2,2], [1,2])
elif comm == "U2":
swap2(sqColor, [0,0], [0,8])
swap2(sqColor, [0,2], [0,6])
swap2(sqColor, [0,1], [0,7])
swap2(sqColor, [0,3], [0,5])
swap2(sqColor, [1,0], [3,0])
swap2(sqColor, [1,1], [3,1])
swap2(sqColor, [1,2], [3,2])
swap2(sqColor, [2,0], [4,0])
swap2(sqColor, [2,1], [4,1])
swap2(sqColor, [2,2], [4,2])
elif comm == "U'":
swap4(sqColor, [0,0], [0,6], [0,8], [0,2])
swap4(sqColor, [0,1], [0,3], [0,7], [0,5])
swap4(sqColor, [1,0], [2,0], [3,0], [4,0])
swap4(sqColor, [1,1], [2,1], [3,1], [4,1])
swap4(sqColor, [1,2], [2,2], [3,2], [4,2])
elif comm == "L":
swap4(sqColor, [1,0], [1,2], [1,8], [1,6])
swap4(sqColor, [1,1], [1,5], [1,7], [1,3])
swap4(sqColor, [0,0], [2,0], [5,0], [4,8])
swap4(sqColor, [0,3], [2,3], [5,3], [4,5])
swap4(sqColor, [0,6], [2,6], [5,6], [4,2])
elif comm == "L2":
swap2(sqColor, [1,0], [1,8])
swap2(sqColor, [1,2], [1,6])
swap2(sqColor, [1,1], [1,7])
swap2(sqColor, [1,3], [1,5])
swap2(sqColor, [2,0], [4,8])
swap2(sqColor, [2,3], [4,5])
swap2(sqColor, [2,6], [4,2])
swap2(sqColor, [0,0], [5,0])
swap2(sqColor, [0,3], [5,3])
swap2(sqColor, [0,6], [5,6])
elif comm == "L'":
swap4(sqColor, [1,0], [1,6], [1,8], [1,2])
swap4(sqColor, [1,1], [1,3], [1,7], [1,5])
swap4(sqColor, [5,0], [2,0], [0,0], [4,8])
swap4(sqColor, [5,3], [2,3], [0,3], [4,5])
swap4(sqColor, [5,6], [2,6], [0,6], [4,2])
elif comm == "F":
swap4(sqColor, [2,0], [2,2], [2,8], [2,6])
swap4(sqColor, [2,1], [2,5], [2,7], [2,3])
swap4(sqColor, [0,6], [3,0], [5,2], [1,8])
swap4(sqColor, [0,7], [3,3], [5,1], [1,5])
swap4(sqColor, [0,8], [3,6], [5,0], [1,2])
elif comm == "F2":
swap2(sqColor, [2,0], [2,8])
swap2(sqColor, [2,2], [2,6])
swap2(sqColor, [2,1], [2,7])
swap2(sqColor, [2,3], [2,5])
swap2(sqColor, [0,6], [5,2])
swap2(sqColor, [0,7], [5,1])
swap2(sqColor, [0,8], [5,0])
swap2(sqColor, [1,8], [3,0])
swap2(sqColor, [1,5], [3,3])
swap2(sqColor, [1,2], [3,6])
elif comm == "F'":
swap4(sqColor, [2,0], [2,6], [2,8], [2,2])
swap4(sqColor, [2,1], [2,3], [2,7], [2,5])
swap4(sqColor, [0,6], [1,8], [5,2], [3,0])
swap4(sqColor, [0,7], [1,5], [5,1], [3,3])
swap4(sqColor, [0,8], [1,2], [5,0], [3,6])
elif comm == "R":
swap4(sqColor, [3,0], [3,2], [3,8], [3,6])
swap4(sqColor, [3,1], [3,5], [3,7], [3,3])
swap4(sqColor, [0,8], [4,0], [5,8], [2,8])
swap4(sqColor, [0,5], [4,3], [5,5], [2,5])
swap4(sqColor, [0,2], [4,6], [5,2], [2,2])
elif comm == "R2":
swap2(sqColor, [3,0], [3,8])
swap2(sqColor, [3,2], [3,6])
swap2(sqColor, [3,1], [3,7])
swap2(sqColor, [3,3], [3,5])
swap2(sqColor, [2,2], [4,6])
swap2(sqColor, [2,5], [4,3])
swap2(sqColor, [2,8], [4,0])
swap2(sqColor, [0,8], [5,8])
swap2(sqColor, [0,5], [5,5])
swap2(sqColor, [0,2], [5,2])
elif comm == "R'":
swap4(sqColor, [3,0], [3,6], [3,8], [3,2])
swap4(sqColor, [3,1], [3,3], [3,7], [3,5])
swap4(sqColor, [0,8], [2,8], [5,8], [4,0])
swap4(sqColor, [0,5], [2,5], [5,5], [4,3])
swap4(sqColor, [0,2], [2,2], [5,2], [4,6])
elif comm == "B":
swap4(sqColor, [4,0], [4,2], [4,8], [4,6])
swap4(sqColor, [4,1], [4,5], [4,7], [4,3])
swap4(sqColor, [0,2], [1,0], [5,6], [3,8])
swap4(sqColor, [0,1], [1,3], [5,7], [3,5])
swap4(sqColor, [0,0], [1,6], [5,8], [3,2])
elif comm == "B2":
swap2(sqColor, [4,0], [4,8])
swap2(sqColor, [4,2], [4,6])
swap2(sqColor, [4,1], [4,7])
swap2(sqColor, [4,3], [4,5])
swap2(sqColor, [0,2], [5,6])
swap2(sqColor, [0,1], [5,7])
swap2(sqColor, [0,0], [5,8])
swap2(sqColor, [1,0], [3,8])
swap2(sqColor, [1,3], [3,5])
swap2(sqColor, [1,6], [3,2])
elif comm == "B'":
swap4(sqColor, [4,0], [4,6], [4,8], [4,2])
swap4(sqColor, [4,1], [4,3], [4,7], [4,5])
swap4(sqColor, [0,2], [3,8], [5,6], [1,0])
swap4(sqColor, [0,1], [3,5], [5,7], [1,3])
swap4(sqColor, [0,0], [3,2], [5,8], [1,6])
elif comm == "D":
swap4(sqColor, [5,0], [5,2], [5,8], [5,6])
swap4(sqColor, [5,1], [5,5], [5,7], [5,3])
swap4(sqColor, [1,6], [2,6], [3,6], [4,6])
swap4(sqColor, [1,7], [2,7], [3,7], [4,7])
swap4(sqColor, [1,8], [2,8], [3,8], [4,8])
elif comm == "D2":
swap2(sqColor, [5,0], [5,8])
swap2(sqColor, [5,2], [5,6])
swap2(sqColor, [5,1], [5,7])
swap2(sqColor, [5,3], [5,5])
swap2(sqColor, [1,6], [3,6])
swap2(sqColor, [1,7], [3,7])
swap2(sqColor, [1,8], [3,8])
swap2(sqColor, [2,6], [4,6])
swap2(sqColor, [2,7], [4,7])
swap2(sqColor, [2,8], [4,8])
elif comm == "D'":
swap4(sqColor, [5,0], [5,6], [5,8], [5,2])
swap4(sqColor, [5,1], [5,3], [5,7], [5,5])
swap4(sqColor, [1,6], [4,6], [3,6], [2,6])
swap4(sqColor, [1,7], [4,7], [3,7], [2,7])
swap4(sqColor, [1,8], [4,8], [3,8], [2,8])
return sqColor
def swap4(sqColor, p0, p1, p2, p3):
temp = sqColor[p0[0]][p0[1]]
sqColor[p0[0]][p0[1]] = sqColor[p3[0]][p3[1]]
sqColor[p3[0]][p3[1]] = sqColor[p2[0]][p2[1]]
sqColor[p2[0]][p2[1]] = sqColor[p1[0]][p1[1]]
sqColor[p1[0]][p1[1]] = temp
return sqColor
def swap2(sqColor, p0, p1):
temp = sqColor[p0[0]][p0[1]]
sqColor[p0[0]][p0[1]] = sqColor[p1[0]][p1[1]]
sqColor[p1[0]][p1[1]] = temp
return sqColor
def setCube(sqColor):
done = 0
print('''
Faces Positions
0 0 1 2
1 2 3 4 3 4 5
5 6 7 8
0 = Blue, 1 = Red, 2 = Yellow, 3 = Orange, 4 = White, 5 = Green, 6 = Gray
Use Face = -1 to quit
''')
face = input('Enter a face to change: ')
if face in ['0', '1', '2', '3', '4', '5']:
pos = input('Enter a position to chance: ')
if pos in ['0', '1', '2', '3', '4', '5', '6', '7', '8']:
color = input('Enter the color: ')
if color in ['0', '1', '2', '3', '4', '5', '6']:
face = int(face)
pos = int(pos)
color = int(color)
sqColor[face][pos] = color
elif face == '-1':
done = 1
return done, sqColor
def buildLib():
xAxis = [["F"], ["F2"], ["F'"], ["B"], ["B2"], ["B'"],
["F", "B"], ["F", "B2"], ["F", "B'"],
["F2", "B"], ["F2", "B2"], ["F2", "B'"],
["F'", "B"], ["F'", "B2"], ["F'", "B'"] ]
yAxis = [["L"], ["L2"], ["L'"], ["R"], ["R2"], ["R'"],
["L", "R"], ["L", "R2"], ["L", "R'"],
["L2", "R"], ["L2", "R2"], ["L2", "R'"],
["L'", "R"], ["L'", "R2"], ["L'", "R'"] ]
zAxis = [["U"], ["U2"], ["U'"], ["D"], ["D2"], ["D'"],
["U", "D"], ["U", "D2"], ["U", "D'"],
["U2", "D"], ["U2", "D2"], ["U2", "D'"],
["U'", "D"], ["U'", "D2"], ["U'", "D'"] ]
maxDepth = 3
moveList = [ [move] for move in xAxis+yAxis+zAxis]
for firstMove in xAxis+yAxis+zAxis:
thisComm = [ firstMove ]
done = 0
goBack = 0
while done == 0:
if len( moveList ) % 1000 == 0:
print(len(moveList))
if len( thisComm ) < maxDepth and goBack == 0:
if thisComm[-1] in xAxis:
thisComm.append( yAxis[0] )
else:
thisComm.append( xAxis[0] )
else:
goBack = 0
lastMove = thisComm[-1]
if lastMove in xAxis:
if xAxis.index( lastMove ) < len( xAxis ) - 1:
thisComm[-1] = xAxis[ xAxis.index( lastMove ) + 1]
else:
if thisComm[-2] in yAxis:
thisComm[-1] = zAxis[0]
else:
thisComm[-1] = yAxis[0]
elif lastMove in yAxis:
if yAxis.index( lastMove ) < len( yAxis ) - 1:
thisComm[-1] = yAxis[ yAxis.index( lastMove ) + 1]
else:
if thisComm[-1] in xAxis:
thisComm[-1] = zAxis[0]
else:
if thisComm[-2] in xAxis:
thisComm[-1] = zAxis[0]
else:
thisComm = thisComm[:-1]
goBack = 1
elif lastMove in zAxis:
if zAxis.index( lastMove ) < len( xAxis) - 1:
thisComm[-1] = zAxis[ zAxis.index( lastMove ) + 1]
else:
thisComm = thisComm[:-1]
goBack = 1
if len( thisComm ) == 1:
done = 1
if goBack == 0 and done == 0:
moveList.append( thisComm[:] )
flatList = []
for move in moveList:
flatList.append( [ item for sublist in move for item in sublist ] )
pickle_out = open("flatList.pickle", 'wb')
pickle.dump(flatList, pickle_out)
pickle_out.close()
return
def buildPosLib():
pickle_in = open("flatList.pickle",'rb')
flatList = pickle.load(pickle_in)
pickle_in.close()
posList = [ [ [ i for ii in range(9) ] for i in range(6) ] ]
solList = [ [] ]
for moveSeq in flatList:
if len(solList) % 1000 == 0:
print(len(solList))
sqColor = [ [ i for ii in range(9) ] for i in range(6) ]
for move in moveSeq:
sqColor = permute(move, sqColor)
posList.append( [ sqColor ] )
solList.append( invertMoves( moveSeq ) )
pickle_out = open("posList.pickle",'wb')
pickle.dump(posList, pickle_out)
pickle_out.close()
pickle_out = open("solList.pickle",'wb')
pickle.dump(solList, pickle_out)
pickle_out.close()
def invertMoves( seq ):
inverted = []
for i in range(len(seq)):
j = i+1
if seq[-j] == "F":
inverted.append("F'")
elif seq[-j] == "F'":
inverted.append("F")
elif seq[-j] == "B":
inverted.append("B'")
elif seq[-j] == "B'":
inverted.append("B")
elif seq[-j] == "R":
inverted.append("R'")
elif seq[-j] == "R'":
inverted.append("R")
elif seq[-j] == "L":
inverted.append("L'")
elif seq[-j] == "L'":
inverted.append("L")
elif seq[-j] == "U":
inverted.append("U'")
elif seq[-j] == "U'":
inverted.append("U")
elif seq[-j] == "D":
inverted.append("D'")
elif seq[-j] == "D'":
inverted.append("D")
else:
inverted.append( seq[-j] )
return inverted
### Main program
comm = 0
while comm != 9:
comm = menu()
if comm == 1:
drawIt1(window1, sqPos, sqColor, drawColor)
playCube(sqColor)
elif comm == 2:
finished = 0
while finished == 0:
drawIt1(window1, sqPos, sqColor, drawColor)
finished, sqColor = setCube(sqColor)
drawIt1(window1, sqPos, sqColor, drawColor)
elif comm == 6:
buildPosLib()
elif comm == 7:
buildLib()
elif comm == 8:
sqColor = [ [ i for ii in range(9) ] for i in range(6) ]
elif comm == 9:
quit()
No comments:
Post a Comment