I am trying to complete a breadth first search to find the number of moves it takes to get to a permutation of a (masked) Rubik's cube, and then output this to a dictionary.
For testing, I have given it a cube where all facelets (face segments) have the same 'color' except one (this is the masked cube) - therefore it should return a dictionary with all possible locations of this one unique facelet, and how many moves it takes to get there. However, for some reason, it only manages to find 4 permutations - one for each 90 degree rotation of the face the facelet is on. I have tested the rotations of the other faces, and they work.
I thought this might have something to do with python not making deep copies of the cube/newCube variables - I have tried to work around this to no avail.
from cube import *
from solutionTools import *
from queue import Queue
import json
class Masker:
def __init__(self):
pass
def mask(self, cube: Cube, mask: list, maskTo: list, defaultMask: str="X") -> Cube:
ifCube = ifCubeGen(cube).constructIFCube().getState()
outCube = Cube().getState()
for i in range(6):
for j in range(3):
for k in range(3):
if ifCube[i][j][k] in mask:
outCube[i][j][k] = maskTo[mask.index(ifCube[i][j][k])]
else:
outCube[i][j][k] = defaultMask
return Cube(state=outCube)
class GeneratePruningTable:
def __init__(self):
pass
def BFS(self, start: Cube) -> dict:
queue: Queue[Cube] = Queue()
depth = 0
table = {}
queue.put(start)
while queue.qsize() > 0:
layer_size = queue.qsize()
while layer_size > 0:
cube = queue.get()
key = cube.generateKey()
if key not in table:
table[key] = depth
for i in range(6):
for j in range(2):
newCube = Cube(state=cube.getState().copy())
if j == 0:
dir = 1
else:
dir = -1
newCube.rotateFace(i, dir)
queue.put(Cube(state=newCube.getState().copy()))
layer_size -= 1
print(f"Depth {depth} complete")
depth += 1
return table
def writeTableToFile(self, table: dict, directory: str):
with open(directory, "w") as f:
json.dump(table, f)
cube = Cube()
mask = ["U0"]
maskTo = ["U"]
m = Masker()
masked = m.mask(cube, mask, maskTo)
#masked.rotateFace(4, 1)
#print(masked.generateKey())
gen = GeneratePruningTable()
table = gen.BFS(masked)
gen.writeTableToFile(table, r"testDB.json")
Output (in testDB.json): - This shows that the 'U' facelet is staying within the U face.
{"UXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX": 0, "XXXXXUXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX": 1, "XXUXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX": 1, "XXXXXXXUXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX": 2}
SOLUTION FOUND
My suspicion was correct but I stupidly thought I was deep copying by using list.copy().
Instead, import copy and use copy.deepcopy(list).
This now works.