Files
eolrb/eolr.py

128 lines
3.4 KiB
Python

from dataclasses import dataclass
from enum import Enum
import itertools
from typing import List, Tuple, Iterator
from cube import Edge, LSECube
class EOLROrientation(Enum):
Arrow = ["UR", "UF", "UL", "DF"]
BackArrow = ["UR", "UF", "UL", "DB"]
FourZero = ["UB", "UR", "UF", "UL"]
OneOne = ["UB", "DF"]
BackOneOne = ["UB", "DB"]
SixFlip = ["UB", "UR", "UF", "UL", "DF", "DB"]
Solved = []
TwoAdjTwo = ["UB", "UR", "DF", "DB"]
TwoAdjZero = ["UB", "UR"]
TwoOppTwo = ["UB", "UF", "DF", "DB"]
TwoOppZero = ["UB", "UF"]
ZeroTwo = ["DF", "DB"]
@dataclass
class EOLRPermutation:
UR: str
UL: str
EOLR_PERMUTATIONS = [
EOLRPermutation(ur_pos, ul_pos)
for ul_pos, ur_pos in itertools.permutations(
["UB", "UR", "UF", "UL", "DF", "DB"], 2
)
]
EOLR_EDGES = [
"UB",
"UR",
"UF",
"UL",
"DF",
"DB",
]
def apply_eolr_orientation(cube: LSECube, ori: EOLROrientation):
for edge in ori.value:
cube.edges[edge].oriented = not cube.edges[edge].oriented
def apply_eolr_permutation(cube: LSECube, perm: EOLRPermutation):
cube.edges[perm.UR], cube.edges["UR"] = cube.edges["UR"], cube.edges[perm.UR]
cube.edges[perm.UL], cube.edges["UL"] = cube.edges["UL"], cube.edges[perm.UL]
def apply_eolr_auf(cube: LSECube, auf: int):
cube.cycle_corners(auf)
def eolrb_states_generator(
orientations: List[EOLROrientation], permutations: List[EOLRPermutation]
) -> Tuple[Iterator[Tuple[LSECube, EOLROrientation, EOLRPermutation, int]], int]:
num_permutations = len(orientations) * len(permutations) * 4
def generator():
for ori in orientations:
for perm in permutations:
for auf in range(4):
state = LSECube()
apply_eolr_auf(state, auf)
# applying permutation before orientation is crucial, as permutation swaps pieces and doesn't care about their orientation
apply_eolr_permutation(state, perm)
apply_eolr_orientation(state, ori)
yield (state, ori, perm, auf)
return generator(), num_permutations
def lr_solved(cube: LSECube):
return cube.edges["UR"] == Edge("UR", True) and cube.edges["UL"] == Edge("UL", True)
def eo_solved_non_mc(cube: LSECube) -> bool:
return (
cube.edges["UB"].oriented
and cube.edges["UF"].oriented
and cube.edges["DF"].oriented
and cube.edges["DB"].oriented
)
def centers_solved_non_mc(cube: LSECube) -> bool:
return cube.centers["U"] in ["U", "D"]
def eo_solved_mc(cube: LSECube) -> bool:
return (
not cube.edges["UB"].oriented
and not cube.edges["UF"].oriented
and not cube.edges["DF"].oriented
and not cube.edges["DB"].oriented
)
def centers_solved_mc(cube: LSECube) -> bool:
return cube.centers["U"] in ["F", "B"]
def eolrb_solved(cube: LSECube) -> bool:
"""
this function has weird side effects and modifies cube but we don't care about it for now
"""
if not lr_solved(cube):
return False
if centers_solved_non_mc(cube) and eo_solved_non_mc(cube):
return True
if centers_solved_mc(cube) and eo_solved_mc(cube):
return True
return False
def eolrb_solution_mc(cube: LSECube) -> bool:
"""
this function only works if eolrb is solved
"""
return centers_solved_mc(cube) and eo_solved_mc(cube)