twisty-0.1.0: Twisty/CubeSymmetries.hs
{-
Copyright 2011 Google Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeFamilies #-}
-- | Operators for transforming algorithms of cube-based puzzles according to
-- the symmetries of the cube.
module Twisty.CubeSymmetries where
import Twisty.Cube
import Twisty.FaceTwist
import Twisty.Polyhedron
import Twisty.Puzzle
-- | Transforms a move by rotating it on the cube a quarter turn clockwise
-- around the given face.
rotateMove :: (Ord d) => Face -> CubeMove d -> CubeMove d
rotateMove f m@(FaceTwist f2 t d)
| f2 `neighbors` f = FaceTwist (nextNeighbor f f2) t d
| otherwise = m
-- | Transforms a move by reflecting it on the cube parallel to the given face.
reflectMove :: (Ord d) => Face -> CubeMove d -> CubeMove d
reflectMove f (FaceTwist f2 t d)
| f2 `neighbors` f = FaceTwist f2 (-t) d
| otherwise = FaceTwist (oppositeFace f2) (-t) d
type CubeSymmetry = forall p d. (Puzzle p, Ord d, Move p ~ CubeMove d) => Algorithm p -> Algorithm p
rotU :: CubeSymmetry -- ^ 1/4 turn around UD axis, clockwise according to U.
rotU = morph (rotateMove U)
rotF :: CubeSymmetry -- ^ 1/4 turn around FB axis, clockwise according to F.
rotF = morph (rotateMove F)
rotL :: CubeSymmetry -- ^ 1/4 turn around LR axis, clockwise according to L.
rotL = morph (rotateMove L)
rotR :: CubeSymmetry -- ^ 1/4 turn around LR axis, clockwise according to R.
rotR = morph (rotateMove R)
rotB :: CubeSymmetry -- ^ 1/4 turn around FB axis, clockwise according to B.
rotB = morph (rotateMove B)
rotD :: CubeSymmetry -- ^ 1/4 turn around UD axis, clockwise according to D.
rotD = morph (rotateMove D)
rotUD :: CubeSymmetry -- ^ 1/2 turn around UD axis.
rotUD = rotU . rotU
rotFB :: CubeSymmetry -- ^ 1/2 turn around FB axis.
rotFB = rotF . rotF
rotLR :: CubeSymmetry -- ^ 1/2 turn around LR axis.
rotLR = rotL . rotL
rotFR :: CubeSymmetry -- ^ 1/2 turn around FR edge.
rotFR = rotFB . rotU
rotFL :: CubeSymmetry -- ^ 1/2 turn around FL edge.
rotFL = rotU . rotFB
rotUL :: CubeSymmetry -- ^ 1/2 turn around UL edge.
rotUL = rotUD . rotF
rotUR :: CubeSymmetry -- ^ 1/2 turn around UR edge.
rotUR = rotF . rotUD
rotUB :: CubeSymmetry -- ^ 1/2 turn around UB edge.
rotUB = rotUD . rotL
rotUF :: CubeSymmetry -- ^ 1/2 turn around UF edge.
rotUF = rotL . rotUD
rotURF :: CubeSymmetry -- ^ 1/3 turn around diagonal.
rotURF = rotF . rotU
rotUFR :: CubeSymmetry -- ^ 1/3 turn around diagonal.
rotUFR = rotD . rotB
rotUFL :: CubeSymmetry -- ^ 1/3 turn around diagonal.
rotUFL = rotU . rotF
rotULF :: CubeSymmetry -- ^ 1/3 turn around diagonal.
rotULF = rotB . rotD
rotURB :: CubeSymmetry -- ^ 1/3 turn around diagonal.
rotURB = rotF . rotD
rotUBR :: CubeSymmetry -- ^ 1/3 turn around diagonal.
rotUBR = rotU . rotB
rotUBL :: CubeSymmetry -- ^ 1/3 turn around diagonal.
rotUBL = rotD . rotF
rotULB :: CubeSymmetry -- ^ 1/3 turn around diagonal.
rotULB = rotB . rotU
mirUD :: CubeSymmetry -- ^ Reflection across UD axis.
mirUD = morph (reflectMove U)
mirFB :: CubeSymmetry -- ^ Reflection across FB axis.
mirFB = morph (reflectMove F)
mirLR :: CubeSymmetry -- ^ Reflection across LR axis.
mirLR = morph (reflectMove L)
rotMirU :: CubeSymmetry -- ^ 1/4 turn around, and reflection across, UD axis, clockwise according to U.
rotMirU = rotU . mirUD
rotMirF :: CubeSymmetry -- ^ 1/4 turn around, and reflection across, FB axis, clockwise according to F.
rotMirF = rotF . mirFB
rotMirL :: CubeSymmetry -- ^ 1/4 turn around, and reflection across, LR axis, clockwise according to L.
rotMirL = rotL . mirLR
rotMirR :: CubeSymmetry -- ^ 1/4 turn around, and reflection across, UD axis, clockwise according to R.
rotMirR = rotR . mirLR
rotMirB :: CubeSymmetry -- ^ 1/4 turn around, and reflection across, FB axis, clockwise according to B.
rotMirB = rotB . mirFB
rotMirD :: CubeSymmetry -- ^ 1/4 turn around, and reflection across, LR axis, clockwise according to D.
rotMirD = rotD . mirUD
mirUL :: CubeSymmetry -- ^ Reflection across UL edge.
mirUL = rotF . mirUD
mirUR :: CubeSymmetry -- ^ Reflection across UR edge.
mirUR = mirUD . rotF
mirUF :: CubeSymmetry -- ^ Reflection across UF edge.
mirUF = mirUD . rotL
mirUB :: CubeSymmetry -- ^ Reflection across UB edge.
mirUB = rotL . mirUD
mirFL :: CubeSymmetry -- ^ Reflection across FL edge.
mirFL = mirFB . rotU
mirFR :: CubeSymmetry -- ^ Reflection across FR edge.
mirFR = rotU . mirFB
rotMirUFL :: CubeSymmetry -- ^ 1/6 turn around, and reflection across, diagonal.
rotMirUFL = rotURF . mirFB
rotMirUBL :: CubeSymmetry -- ^ 1/6 turn around, and reflection across, diagonal.
rotMirUBL = mirFB . rotURF
rotMirULB :: CubeSymmetry -- ^ 1/6 turn around, and reflection across, diagonal.
rotMirULB = rotUFR . mirFB
rotMirULF :: CubeSymmetry -- ^ 1/6 turn around, and reflection across, diagonal.
rotMirULF = mirFB . rotUFR
rotMirURF :: CubeSymmetry -- ^ 1/6 turn around, and reflection across, diagonal.
rotMirURF = rotUBL . mirFB
rotMirURB :: CubeSymmetry -- ^ 1/6 turn around, and reflection across, diagonal.
rotMirURB = mirFB . rotUBL
rotMirUFR :: CubeSymmetry -- ^ 1/6 turn around, and reflection across, diagonal.
rotMirUFR = mirFB . rotULB
rotMirUBR :: CubeSymmetry -- ^ 1/6 turn around, and reflection across, diagonal.
rotMirUBR = rotULB . mirFB
mir :: CubeSymmetry -- ^ Reflection across center of cube.
mir = mirUD . mirFB . mirLR