module BishBosh.Direction.Diagonal(
Diagonal()
) where
import Control.Arrow((***))
import qualified BishBosh.Direction.Horizontal as Direction.Horizontal
import qualified BishBosh.Direction.Vertical as Direction.Vertical
import qualified BishBosh.Property.FixedMembership as Property.FixedMembership
import qualified BishBosh.Property.Opposable as Property.Opposable
import qualified BishBosh.Property.Orientated as Property.Orientated
import qualified BishBosh.Property.Reflectable as Property.Reflectable
import qualified Control.DeepSeq
import qualified Data.List.Extra
data Diagonal = MkDiagonal {
Diagonal -> Vertical
getVertical :: Direction.Vertical.Vertical,
Diagonal -> Horizontal
getHorizontal :: Direction.Horizontal.Horizontal
} deriving (Diagonal -> Diagonal -> Bool
(Diagonal -> Diagonal -> Bool)
-> (Diagonal -> Diagonal -> Bool) -> Eq Diagonal
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Diagonal -> Diagonal -> Bool
$c/= :: Diagonal -> Diagonal -> Bool
== :: Diagonal -> Diagonal -> Bool
$c== :: Diagonal -> Diagonal -> Bool
Eq, Eq Diagonal
Eq Diagonal
-> (Diagonal -> Diagonal -> Ordering)
-> (Diagonal -> Diagonal -> Bool)
-> (Diagonal -> Diagonal -> Bool)
-> (Diagonal -> Diagonal -> Bool)
-> (Diagonal -> Diagonal -> Bool)
-> (Diagonal -> Diagonal -> Diagonal)
-> (Diagonal -> Diagonal -> Diagonal)
-> Ord Diagonal
Diagonal -> Diagonal -> Bool
Diagonal -> Diagonal -> Ordering
Diagonal -> Diagonal -> Diagonal
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Diagonal -> Diagonal -> Diagonal
$cmin :: Diagonal -> Diagonal -> Diagonal
max :: Diagonal -> Diagonal -> Diagonal
$cmax :: Diagonal -> Diagonal -> Diagonal
>= :: Diagonal -> Diagonal -> Bool
$c>= :: Diagonal -> Diagonal -> Bool
> :: Diagonal -> Diagonal -> Bool
$c> :: Diagonal -> Diagonal -> Bool
<= :: Diagonal -> Diagonal -> Bool
$c<= :: Diagonal -> Diagonal -> Bool
< :: Diagonal -> Diagonal -> Bool
$c< :: Diagonal -> Diagonal -> Bool
compare :: Diagonal -> Diagonal -> Ordering
$ccompare :: Diagonal -> Diagonal -> Ordering
$cp1Ord :: Eq Diagonal
Ord)
instance Control.DeepSeq.NFData Diagonal where
rnf :: Diagonal -> ()
rnf MkDiagonal {
getVertical :: Diagonal -> Vertical
getVertical = Vertical
_,
getHorizontal :: Diagonal -> Horizontal
getHorizontal = Horizontal
_
} = ()
instance Enum Diagonal where
fromEnum :: Diagonal -> Int
fromEnum MkDiagonal {
getVertical :: Diagonal -> Vertical
getVertical = Vertical
v,
getHorizontal :: Diagonal -> Horizontal
getHorizontal = Horizontal
h
} = Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
Direction.Vertical.nVerticals Int -> Int -> Int
forall a. Num a => a -> a -> a
* Vertical -> Int
forall a. Enum a => a -> Int
fromEnum Vertical
v Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Horizontal -> Int
forall a. Enum a => a -> Int
fromEnum Horizontal
h
toEnum :: Int -> Diagonal
toEnum Int
i = (Vertical -> Horizontal -> Diagonal)
-> (Vertical, Horizontal) -> Diagonal
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Vertical -> Horizontal -> Diagonal
MkDiagonal ((Vertical, Horizontal) -> Diagonal)
-> ((Int, Int) -> (Vertical, Horizontal)) -> (Int, Int) -> Diagonal
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> Vertical
forall a. Enum a => Int -> a
toEnum (Int -> Vertical)
-> (Int -> Horizontal) -> (Int, Int) -> (Vertical, Horizontal)
forall (a :: * -> * -> *) b c b' c'.
Arrow a =>
a b c -> a b' c' -> a (b, b') (c, c')
*** Int -> Horizontal
forall a. Enum a => Int -> a
toEnum) ((Int, Int) -> Diagonal) -> (Int, Int) -> Diagonal
forall a b. (a -> b) -> a -> b
$! Int
i Int -> Int -> (Int, Int)
forall a. Integral a => a -> a -> (a, a)
`divMod` Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
Direction.Vertical.nVerticals
instance Show Diagonal where
showsPrec :: Int -> Diagonal -> ShowS
showsPrec Int
precedence MkDiagonal {
getVertical :: Diagonal -> Vertical
getVertical = Vertical
v,
getHorizontal :: Diagonal -> Horizontal
getHorizontal = Horizontal
h
} = Int -> Vertical -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
precedence Vertical
v ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Horizontal -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
precedence Horizontal
h
instance Read Diagonal where
readsPrec :: Int -> ReadS Diagonal
readsPrec Int
precedence String
s = case Int -> ReadS Vertical
forall a. Read a => Int -> ReadS a
readsPrec Int
precedence ReadS Vertical -> ReadS Vertical
forall a b. (a -> b) -> a -> b
$ ShowS
Data.List.Extra.trimStart String
s of
[(Vertical
vertical, String
s')] -> case Int -> ReadS Horizontal
forall a. Read a => Int -> ReadS a
readsPrec Int
precedence String
s' of
[(Horizontal
horizontal, String
s'')] -> [
(
MkDiagonal :: Vertical -> Horizontal -> Diagonal
MkDiagonal {
getVertical :: Vertical
getVertical = Vertical
vertical,
getHorizontal :: Horizontal
getHorizontal = Horizontal
horizontal
},
String
s''
)
]
[(Horizontal, String)]
_ -> []
[(Vertical, String)]
_ -> []
instance Property.FixedMembership.FixedMembership Diagonal where
members :: [Diagonal]
members = (Vertical -> Horizontal -> Diagonal)
-> [Vertical] -> [Horizontal -> Diagonal]
forall a b. (a -> b) -> [a] -> [b]
map Vertical -> Horizontal -> Diagonal
MkDiagonal [Vertical]
forall a. FixedMembership a => [a]
Property.FixedMembership.members [Horizontal -> Diagonal] -> [Horizontal] -> [Diagonal]
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> [Horizontal]
forall a. FixedMembership a => [a]
Property.FixedMembership.members
instance Property.Opposable.Opposable Diagonal where
getOpposite :: Diagonal -> Diagonal
getOpposite MkDiagonal {
getVertical :: Diagonal -> Vertical
getVertical = Vertical
v,
getHorizontal :: Diagonal -> Horizontal
getHorizontal = Horizontal
h
} = MkDiagonal :: Vertical -> Horizontal -> Diagonal
MkDiagonal {
getVertical :: Vertical
getVertical = Vertical -> Vertical
forall a. Opposable a => a -> a
Property.Opposable.getOpposite Vertical
v,
getHorizontal :: Horizontal
getHorizontal = Horizontal -> Horizontal
forall a. Opposable a => a -> a
Property.Opposable.getOpposite Horizontal
h
}
instance Property.Orientated.Orientated Diagonal where
isParallel :: Diagonal -> Bool
isParallel = Bool -> Diagonal -> Bool
forall a b. a -> b -> a
const Bool
False
isDiagonal :: Diagonal -> Bool
isDiagonal = Bool -> Diagonal -> Bool
forall a b. a -> b -> a
const Bool
True
isStraight :: Diagonal -> Bool
isStraight = Bool -> Diagonal -> Bool
forall a b. a -> b -> a
const Bool
True
instance Property.Reflectable.ReflectableOnX Diagonal where
reflectOnX :: Diagonal -> Diagonal
reflectOnX diagonal :: Diagonal
diagonal@MkDiagonal {
getVertical :: Diagonal -> Vertical
getVertical = Vertical
v
} = Diagonal
diagonal {
getVertical :: Vertical
getVertical = Vertical -> Vertical
forall a. ReflectableOnX a => a -> a
Property.Reflectable.reflectOnX Vertical
v
}
instance Property.Reflectable.ReflectableOnY Diagonal where
reflectOnY :: Diagonal -> Diagonal
reflectOnY diagonal :: Diagonal
diagonal@MkDiagonal {
getHorizontal :: Diagonal -> Horizontal
getHorizontal = Horizontal
h
} = Diagonal
diagonal {
getHorizontal :: Horizontal
getHorizontal = Horizontal -> Horizontal
forall a. ReflectableOnY a => a -> a
Property.Reflectable.reflectOnY Horizontal
h
}