def solution(self): solution = [] for color in 'RGOB': cubie_position = self.cube.search_by_colors('W', color) orig_cubie = self.cube.cubies[cubie_position] white_facing = orig_cubie.color_facing('W') color_facing = orig_cubie.color_facing(color) step_solution = WhiteCrossSolver.first_step( white_facing, color_facing) # First goal is to put white sticker on top face for m in step_solution: self.cube.move(Move(m)) solution.extend(step_solution) # Second goal is to place the cubie on the top over its place while self.cube.cubies['FU'].facings[ 'U'] != 'W' or self.cube.cubies['FU'].facings['F'] != color: solution.append('U') self.cube.move(Move('U')) # Third goal will be a F2 movement solution.append("F2") self.cube.move(Move("F2")) solution.append('Y') self.cube.move(Move("Y")) return solution
def solution(self): solution = [] # There are 4 down-corners for _ in range(4): front_color = self.cube.cubies['F'].facings['F'] right_color = self.cube.cubies['R'].facings['R'] goal_cubie = self.cube.search_by_colors('W', front_color, right_color) goal_cubie_obj = self.cube.cubies[goal_cubie] step_solution = WhiteFaceSolver.first_step(goal_cubie, goal_cubie_obj.color_facing('W')) for move in step_solution: self.cube.move(Move(move)) # If corner is not already well placed and oriented, continue if len(step_solution) > 0 or goal_cubie != 'DFR': # Cubie is at FRU, place it at DRU with correct orientation solution.extend(step_solution) step_solution = WhiteFaceSolver.second_step(self.cube.cubies['FRU'].color_facing('W')) for move in step_solution: self.cube.move(Move(move)) solution.extend(step_solution) # Cubie is placed, move to next solution.append('Y') self.cube.move(Move('Y')) return solution
def solution(self): solution = [] for _ in range(4): front_color = self.cube.cubies['F'].facings['F'].color right_color = self.cube.cubies['R'].facings['R'].color corner = self.cube.search_by_colors(front_color, right_color, 'W') step_solution = WhiteFaceSolver.first_step( corner, self.cube.cubies[corner].color_facing('W')) solution.extend(step_solution) for s in step_solution: self.cube.move(Move(s)) edge = self.cube.search_by_colors(front_color, right_color) # If edge is in BL or BR, WAF!, this case is not expected in any manual if edge == 'BL': self.move("B'", solution) self.move("U'", solution) self.move("B", solution) elif edge == 'BR': self.move("B", solution) self.move("U", solution) self.move("B'", solution) elif edge == 'FL': self.move("L'", solution) self.move("U'", solution) self.move("L", solution) corner = self.cube.search_by_colors(front_color, right_color, 'W') #Place corner in FRU if needed if 'U' in corner: while corner != 'FRU': self.move("U", solution) corner = self.cube.search_by_colors( front_color, right_color, 'W') edge = self.cube.search_by_colors(front_color, right_color) corner_facings = ''.join([ self.cube.cubies[corner].color_facing(front_color), self.cube.cubies[corner].color_facing(right_color), self.cube.cubies[corner].color_facing('W') ]) edge_facings = ''.join([ self.cube.cubies[edge].color_facing(front_color), self.cube.cubies[edge].color_facing(right_color) ]) step_solution = F2LSolver.get_step(corner_facings, edge_facings) solution.extend(step_solution) for s in step_solution: self.cube.move(Move(s)) self.cube.move(Move("Y")) solution.append("Y") return solution
def solution(self): cube = copy.deepcopy(self.cube) solution = WhiteCrossSolver.WhiteCrossSolver(cube).solution() solution += F2LSolver.F2LSolver(cube).solution() solution += OLLSolver.OLLSolver(cube).solution() solution += PLLSolver.PLLSolver(cube).solution() # Align top layer while cube.cubies['F'].facings['F'] != cube.cubies['FU'].facings['F']: cube.move(Move('U')) return [Move(m) for m in solution]
def test_first_step(self): goals = [ 'DFR', 'DFL', 'BDL', 'BDR', 'BRU', 'BLU', 'FLU', ] for goal in goals: c = Cube() solver = WhiteFaceSolver(c) # Muahaha at that range for i in range(1 if goal == 'DFR' else 0, 3): c.cubies[goal].facings[goal[i % 3]] = 'W' c.cubies[goal].facings[goal[(i + 1) % 3]] = 'Y' c.cubies[goal].facings[goal[(i + 2) % 3]] = 'O' steps = WhiteFaceSolver.first_step(goal, goal[i % 3]) for s in steps: c.move(Move(s)) self.assertIn('W', c.cubies['FRU'].colors, "%s --> %d" % (goal, i)) self.assertIn('Y', c.cubies['FRU'].colors, "%s --> %d" % (goal, i)) self.assertIn('O', c.cubies['FRU'].colors, "%s --> %d" % (goal, i))
def test_steps(self): cubies = ['BLU', 'BU', 'BRU', 'LU', 'U', 'RU', 'FLU', 'FU', 'FRU'] orientations = { 2: { '1': 'BU', '3': 'LU', '5': 'RU', '7': 'FU' }, 3: { '0': 'BLU', '2': 'RBU', '6': 'LFU', '8': 'FRU' } } cr = Cube() for orientation, steps in PLLSolver.STEPS.items(): c = Cube() for i, oriented in enumerate(orientation): if i != 4: # The center cubie doesn't need to be relocated cubie_or = cubies[i] cubie_dest = cubies[int(oriented)] orient_or = orientations[len(cubie_or)][str(i)] orient_dest = orientations[len(cubie_or)][oriented] kwargs = {} for j, orient in enumerate(orient_or): kwargs[orient_dest[j]] = cr.cubies[cubie_or].facings[ orient].color c.cubies[cubie_dest] = Cubie(**kwargs) for s in steps: c.move(Move(s)) while cr.cubies['F'].facings['F'] != c.cubies['F'].facings['F']: c.move(Move('Y')) for cubie in cr.cubies: for facing in cr.cubies[cubie].facings: self.assertEqual( cr.cubies[cubie].facings[facing], c.cubies[cubie].facings[facing], msg= '%s != %s -> Fail PLL with %s orientation on cubie %s' % (cr.cubies[cubie].facings[facing].color, c.cubies[cubie].facings[facing].color, orientation, cubie))
def solution(self): cube = copy.deepcopy(self.cube) solution = WhiteCrossSolver.WhiteCrossSolver(cube).solution() solution += WhiteFaceSolver.WhiteFaceSolver(cube).solution() solution += SecondLayerSolver.SecondLayerSolver(cube).solution() solution += YellowCrossSolver.YellowCrossSolver(cube).solution() solution += YellowFaceSolver.YellowFaceSolver(cube).solution() return [Move(m) for m in solution]
def _check_solution(self, c, solution): cr = Cube() for s in solution: c.move(s) # Align faces while cr.cubies['F'].facings['F'] != c.cubies['F'].facings['F']: c.move(Move('Y')) for cubie in cr.cubies: for facing in cr.cubies[cubie].facings: self.assertEqual(cr.cubies[cubie].facings[facing], c.cubies[cubie].facings[facing])
def test_logic(self): m = Move(self.allowed_moves[0]) self.assertTrue(m.clockwise) self.assertFalse(m.counterclockwise) self.assertFalse(m.double) m.double = True self.assertFalse(m.clockwise) self.assertFalse(m.counterclockwise) self.assertTrue(m.double) m.double = False self.assertTrue(m.clockwise) self.assertFalse(m.counterclockwise) self.assertFalse(m.double) m.counterclockwise = True self.assertFalse(m.clockwise) self.assertTrue(m.counterclockwise) self.assertFalse(m.double) m.counterclockwise = False self.assertTrue(m.clockwise) self.assertFalse(m.counterclockwise) self.assertFalse(m.double)
def test_corner_is_placed(self): c = Cube() solver = YellowFaceSolver(c) for _ in range(4): c.move(Move('U')) for corner in ['FRU', 'FLU', 'BRU', 'BLU']: self.assertTrue(solver.corner_is_placed(corner)) self.assertTrue(solver.placed_corners()) for corner in ['FRU', 'FLU', 'BRU', 'BLU']: c = Cube() solver = YellowFaceSolver(c) c.cubies[corner].facings[corner[0]] = 'W' self.assertFalse(solver.corner_is_placed(corner))
def test_second_step(self): # Case 1 c = Cube() c.cubies['FRU'].facings['F'] = 'W' c.cubies['FRU'].facings['R'] = 'Y' c.cubies['FRU'].facings['U'] = 'O' steps = WhiteFaceSolver.second_step('F') for s in steps: c.move(Move(s)) self.assertEqual(c.cubies['DFR'].facings['D'], 'W') self.assertEqual(c.cubies['DFR'].facings['F'], 'O') self.assertEqual(c.cubies['DFR'].facings['R'], 'Y') # Case 2 c = Cube() c.cubies['FRU'].facings['F'] = 'O' c.cubies['FRU'].facings['R'] = 'W' c.cubies['FRU'].facings['U'] = 'Y' steps = WhiteFaceSolver.second_step('R') for s in steps: c.move(Move(s)) self.assertEqual(c.cubies['DFR'].facings['D'], 'W') self.assertEqual(c.cubies['DFR'].facings['F'], 'O') self.assertEqual(c.cubies['DFR'].facings['R'], 'Y') # Case 3 c = Cube() c.cubies['FRU'].facings['F'] = 'O' c.cubies['FRU'].facings['R'] = 'Y' c.cubies['FRU'].facings['U'] = 'W' steps = WhiteFaceSolver.second_step('U') for s in steps: c.move(Move(s)) self.assertEqual(c.cubies['DFR'].facings['D'], 'W') self.assertEqual(c.cubies['DFR'].facings['F'], 'Y') self.assertEqual(c.cubies['DFR'].facings['R'], 'O')
def _check_solution(self, c, solution): cr = Cube() for s in solution: c.move(s) # Align faces while cr.cubies['F'].facings['F'] != c.cubies['F'].facings['F']: c.move(Move('Y')) for cubie in cr.cubies: for facing in cr.cubies[cubie].facings: self.assertEqual( cr.cubies[cubie].facings[facing], c.cubies[cubie].facings[facing], msg='Invalid solution at cubie %s --> %s != %s' % (cubie, cr.cubies[cubie].facings[facing], c.cubies[cubie].facings[facing]))
def test_solution(self): for i in range(1): c = Cube() cr = Cube() c.shuffle(i) cross_steps = WhiteCrossSolver(c).solution() solution = self._test_solution(c) # Align faces while cr.cubies['F'].facings['F'] != c.cubies['F'].facings['F']: c.move(Move('Y')) for cubie in cr.cubies: for facing in cr.cubies[cubie].facings: # Upper cubies aren't positioned if 'U' not in cubie: self.assertEqual(cr.cubies[cubie].facings[facing], c.cubies[cubie].facings[facing])
def test_reverse(self): m = Move(self.allowed_moves[0]) m1 = m.reverse() self.assertFalse(m1.clockwise) self.assertTrue(m1.counterclockwise) self.assertFalse(m1.double) m.double = True m1 = m.reverse() self.assertFalse(m1.clockwise) self.assertFalse(m1.counterclockwise) self.assertTrue(m1.double) m.counterclockwise = True m1 = m.reverse() self.assertTrue(m1.clockwise) self.assertFalse(m1.counterclockwise) self.assertFalse(m1.double)
def test_steps(self): for orientation, steps in OLLSolver.STEPS.items(): c = Cube() for i, cubie in enumerate( ['BLU', 'BU', 'BRU', 'LU', 'U', 'RU', 'FLU', 'FU', 'FRU']): for facing in cubie: if facing == orientation[i]: c.cubies[cubie].facings[facing].color = 'Y' else: c.cubies[cubie].facings[facing].color = 'W' for s in steps: c.move(Move(s)) for i, cubie in enumerate( ['BLU', 'BU', 'BRU', 'LU', 'U', 'RU', 'FLU', 'FU', 'FRU']): self.assertEqual( c.cubies[cubie].facings['U'].color, 'Y', msg='%s != %s -> Fail OLL with %s orientation on cubie %s' % (c.cubies[cubie].facings['U'], 'Y', orientation, cubie))
def test_steps(self): for corner in F2LSolver.STEPS: for edge, steps in F2LSolver.STEPS[corner].items(): c = Cube() tmp = c.cubies[Cube._t_key(corner)] orig_corner = ''.join([ tmp.facings[corner[0]].color, tmp.facings[corner[1]].color, tmp.facings[corner[2]].color ]) tmp = c.cubies[Cube._t_key(edge)] orig_edge = ''.join([ tmp.facings[edge[0]].color, tmp.facings[edge[1]].color, ]) for s in steps: c.move(Move(s)) dest_corner = ''.join([ c.cubies['DFR'].facings['F'].color, c.cubies['DFR'].facings['R'].color, c.cubies['DFR'].facings['D'].color, ]) dest_edge = ''.join([ c.cubies['FR'].facings['F'].color, c.cubies['FR'].facings['R'].color, ]) self.assertEqual( dest_corner, orig_corner, msg='Failed F2L corner check corner:%s edge:%s (%s != %s)' % (corner, edge, dest_corner, orig_corner)) self.assertEqual( dest_edge, orig_edge, msg='Failed F2L edge check corner:%s edge:%s (%s != %s)' % (corner, edge, dest_edge, orig_edge))
def test_solution(self): cases = [ ('D', 'F'), ('D', 'B'), ('D', 'R'), ('D', 'L'), ('F', 'U'), ('F', 'D'), ('F', 'R'), ('F', 'L'), ('B', 'U'), ('B', 'D'), ('B', 'R'), ('B', 'L'), ('R', 'U'), ('R', 'D'), ('R', 'F'), ('R', 'B'), ('L', 'U'), ('L', 'D'), ('L', 'F'), ('L', 'B'), ] for c0, c1 in cases: c = Cube() # Use an "imposible" edge to move, so it is not duped in the cube c.cubies[c._t_key(c0 + c1)].facings[c0].color = 'W' c.cubies[c._t_key(c0 + c1)].facings[c1].color = 'Y' steps = WhiteCrossSolver.first_step(c0, c1) for step in steps: c.move(Move(step)) place = c.search_by_colors('W', 'Y') self.assertEqual(c.cubies[place].facings['U'], 'W') # Weird, but works self.assertEqual(c.cubies[place].facings[place.replace('U', '')], 'Y')
def move(self, move, solution): solution.append(move) self.cube.move(Move(move))
def test_init(self): for c in string.ascii_lowercase: if c in self.allowed_moves: self.assertEqual(Move(c).raw, c.upper()) self.assertEqual(Move(c.upper()).raw, c.upper()) self.assertEqual(Move(c + "2").raw, c.upper() + "2") self.assertEqual(Move(c.upper() + "2").raw, c.upper() + "2") self.assertEqual(Move(c + "'").raw, c.upper() + "'") self.assertEqual(Move(c.upper() + "'").raw, c.upper() + "'") self.assertEqual(Move(c).face, c.upper()) self.assertEqual(Move(c.upper()).face, c.upper()) self.assertEqual(Move(c + "2").face, c.upper()) self.assertEqual(Move(c.upper() + "2").face, c.upper()) self.assertEqual(Move(c + "'").face, c.upper()) self.assertEqual(Move(c.upper() + "'").face, c.upper()) self.assertTrue(Move(c).clockwise) self.assertFalse(Move(c).counterclockwise) self.assertFalse(Move(c).double) self.assertFalse(Move(c + "'").clockwise) self.assertTrue(Move(c + "'").counterclockwise) self.assertFalse(Move(c + "'").double) self.assertFalse(Move(c + "2").clockwise) self.assertFalse(Move(c + "2").counterclockwise) self.assertTrue(Move(c + "2").double) else: with self.assertRaises(ValueError): Move(c) with self.assertRaises(ValueError): Move(c + "'") with self.assertRaises(ValueError): Move(c + "2")
def test_equals(self): self.assertEqual(Move("F"), 'f') self.assertEqual(Move("f"), 'f') self.assertEqual(Move("F"), 'F') self.assertEqual(Move("f"), 'F') self.assertEqual(Move("F"), Move("f")) self.assertNotEqual(Move("F"), "B") self.assertNotEqual(Move("F"), "b") self.assertNotEqual(Move("F"), Move("B")) self.assertEqual(Move("F'"), "f'") self.assertEqual(Move("f'"), "f'") self.assertEqual(Move("F'"), "F'") self.assertEqual(Move("f'"), "F'") self.assertEqual(Move("F'"), Move("f'")) self.assertNotEqual(Move("F'"), "B") self.assertEqual(Move("F2"), "f2") self.assertEqual(Move("f2"), "f2") self.assertEqual(Move("F2"), "F2") self.assertEqual(Move("f2"), "F2") self.assertEqual(Move("F2"), Move("f2")) self.assertNotEqual(Move("F2"), "B")
def solution(self, maxDepth=23, timeOut=100): solution = Search.Search.solution( self.cube.to_naive_cube().to_face_cube().to_String(), maxDepth, timeOut) return [Move(m) for m in solution]
def move(self, m, solution): self.cube.move(Move(m)) solution.append(m)
def test_maths(self): m = Move(self.allowed_moves[0]) for c in self.allowed_moves[1:]: with self.assertRaises(ValueError): m1 = m + Move(c) self.assertIsNone(Move("f") + Move("f'")) self.assertIsNone(Move("f2") + Move("f2")) self.assertEqual(Move("f") + Move("f"), "F2") self.assertEqual(Move("f") + Move("f") + Move("f"), "F'") self.assertEqual(Move("f2") + Move("f"), "F'") self.assertIsNone(Move("f") + Move("f") + Move("f") + Move("f")) self.assertIsNone(Move("f") * 4) self.assertIsNone(Move("f") * 8) self.assertEqual(Move("f") * 2, Move("f2")) self.assertEqual(Move("f") * 3, Move("f'")) self.assertEqual(Move("f'") * 2, Move("f2")) self.assertEqual(Move("f'") * 3, Move("f")) self.assertIsNone(Move("f2") * 2) self.assertIsNone(Move("f2") * 4)
def test_edges_are_placed(self): c = Cube() solver = YellowFaceSolver(c) for _ in range(4): c.move(Move('U')) self.assertTrue(solver.edges_are_placed())
def move(self, s, solution): self.cube.move(Move(s)) solution.append(s)