{-# LANGUAGE PatternSynonyms #-}
module Game.Chess.Internal.Square where

import           Control.Lens   (Iso', from, iso, view)
import           Data.Bifunctor (Bifunctor (..))
import           Data.Binary    (Binary (get, put), getWord8, putWord8)
import           Data.Bits      (Bits (testBit))
import           Data.Char      (chr, ord)
import           Data.Coerce    (coerce)
import           Data.Ix        (Ix (..))
import           Data.String    (IsString (fromString))
import           Data.Word      (Word64)
import           GHC.Stack      (HasCallStack)

newtype Rank = Rank Int deriving (Rank -> Rank -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Rank -> Rank -> Bool
$c/= :: Rank -> Rank -> Bool
== :: Rank -> Rank -> Bool
$c== :: Rank -> Rank -> Bool
Eq, Eq Rank
Rank -> Rank -> Bool
Rank -> Rank -> Ordering
Rank -> Rank -> Rank
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 :: Rank -> Rank -> Rank
$cmin :: Rank -> Rank -> Rank
max :: Rank -> Rank -> Rank
$cmax :: Rank -> Rank -> Rank
>= :: Rank -> Rank -> Bool
$c>= :: Rank -> Rank -> Bool
> :: Rank -> Rank -> Bool
$c> :: Rank -> Rank -> Bool
<= :: Rank -> Rank -> Bool
$c<= :: Rank -> Rank -> Bool
< :: Rank -> Rank -> Bool
$c< :: Rank -> Rank -> Bool
compare :: Rank -> Rank -> Ordering
$ccompare :: Rank -> Rank -> Ordering
Ord)

unRank :: Rank -> Int
unRank :: Rank -> Int
unRank = coerce :: forall a b. Coercible a b => a -> b
coerce

mkRank :: HasCallStack => Int -> Rank
mkRank :: HasCallStack => Int -> Rank
mkRank Int
n | Int
n forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
n forall a. Ord a => a -> a -> Bool
<= Int
7 = Int -> Rank
Rank Int
n
         | Bool
otherwise        = forall a. HasCallStack => [Char] -> a
error forall a b. (a -> b) -> a -> b
$ [Char]
"mkRank " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Int
n

instance Show Rank where
  showsPrec :: Int -> Rank -> ShowS
showsPrec Int
_ (Rank Int
0) = [Char] -> ShowS
showString [Char]
"Rank1"
  showsPrec Int
_ (Rank Int
1) = [Char] -> ShowS
showString [Char]
"Rank2"
  showsPrec Int
_ (Rank Int
2) = [Char] -> ShowS
showString [Char]
"Rank3"
  showsPrec Int
_ (Rank Int
3) = [Char] -> ShowS
showString [Char]
"Rank4"
  showsPrec Int
_ (Rank Int
4) = [Char] -> ShowS
showString [Char]
"Rank5"
  showsPrec Int
_ (Rank Int
5) = [Char] -> ShowS
showString [Char]
"Rank6"
  showsPrec Int
_ (Rank Int
6) = [Char] -> ShowS
showString [Char]
"Rank7"
  showsPrec Int
_ (Rank Int
7) = [Char] -> ShowS
showString [Char]
"Rank8"
  showsPrec Int
d (Rank Int
n) = Bool -> ShowS -> ShowS
showParen (Int
d forall a. Ord a => a -> a -> Bool
> Int
10) forall a b. (a -> b) -> a -> b
$
                         [Char] -> ShowS
showString [Char]
"Rank " forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => Int -> a -> ShowS
showsPrec Int
11 Int
n

instance Enum Rank where
  toEnum :: Int -> Rank
toEnum Int
n | Int
n forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
n forall a. Ord a => a -> a -> Bool
<= Int
7 = Int -> Rank
Rank Int
n
           | Bool
otherwise        = forall a. HasCallStack => [Char] -> a
error forall a b. (a -> b) -> a -> b
$ [Char]
"Rank out-of-bound " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Int
n
  fromEnum :: Rank -> Int
fromEnum = coerce :: forall a b. Coercible a b => a -> b
coerce

instance Bounded Rank where
  minBound :: Rank
minBound = Rank
Rank1
  maxBound :: Rank
maxBound = Rank
Rank8

pattern Rank1, Rank2, Rank3, Rank4, Rank5, Rank6, Rank7, Rank8 :: Rank
pattern $bRank1 :: Rank
$mRank1 :: forall {r}. Rank -> ((# #) -> r) -> ((# #) -> r) -> r
Rank1 = Rank 0
pattern $bRank2 :: Rank
$mRank2 :: forall {r}. Rank -> ((# #) -> r) -> ((# #) -> r) -> r
Rank2 = Rank 1
pattern $bRank3 :: Rank
$mRank3 :: forall {r}. Rank -> ((# #) -> r) -> ((# #) -> r) -> r
Rank3 = Rank 2
pattern $bRank4 :: Rank
$mRank4 :: forall {r}. Rank -> ((# #) -> r) -> ((# #) -> r) -> r
Rank4 = Rank 3
pattern $bRank5 :: Rank
$mRank5 :: forall {r}. Rank -> ((# #) -> r) -> ((# #) -> r) -> r
Rank5 = Rank 4
pattern $bRank6 :: Rank
$mRank6 :: forall {r}. Rank -> ((# #) -> r) -> ((# #) -> r) -> r
Rank6 = Rank 5
pattern $bRank7 :: Rank
$mRank7 :: forall {r}. Rank -> ((# #) -> r) -> ((# #) -> r) -> r
Rank7 = Rank 6
pattern $bRank8 :: Rank
$mRank8 :: forall {r}. Rank -> ((# #) -> r) -> ((# #) -> r) -> r
Rank8 = Rank 7

{-# COMPLETE Rank1, Rank2, Rank3, Rank4, Rank5, Rank6, Rank7, Rank8 :: Rank #-}

newtype File = File Int deriving (File -> File -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: File -> File -> Bool
$c/= :: File -> File -> Bool
== :: File -> File -> Bool
$c== :: File -> File -> Bool
Eq, Eq File
File -> File -> Bool
File -> File -> Ordering
File -> File -> File
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 :: File -> File -> File
$cmin :: File -> File -> File
max :: File -> File -> File
$cmax :: File -> File -> File
>= :: File -> File -> Bool
$c>= :: File -> File -> Bool
> :: File -> File -> Bool
$c> :: File -> File -> Bool
<= :: File -> File -> Bool
$c<= :: File -> File -> Bool
< :: File -> File -> Bool
$c< :: File -> File -> Bool
compare :: File -> File -> Ordering
$ccompare :: File -> File -> Ordering
Ord)

unFile :: File -> Int
unFile :: File -> Int
unFile = coerce :: forall a b. Coercible a b => a -> b
coerce

mkFile :: HasCallStack => Int -> File
mkFile :: HasCallStack => Int -> File
mkFile Int
n | Int
n forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
n forall a. Ord a => a -> a -> Bool
<= Int
7 = Int -> File
File Int
n
         | Bool
otherwise        = forall a. HasCallStack => [Char] -> a
error forall a b. (a -> b) -> a -> b
$ [Char]
"mkFile " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Int
n

instance Show File where
  showsPrec :: Int -> File -> ShowS
showsPrec Int
_ (File Int
0) = [Char] -> ShowS
showString [Char]
"FileA"
  showsPrec Int
_ (File Int
1) = [Char] -> ShowS
showString [Char]
"FileB"
  showsPrec Int
_ (File Int
2) = [Char] -> ShowS
showString [Char]
"FileC"
  showsPrec Int
_ (File Int
3) = [Char] -> ShowS
showString [Char]
"FileD"
  showsPrec Int
_ (File Int
4) = [Char] -> ShowS
showString [Char]
"FileE"
  showsPrec Int
_ (File Int
5) = [Char] -> ShowS
showString [Char]
"FileF"
  showsPrec Int
_ (File Int
6) = [Char] -> ShowS
showString [Char]
"FileG"
  showsPrec Int
_ (File Int
7) = [Char] -> ShowS
showString [Char]
"FileH"
  showsPrec Int
d (File Int
n) = Bool -> ShowS -> ShowS
showParen (Int
d forall a. Ord a => a -> a -> Bool
> Int
10) forall a b. (a -> b) -> a -> b
$
                         [Char] -> ShowS
showString [Char]
"File " forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => Int -> a -> ShowS
showsPrec Int
11 Int
n

instance Enum File where
  toEnum :: Int -> File
toEnum Int
n | Int
n forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
n forall a. Ord a => a -> a -> Bool
<= Int
7 = Int -> File
File Int
n
           | Bool
otherwise        = forall a. HasCallStack => [Char] -> a
error forall a b. (a -> b) -> a -> b
$ [Char]
"File out-of-bound " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Int
n
  fromEnum :: File -> Int
fromEnum = coerce :: forall a b. Coercible a b => a -> b
coerce

instance Bounded File where
  minBound :: File
minBound = File
FileA
  maxBound :: File
maxBound = File
FileH

pattern FileA, FileB, FileC, FileD, FileE, FileF, FileG, FileH :: File
pattern $bFileA :: File
$mFileA :: forall {r}. File -> ((# #) -> r) -> ((# #) -> r) -> r
FileA = File 0
pattern $bFileB :: File
$mFileB :: forall {r}. File -> ((# #) -> r) -> ((# #) -> r) -> r
FileB = File 1
pattern $bFileC :: File
$mFileC :: forall {r}. File -> ((# #) -> r) -> ((# #) -> r) -> r
FileC = File 2
pattern $bFileD :: File
$mFileD :: forall {r}. File -> ((# #) -> r) -> ((# #) -> r) -> r
FileD = File 3
pattern $bFileE :: File
$mFileE :: forall {r}. File -> ((# #) -> r) -> ((# #) -> r) -> r
FileE = File 4
pattern $bFileF :: File
$mFileF :: forall {r}. File -> ((# #) -> r) -> ((# #) -> r) -> r
FileF = File 5
pattern $bFileG :: File
$mFileG :: forall {r}. File -> ((# #) -> r) -> ((# #) -> r) -> r
FileG = File 6
pattern $bFileH :: File
$mFileH :: forall {r}. File -> ((# #) -> r) -> ((# #) -> r) -> r
FileH = File 7

{-# COMPLETE FileA, FileB, FileC, FileD, FileE, FileF, FileG, FileH :: File #-}

newtype Square = Sq Int deriving (Square -> Square -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Square -> Square -> Bool
$c/= :: Square -> Square -> Bool
== :: Square -> Square -> Bool
$c== :: Square -> Square -> Bool
Eq, Eq Square
Square -> Square -> Bool
Square -> Square -> Ordering
Square -> Square -> Square
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 :: Square -> Square -> Square
$cmin :: Square -> Square -> Square
max :: Square -> Square -> Square
$cmax :: Square -> Square -> Square
>= :: Square -> Square -> Bool
$c>= :: Square -> Square -> Bool
> :: Square -> Square -> Bool
$c> :: Square -> Square -> Bool
<= :: Square -> Square -> Bool
$c<= :: Square -> Square -> Bool
< :: Square -> Square -> Bool
$c< :: Square -> Square -> Bool
compare :: Square -> Square -> Ordering
$ccompare :: Square -> Square -> Ordering
Ord)

instance Binary Square where
  put :: Square -> Put
put = Word8 -> Put
putWord8 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Integral a, Num b) => a -> b
fromIntegral forall b c a. (b -> c) -> (a -> b) -> a -> c
. Square -> Int
unSquare
  get :: Get Square
get = HasCallStack => Int -> Square
mkSq forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Integral a, Num b) => a -> b
fromIntegral forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word8
getWord8

instance Ix Square where
  range :: (Square, Square) -> [Square]
range (Sq Int
i, Sq Int
j) = [Int -> Square
Sq Int
k | Int
k <- [Int
i..Int
j]]
  index :: (Square, Square) -> Square -> Int
index (Sq Int
i, Sq Int
j) (Sq Int
k) = forall a. Ix a => (a, a) -> a -> Int
index (Int
i, Int
j) Int
k
  inRange :: (Square, Square) -> Square -> Bool
inRange (Sq Int
i, Sq Int
j) (Sq Int
k) = forall a. Ix a => (a, a) -> a -> Bool
inRange (Int
i, Int
j) Int
k
  rangeSize :: (Square, Square) -> Int
rangeSize (Sq Int
i, Sq Int
j) = Int
j forall a. Num a => a -> a -> a
- Int
i

unSquare :: Square -> Int
unSquare :: Square -> Int
unSquare = coerce :: forall a b. Coercible a b => a -> b
coerce
{-# INLINE unSquare #-}

-- TODO: this check is expensive, maybe only worth in "debug" builds.
mkSq :: HasCallStack => Int -> Square
mkSq :: HasCallStack => Int -> Square
mkSq Int
n | Int
n forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
n forall a. Ord a => a -> a -> Bool
<= Int
63 = Int -> Square
Sq Int
n
       | Bool
otherwise         = forall a. HasCallStack => [Char] -> a
error forall a b. (a -> b) -> a -> b
$ [Char]
"mkSq " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Int
n

instance Show Square where
  showsPrec :: Int -> Square -> ShowS
showsPrec Int
d (Sq Int
i) | Int
i forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
i forall a. Ord a => a -> a -> Bool
<= Int
63 = [Char] -> ShowS
showString [Char
f', Char
r']
                     | Bool
otherwise         = Bool -> ShowS -> ShowS
showParen (Int
d forall a. Ord a => a -> a -> Bool
> Int
10) forall a b. (a -> b) -> a -> b
$
                                           [Char] -> ShowS
showString [Char]
"Sq " forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => Int -> a -> ShowS
showsPrec Int
11 Int
i
      where
        (Int
r, Int
f) = Int
i forall a. Integral a => a -> a -> (a, a)
`divMod` Int
8
        r' :: Char
r' = Int -> Char
chr (Int
r forall a. Num a => a -> a -> a
+ Char -> Int
ord Char
'1')
        f' :: Char
f' = Int -> Char
chr (Int
f forall a. Num a => a -> a -> a
+ Char -> Int
ord Char
'A')

instance Enum Square where
  toEnum :: Int -> Square
toEnum Int
n | Int
n forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
n forall a. Ord a => a -> a -> Bool
<= Int
63 = Int -> Square
Sq Int
n
           | Bool
otherwise         = forall a. HasCallStack => [Char] -> a
error forall a b. (a -> b) -> a -> b
$ [Char]
"Sq out-of-bound " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Int
n
  fromEnum :: Square -> Int
fromEnum = coerce :: forall a b. Coercible a b => a -> b
coerce

instance Bounded Square where
  minBound :: Square
minBound = Square
A1
  maxBound :: Square
maxBound = Square
H8

pattern A1, A2, A3, A4, A5, A6, A7, A8 :: Square
pattern B1, B2, B3, B4, B5, B6, B7, B8 :: Square
pattern C1, C2, C3, C4, C5, C6, C7, C8 :: Square
pattern D1, D2, D3, D4, D5, D6, D7, D8 :: Square
pattern E1, E2, E3, E4, E5, E6, E7, E8 :: Square
pattern F1, F2, F3, F4, F5, F6, F7, F8 :: Square
pattern G1, G2, G3, G4, G5, G6, G7, G8 :: Square
pattern H1, H2, H3, H4, H5, H6, H7, H8 :: Square

pattern $bA1 :: Square
$mA1 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
A1 = Sq 0
pattern $bB1 :: Square
$mB1 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
B1 = Sq 1
pattern $bC1 :: Square
$mC1 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
C1 = Sq 2
pattern $bD1 :: Square
$mD1 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
D1 = Sq 3
pattern $bE1 :: Square
$mE1 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
E1 = Sq 4
pattern $bF1 :: Square
$mF1 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
F1 = Sq 5
pattern $bG1 :: Square
$mG1 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
G1 = Sq 6
pattern $bH1 :: Square
$mH1 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
H1 = Sq 7

pattern $bA2 :: Square
$mA2 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
A2 = Sq 8
pattern $bB2 :: Square
$mB2 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
B2 = Sq 9
pattern $bC2 :: Square
$mC2 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
C2 = Sq 10
pattern $bD2 :: Square
$mD2 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
D2 = Sq 11
pattern $bE2 :: Square
$mE2 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
E2 = Sq 12
pattern $bF2 :: Square
$mF2 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
F2 = Sq 13
pattern $bG2 :: Square
$mG2 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
G2 = Sq 14
pattern $bH2 :: Square
$mH2 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
H2 = Sq 15

pattern $bA3 :: Square
$mA3 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
A3 = Sq 16
pattern $bB3 :: Square
$mB3 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
B3 = Sq 17
pattern $bC3 :: Square
$mC3 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
C3 = Sq 18
pattern $bD3 :: Square
$mD3 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
D3 = Sq 19
pattern $bE3 :: Square
$mE3 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
E3 = Sq 20
pattern $bF3 :: Square
$mF3 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
F3 = Sq 21
pattern $bG3 :: Square
$mG3 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
G3 = Sq 22
pattern $bH3 :: Square
$mH3 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
H3 = Sq 23

pattern $bA4 :: Square
$mA4 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
A4 = Sq 24
pattern $bB4 :: Square
$mB4 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
B4 = Sq 25
pattern $bC4 :: Square
$mC4 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
C4 = Sq 26
pattern $bD4 :: Square
$mD4 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
D4 = Sq 27
pattern $bE4 :: Square
$mE4 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
E4 = Sq 28
pattern $bF4 :: Square
$mF4 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
F4 = Sq 29
pattern $bG4 :: Square
$mG4 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
G4 = Sq 30
pattern $bH4 :: Square
$mH4 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
H4 = Sq 31

pattern $bA5 :: Square
$mA5 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
A5 = Sq 32
pattern $bB5 :: Square
$mB5 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
B5 = Sq 33
pattern $bC5 :: Square
$mC5 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
C5 = Sq 34
pattern $bD5 :: Square
$mD5 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
D5 = Sq 35
pattern $bE5 :: Square
$mE5 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
E5 = Sq 36
pattern $bF5 :: Square
$mF5 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
F5 = Sq 37
pattern $bG5 :: Square
$mG5 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
G5 = Sq 38
pattern $bH5 :: Square
$mH5 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
H5 = Sq 39

pattern $bA6 :: Square
$mA6 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
A6 = Sq 40
pattern $bB6 :: Square
$mB6 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
B6 = Sq 41
pattern $bC6 :: Square
$mC6 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
C6 = Sq 42
pattern $bD6 :: Square
$mD6 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
D6 = Sq 43
pattern $bE6 :: Square
$mE6 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
E6 = Sq 44
pattern $bF6 :: Square
$mF6 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
F6 = Sq 45
pattern $bG6 :: Square
$mG6 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
G6 = Sq 46
pattern $bH6 :: Square
$mH6 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
H6 = Sq 47

pattern $bA7 :: Square
$mA7 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
A7 = Sq 48
pattern $bB7 :: Square
$mB7 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
B7 = Sq 49
pattern $bC7 :: Square
$mC7 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
C7 = Sq 50
pattern $bD7 :: Square
$mD7 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
D7 = Sq 51
pattern $bE7 :: Square
$mE7 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
E7 = Sq 52
pattern $bF7 :: Square
$mF7 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
F7 = Sq 53
pattern $bG7 :: Square
$mG7 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
G7 = Sq 54
pattern $bH7 :: Square
$mH7 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
H7 = Sq 55

pattern $bA8 :: Square
$mA8 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
A8 = Sq 56
pattern $bB8 :: Square
$mB8 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
B8 = Sq 57
pattern $bC8 :: Square
$mC8 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
C8 = Sq 58
pattern $bD8 :: Square
$mD8 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
D8 = Sq 59
pattern $bE8 :: Square
$mE8 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
E8 = Sq 60
pattern $bF8 :: Square
$mF8 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
F8 = Sq 61
pattern $bG8 :: Square
$mG8 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
G8 = Sq 62
pattern $bH8 :: Square
$mH8 :: forall {r}. Square -> ((# #) -> r) -> ((# #) -> r) -> r
H8 = Sq 63

rank :: Square -> Rank
rank :: Square -> Rank
rank = Int -> Rank
Rank forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a. Integral a => a -> a -> a
`div` Int
8) forall b c a. (b -> c) -> (a -> b) -> a -> c
. coerce :: forall a b. Coercible a b => a -> b
coerce

file :: Square -> File
file :: Square -> File
file = Int -> File
File forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a. Integral a => a -> a -> a
`mod` Int
8) forall b c a. (b -> c) -> (a -> b) -> a -> c
. coerce :: forall a b. Coercible a b => a -> b
coerce

rankFile :: Iso' Square (Rank, File)
rankFile :: Iso' Square (Rank, File)
rankFile = forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
iso Square -> (Rank, File)
rf (Rank, File) -> Square
sq where
  rf :: Square -> (Rank, File)
rf (Sq Int
i) = forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap Int -> Rank
Rank Int -> File
File forall a b. (a -> b) -> a -> b
$ Int
i forall a. Integral a => a -> a -> (a, a)
`divMod` Int
8
  sq :: (Rank, File) -> Square
sq (Rank Int
r, File Int
f) = Int -> Square
Sq forall a b. (a -> b) -> a -> b
$ Int
rforall a. Num a => a -> a -> a
*Int
8 forall a. Num a => a -> a -> a
+ Int
f

mapRank :: (Rank -> Rank) -> Square -> Square
mapRank :: (Rank -> Rank) -> Square -> Square
mapRank Rank -> Rank
f = forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view (forall s t a b. AnIso s t a b -> Iso b a t s
from Iso' Square (Rank, File)
rankFile) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first Rank -> Rank
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Iso' Square (Rank, File)
rankFile

mapFile :: (File -> File) -> Square -> Square
mapFile :: (File -> File) -> Square -> Square
mapFile File -> File
f = forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view (forall s t a b. AnIso s t a b -> Iso b a t s
from Iso' Square (Rank, File)
rankFile) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second File -> File
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Iso' Square (Rank, File)
rankFile

fileChar, rankChar :: Square -> Char
fileChar :: Square -> Char
fileChar = Int -> Char
chr forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Int
ord Char
'a' forall a. Num a => a -> a -> a
+) forall b c a. (b -> c) -> (a -> b) -> a -> c
. File -> Int
unFile forall b c a. (b -> c) -> (a -> b) -> a -> c
. Square -> File
file
rankChar :: Square -> Char
rankChar = Int -> Char
chr forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Int
ord Char
'1' forall a. Num a => a -> a -> a
+) forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rank -> Int
unRank forall b c a. (b -> c) -> (a -> b) -> a -> c
. Square -> Rank
rank

toCoord :: IsString s => Square -> s
toCoord :: forall s. IsString s => Square -> s
toCoord Square
sq = forall a. IsString a => [Char] -> a
fromString forall a b. (a -> b) -> a -> b
$ (forall a b. (a -> b) -> a -> b
$ Square
sq) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Square -> Char
fileChar, Square -> Char
rankChar]

isDark :: Square -> Bool
isDark :: Square -> Bool
isDark (Sq Int
i) = (Word64
0xaa55aa55aa55aa55 :: Word64) forall a. Bits a => a -> Int -> Bool
`testBit` Int
i

isLight :: Square -> Bool
isLight :: Square -> Bool
isLight = Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. Square -> Bool
isDark