{-# LANGUAGE CPP, FlexibleContexts #-}
module BishBosh.Cartesian.Coordinates(
Coordinates(
getX,
getY
),
ArrayByCoordinates,
tag,
topLeft,
bottomRight,
nSquares,
extrapolate,
interpolate,
getLogicalColourOfSquare,
kingsStartingCoordinates,
rooksStartingCoordinates,
measureDistance,
translate,
maybeTranslate,
translateX,
maybeTranslateX,
translateY,
maybeTranslateY,
getAdjacents,
advance,
retreat,
maybeRetreat,
mkCoordinates,
mkMaybeCoordinates,
fromIx,
mkRelativeCoordinates,
listArrayByCoordinates,
arrayByCoordinates,
isPawnsFirstRank,
isEnPassantRank,
areSquaresIsochromatic
) where
import Control.Arrow((&&&))
import Data.Array.IArray((!))
import qualified BishBosh.Attribute.Direction as Attribute.Direction
import qualified BishBosh.Attribute.LogicalColour as Attribute.LogicalColour
import qualified BishBosh.Attribute.LogicalColourOfSquare as Attribute.LogicalColourOfSquare
import qualified BishBosh.Cartesian.Abscissa as Cartesian.Abscissa
import qualified BishBosh.Cartesian.Ordinate as Cartesian.Ordinate
import qualified BishBosh.Data.Exception as Data.Exception
import qualified BishBosh.Property.FixedMembership as Property.FixedMembership
import qualified BishBosh.Property.Opposable as Property.Opposable
import qualified BishBosh.Property.Reflectable as Property.Reflectable
import qualified BishBosh.Property.Rotatable as Property.Rotatable
import qualified BishBosh.Text.ShowList as Text.ShowList
import qualified BishBosh.Type.Length as Type.Length
import qualified Control.DeepSeq
import qualified Control.Exception
import qualified Data.Array.IArray
import qualified Data.Array.Unboxed
import qualified Data.List
import qualified Data.Map
import qualified Data.Maybe
#ifdef USE_PARALLEL
import qualified Control.Parallel.Strategies
#endif
tag :: String
tag :: String
tag = String
"coordinates"
data Coordinates x y = MkCoordinates {
Coordinates x y -> x
getX :: x,
Coordinates x y -> y
getY :: y
} deriving Coordinates x y -> Coordinates x y -> Bool
(Coordinates x y -> Coordinates x y -> Bool)
-> (Coordinates x y -> Coordinates x y -> Bool)
-> Eq (Coordinates x y)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall x y.
(Eq x, Eq y) =>
Coordinates x y -> Coordinates x y -> Bool
/= :: Coordinates x y -> Coordinates x y -> Bool
$c/= :: forall x y.
(Eq x, Eq y) =>
Coordinates x y -> Coordinates x y -> Bool
== :: Coordinates x y -> Coordinates x y -> Bool
$c== :: forall x y.
(Eq x, Eq y) =>
Coordinates x y -> Coordinates x y -> Bool
Eq
instance (
Control.DeepSeq.NFData x,
Control.DeepSeq.NFData y
) => Control.DeepSeq.NFData (Coordinates x y) where
rnf :: Coordinates x y -> ()
rnf MkCoordinates { getX :: forall x y. Coordinates x y -> x
getX = x
x, getY :: forall x y. Coordinates x y -> y
getY = y
y } = (x, y) -> ()
forall a. NFData a => a -> ()
Control.DeepSeq.rnf (x
x, y
y)
instance (Show x, Show y) => Show (Coordinates x y) where
showsPrec :: Int -> Coordinates x y -> ShowS
showsPrec Int
precedence MkCoordinates { getX :: forall x y. Coordinates x y -> x
getX = x
x, getY :: forall x y. Coordinates x y -> y
getY = y
y } = Int -> (x, y) -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
precedence (x
x, y
y)
instance (
Enum x,
Enum y,
Ord x,
Ord y,
Read x,
Read y
) => Read (Coordinates x y) where
readsPrec :: Int -> ReadS (Coordinates x y)
readsPrec Int
precedence String
s = [
(Coordinates x y
coordinates, String
remainder) |
((x
x, y
y), String
remainder) <- Int -> ReadS (x, y)
forall a. Read a => Int -> ReadS a
readsPrec Int
precedence String
s,
Coordinates x y
coordinates <- Maybe (Coordinates x y) -> [Coordinates x y]
forall a. Maybe a -> [a]
Data.Maybe.maybeToList (Maybe (Coordinates x y) -> [Coordinates x y])
-> Maybe (Coordinates x y) -> [Coordinates x y]
forall a b. (a -> b) -> a -> b
$ x -> y -> Maybe (Coordinates x y)
forall x y.
(Enum x, Enum y, Ord x, Ord y) =>
x -> y -> Maybe (Coordinates x y)
mkMaybeCoordinates x
x y
y
]
instance (Ord x, Ord y) => Ord (Coordinates x y) where
{-# SPECIALISE instance Ord (Coordinates Type.Length.X Type.Length.Y) #-}
MkCoordinates { getX :: forall x y. Coordinates x y -> x
getX = x
x, getY :: forall x y. Coordinates x y -> y
getY = y
y } compare :: Coordinates x y -> Coordinates x y -> Ordering
`compare` MkCoordinates { getX :: forall x y. Coordinates x y -> x
getX = x
x', getY :: forall x y. Coordinates x y -> y
getY = y
y' } = (y
y, x
x) (y, x) -> (y, x) -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` (y
y', x
x')
instance (Enum x, Enum y) => Bounded (Coordinates x y) where
minBound :: Coordinates x y
minBound = MkCoordinates :: forall x y. x -> y -> Coordinates x y
MkCoordinates {
getX :: x
getX = x
forall x. Enum x => x
Cartesian.Abscissa.xMin,
getY :: y
getY = y
forall x. Enum x => x
Cartesian.Ordinate.yMin
}
maxBound :: Coordinates x y
maxBound = MkCoordinates :: forall x y. x -> y -> Coordinates x y
MkCoordinates {
getX :: x
getX = x
forall x. Enum x => x
Cartesian.Abscissa.xMax,
getY :: y
getY = y
forall x. Enum x => x
Cartesian.Ordinate.yMax
}
instance (
Enum x,
Enum y,
Ord x,
Ord y
) => Data.Array.IArray.Ix (Coordinates x y) where
{-# SPECIALISE instance Data.Array.IArray.Ix (Coordinates Type.Length.X Type.Length.Y) #-}
range :: (Coordinates x y, Coordinates x y) -> [Coordinates x y]
range (Coordinates x y
lower, Coordinates x y
upper) = Bool -> [Coordinates x y] -> [Coordinates x y]
forall a. (?callStack::CallStack) => Bool -> a -> a
Control.Exception.assert (Coordinates x y
lower Coordinates x y -> Coordinates x y -> Bool
forall a. Eq a => a -> a -> Bool
== Coordinates x y
forall a. Bounded a => a
minBound Bool -> Bool -> Bool
&& Coordinates x y
upper Coordinates x y -> Coordinates x y -> Bool
forall a. Eq a => a -> a -> Bool
== Coordinates x y
forall a. Bounded a => a
maxBound) [Coordinates x y]
forall a. FixedMembership a => [a]
Property.FixedMembership.members
inRange :: (Coordinates x y, Coordinates x y) -> Coordinates x y -> Bool
inRange (Coordinates x y
lower, Coordinates x y
upper) Coordinates x y
coordinates = Bool -> Bool -> Bool
forall a. (?callStack::CallStack) => Bool -> a -> a
Control.Exception.assert (Coordinates x y
coordinates Coordinates x y -> Coordinates x y -> Bool
forall a. Ord a => a -> a -> Bool
>= Coordinates x y
lower Bool -> Bool -> Bool
&& Coordinates x y
coordinates Coordinates x y -> Coordinates x y -> Bool
forall a. Ord a => a -> a -> Bool
<= Coordinates x y
upper) Bool
True
index :: (Coordinates x y, Coordinates x y) -> Coordinates x y -> Int
index (Coordinates x y
lower, Coordinates x y
upper) = Bool -> Int -> Int
forall a. (?callStack::CallStack) => Bool -> a -> a
Control.Exception.assert (Coordinates x y
lower Coordinates x y -> Coordinates x y -> Bool
forall a. Eq a => a -> a -> Bool
== Coordinates x y
forall a. Bounded a => a
minBound Bool -> Bool -> Bool
&& Coordinates x y
upper Coordinates x y -> Coordinates x y -> Bool
forall a. Eq a => a -> a -> Bool
== Coordinates x y
forall a. Bounded a => a
maxBound) (Int -> Int) -> (Coordinates x y -> Int) -> Coordinates x y -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Coordinates x y -> Int
forall x y. (Enum x, Enum y) => Coordinates x y -> Int
toIx
instance Enum y => Property.Reflectable.ReflectableOnX (Coordinates x y) where
reflectOnX :: Coordinates x y -> Coordinates x y
reflectOnX coordinates :: Coordinates x y
coordinates@MkCoordinates { getY :: forall x y. Coordinates x y -> y
getY = y
y } = Coordinates x y
coordinates { getY :: y
getY = y -> y
forall y. Enum y => y -> y
Cartesian.Ordinate.reflect y
y }
instance Enum x => Property.Reflectable.ReflectableOnY (Coordinates x y) where
reflectOnY :: Coordinates x y -> Coordinates x y
reflectOnY coordinates :: Coordinates x y
coordinates@MkCoordinates { getX :: forall x y. Coordinates x y -> x
getX = x
x } = Coordinates x y
coordinates { getX :: x
getX = x -> x
forall y. Enum y => y -> y
Cartesian.Abscissa.reflect x
x }
instance (Enum x, Enum y) => Property.Rotatable.Rotatable (Coordinates x y) where
rotate90 :: Coordinates x y -> Coordinates x y
rotate90 = Direction -> Coordinates x y -> Coordinates x y
forall x y. (Enum x, Enum y) => Direction -> Transformation x y
rotate Direction
Attribute.Direction.w
rotate180 :: Coordinates x y -> Coordinates x y
rotate180 = Direction -> Coordinates x y -> Coordinates x y
forall x y. (Enum x, Enum y) => Direction -> Transformation x y
rotate Direction
Attribute.Direction.s
rotate270 :: Coordinates x y -> Coordinates x y
rotate270 = Direction -> Coordinates x y -> Coordinates x y
forall x y. (Enum x, Enum y) => Direction -> Transformation x y
rotate Direction
Attribute.Direction.e
topLeft :: (Enum x, Enum y) => Coordinates x y
topLeft :: Coordinates x y
topLeft = MkCoordinates :: forall x y. x -> y -> Coordinates x y
MkCoordinates {
getX :: x
getX = x
forall x. Enum x => x
Cartesian.Abscissa.xMin,
getY :: y
getY = y
forall x. Enum x => x
Cartesian.Ordinate.yMax
}
bottomRight :: (Enum x, Enum y) => Coordinates x y
bottomRight :: Coordinates x y
bottomRight = MkCoordinates :: forall x y. x -> y -> Coordinates x y
MkCoordinates {
getX :: x
getX = x
forall x. Enum x => x
Cartesian.Abscissa.xMax,
getY :: y
getY = y
forall x. Enum x => x
Cartesian.Ordinate.yMin
}
nSquares :: Int
nSquares :: Int
nSquares = Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Int) -> Int -> Int
forall a b. (a -> b) -> a -> b
$ Int
Cartesian.Abscissa.xLength Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
Cartesian.Ordinate.yLength
instance (Enum x, Enum y) => Property.FixedMembership.FixedMembership (Coordinates x y) where
{-# SPECIALISE instance Property.FixedMembership.FixedMembership (Coordinates Type.Length.X Type.Length.Y) #-}
members :: [Coordinates x y]
members = [
MkCoordinates :: forall x y. x -> y -> Coordinates x y
MkCoordinates {
getX :: x
getX = x
x,
getY :: y
getY = y
y
} |
y
y <- [y]
forall y. Enum y => [y]
Cartesian.Ordinate.yRange,
x
x <- [x]
forall y. Enum y => [y]
Cartesian.Abscissa.xRange
]
inBounds :: (
Enum x,
Enum y,
Ord x,
Ord y
)
=> x
-> y
-> Bool
{-# INLINABLE inBounds #-}
inBounds :: x -> y -> Bool
inBounds x
x y
y = x -> Bool
forall x. (Enum x, Ord x) => x -> Bool
Cartesian.Abscissa.inBounds x
x Bool -> Bool -> Bool
&& y -> Bool
forall x. (Enum x, Ord x) => x -> Bool
Cartesian.Ordinate.inBounds y
y
mkCoordinates :: (
Enum x,
Enum y,
Ord x,
Ord y
)
=> x
-> y
-> Coordinates x y
mkCoordinates :: x -> y -> Coordinates x y
mkCoordinates x
x y
y = Bool -> Coordinates x y -> Coordinates x y
forall a. (?callStack::CallStack) => Bool -> a -> a
Control.Exception.assert (x -> y -> Bool
forall x y. (Enum x, Enum y, Ord x, Ord y) => x -> y -> Bool
inBounds x
x y
y) (Coordinates x y -> Coordinates x y)
-> Coordinates x y -> Coordinates x y
forall a b. (a -> b) -> a -> b
$ x -> y -> Coordinates x y
forall x y. x -> y -> Coordinates x y
MkCoordinates x
x y
y
mkMaybeCoordinates :: (
Enum x,
Enum y,
Ord x,
Ord y
)
=> x
-> y
-> Maybe (Coordinates x y)
mkMaybeCoordinates :: x -> y -> Maybe (Coordinates x y)
mkMaybeCoordinates x
x y
y
| x -> y -> Bool
forall x y. (Enum x, Enum y, Ord x, Ord y) => x -> y -> Bool
inBounds x
x y
y = Coordinates x y -> Maybe (Coordinates x y)
forall a. a -> Maybe a
Just MkCoordinates :: forall x y. x -> y -> Coordinates x y
MkCoordinates { getX :: x
getX = x
x, getY :: y
getY = y
y }
| Bool
otherwise = Maybe (Coordinates x y)
forall a. Maybe a
Nothing
toIx :: (Enum x, Enum y) => Coordinates x y -> Int
{-# SPECIALISE toIx :: Coordinates Type.Length.X Type.Length.Y -> Int #-}
toIx :: Coordinates x y -> Int
toIx MkCoordinates {
getX :: forall x y. Coordinates x y -> x
getX = x
x,
getY :: forall x y. Coordinates x y -> y
getY = y
y
} = Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
Cartesian.Abscissa.xLength Int -> Int -> Int
forall a. Num a => a -> a -> a
* y -> Int
forall y. Enum y => y -> Int
Cartesian.Ordinate.toIx y
y Int -> Int -> Int
forall a. Num a => a -> a -> a
+ x -> Int
forall y. Enum y => y -> Int
Cartesian.Abscissa.toIx x
x
fromIx :: (Enum x, Enum y) => Int -> Coordinates x y
fromIx :: Int -> Coordinates x y
fromIx = (
\(Int
y, Int
x) -> MkCoordinates :: forall x y. x -> y -> Coordinates x y
MkCoordinates {
getX :: x
getX = Int -> x
forall x. Enum x => Int -> x
Cartesian.Abscissa.fromIx Int
x,
getY :: y
getY = Int -> y
forall x. Enum x => Int -> x
Cartesian.Ordinate.fromIx Int
y
}
) ((Int, Int) -> Coordinates x y)
-> (Int -> (Int, Int)) -> Int -> Coordinates x y
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (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
Cartesian.Abscissa.xLength)
translate :: (
Enum x,
Enum y,
Ord x,
Ord y
) => ((x, y) -> (x, y)) -> Coordinates x y -> Coordinates x y
translate :: ((x, y) -> (x, y)) -> Coordinates x y -> Coordinates x y
translate (x, y) -> (x, y)
transformation MkCoordinates {
getX :: forall x y. Coordinates x y -> x
getX = x
x,
getY :: forall x y. Coordinates x y -> y
getY = y
y
} = (x -> y -> Coordinates x y) -> (x, y) -> Coordinates x y
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry x -> y -> Coordinates x y
forall x y.
(Enum x, Enum y, Ord x, Ord y) =>
x -> y -> Coordinates x y
mkCoordinates ((x, y) -> Coordinates x y) -> (x, y) -> Coordinates x y
forall a b. (a -> b) -> a -> b
$ (x, y) -> (x, y)
transformation (x
x, y
y)
maybeTranslate :: (
Enum x,
Enum y,
Ord x,
Ord y
)
=> ((x, y) -> (x, y))
-> Coordinates x y
-> Maybe (Coordinates x y)
{-# INLINABLE maybeTranslate #-}
maybeTranslate :: ((x, y) -> (x, y)) -> Coordinates x y -> Maybe (Coordinates x y)
maybeTranslate (x, y) -> (x, y)
transformation MkCoordinates {
getX :: forall x y. Coordinates x y -> x
getX = x
x,
getY :: forall x y. Coordinates x y -> y
getY = y
y
} = (x -> y -> Maybe (Coordinates x y))
-> (x, y) -> Maybe (Coordinates x y)
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry x -> y -> Maybe (Coordinates x y)
forall x y.
(Enum x, Enum y, Ord x, Ord y) =>
x -> y -> Maybe (Coordinates x y)
mkMaybeCoordinates ((x, y) -> Maybe (Coordinates x y))
-> (x, y) -> Maybe (Coordinates x y)
forall a b. (a -> b) -> a -> b
$ (x, y) -> (x, y)
transformation (x
x, y
y)
translateX :: (Enum x, Ord x) => (x -> x) -> Transformation x y
translateX :: (x -> x) -> Transformation x y
translateX x -> x
transformation coordinates :: Coordinates x y
coordinates@MkCoordinates { getX :: forall x y. Coordinates x y -> x
getX = x
x } = Coordinates x y
coordinates { getX :: x
getX = (x -> x) -> x -> x
forall x. (Enum x, Ord x) => (x -> x) -> x -> x
Cartesian.Abscissa.translate x -> x
transformation x
x }
maybeTranslateX
:: (Enum x, Ord x)
=> (x -> x)
-> Coordinates x y
-> Maybe (Coordinates x y)
maybeTranslateX :: (x -> x) -> Coordinates x y -> Maybe (Coordinates x y)
maybeTranslateX x -> x
transformation coordinates :: Coordinates x y
coordinates@MkCoordinates { getX :: forall x y. Coordinates x y -> x
getX = x
x } = (\x
x' -> Coordinates x y
coordinates { getX :: x
getX = x
x' }) (x -> Coordinates x y) -> Maybe x -> Maybe (Coordinates x y)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` (x -> x) -> x -> Maybe x
forall x. (Enum x, Ord x) => (x -> x) -> x -> Maybe x
Cartesian.Abscissa.maybeTranslate x -> x
transformation x
x
translateY :: (Enum y, Ord y) => (y -> y) -> Transformation x y
translateY :: (y -> y) -> Transformation x y
translateY y -> y
transformation coordinates :: Coordinates x y
coordinates@MkCoordinates { getY :: forall x y. Coordinates x y -> y
getY = y
y } = Coordinates x y
coordinates { getY :: y
getY = (y -> y) -> y -> y
forall x. (Enum x, Ord x) => (x -> x) -> x -> x
Cartesian.Ordinate.translate y -> y
transformation y
y }
maybeTranslateY
:: (Enum y, Ord y)
=> (y -> y)
-> Coordinates x y
-> Maybe (Coordinates x y)
maybeTranslateY :: (y -> y) -> Coordinates x y -> Maybe (Coordinates x y)
maybeTranslateY y -> y
transformation coordinates :: Coordinates x y
coordinates@MkCoordinates { getY :: forall x y. Coordinates x y -> y
getY = y
y } = (\y
y' -> Coordinates x y
coordinates { getY :: y
getY = y
y' }) (y -> Coordinates x y) -> Maybe y -> Maybe (Coordinates x y)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` (y -> y) -> y -> Maybe y
forall x. (Enum x, Ord x) => (x -> x) -> x -> Maybe x
Cartesian.Ordinate.maybeTranslate y -> y
transformation y
y
mkRelativeCoordinates :: (
Enum x,
Enum y,
Ord x,
Ord y
)
=> ((x, y) -> (x, y))
-> Coordinates x y
mkRelativeCoordinates :: ((x, y) -> (x, y)) -> Coordinates x y
mkRelativeCoordinates = (((x, y) -> (x, y)) -> Coordinates x y -> Coordinates x y
forall x y.
(Enum x, Enum y, Ord x, Ord y) =>
((x, y) -> (x, y)) -> Coordinates x y -> Coordinates x y
`translate` Coordinates x y
forall a. Bounded a => a
minBound)
advance
:: (Enum y, Ord y)
=> Attribute.LogicalColour.LogicalColour
-> Transformation x y
{-# INLINE advance #-}
advance :: LogicalColour -> Transformation x y
advance LogicalColour
logicalColour = (y -> y) -> Transformation x y
forall y x. (Enum y, Ord y) => (y -> y) -> Transformation x y
translateY ((y -> y) -> Transformation x y) -> (y -> y) -> Transformation x y
forall a b. (a -> b) -> a -> b
$ if LogicalColour -> Bool
Attribute.LogicalColour.isBlack LogicalColour
logicalColour
then y -> y
forall y. Enum y => y -> y
pred
else y -> y
forall y. Enum y => y -> y
succ
maybeAdvance
:: (Enum y, Ord y)
=> Attribute.LogicalColour.LogicalColour
-> Coordinates x y
-> Maybe (Coordinates x y)
maybeAdvance :: LogicalColour -> Coordinates x y -> Maybe (Coordinates x y)
maybeAdvance LogicalColour
logicalColour = (y -> y) -> Coordinates x y -> Maybe (Coordinates x y)
forall y x.
(Enum y, Ord y) =>
(y -> y) -> Coordinates x y -> Maybe (Coordinates x y)
maybeTranslateY ((y -> y) -> Coordinates x y -> Maybe (Coordinates x y))
-> (y -> y) -> Coordinates x y -> Maybe (Coordinates x y)
forall a b. (a -> b) -> a -> b
$ if LogicalColour -> Bool
Attribute.LogicalColour.isBlack LogicalColour
logicalColour
then y -> y
forall y. Enum y => y -> y
pred
else y -> y
forall y. Enum y => y -> y
succ
retreat
:: (Enum y, Ord y)
=> Attribute.LogicalColour.LogicalColour
-> Transformation x y
retreat :: LogicalColour -> Transformation x y
retreat = LogicalColour -> Transformation x y
forall y x. (Enum y, Ord y) => LogicalColour -> Transformation x y
advance (LogicalColour -> Transformation x y)
-> (LogicalColour -> LogicalColour)
-> LogicalColour
-> Transformation x y
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LogicalColour -> LogicalColour
forall a. Opposable a => a -> a
Property.Opposable.getOpposite
maybeRetreat
:: (Enum y, Ord y)
=> Attribute.LogicalColour.LogicalColour
-> Coordinates x y
-> Maybe (Coordinates x y)
maybeRetreat :: LogicalColour -> Coordinates x y -> Maybe (Coordinates x y)
maybeRetreat = LogicalColour -> Coordinates x y -> Maybe (Coordinates x y)
forall y x.
(Enum y, Ord y) =>
LogicalColour -> Coordinates x y -> Maybe (Coordinates x y)
maybeAdvance (LogicalColour -> Coordinates x y -> Maybe (Coordinates x y))
-> (LogicalColour -> LogicalColour)
-> LogicalColour
-> Coordinates x y
-> Maybe (Coordinates x y)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LogicalColour -> LogicalColour
forall a. Opposable a => a -> a
Property.Opposable.getOpposite
getAdjacents :: (Enum x, Eq x) => Coordinates x y -> [Coordinates x y]
getAdjacents :: Coordinates x y -> [Coordinates x y]
getAdjacents coordinates :: Coordinates x y
coordinates@MkCoordinates { getX :: forall x y. Coordinates x y -> x
getX = x
x } = (x -> Coordinates x y) -> [x] -> [Coordinates x y]
forall a b. (a -> b) -> [a] -> [b]
map (\x
x' -> Coordinates x y
coordinates { getX :: x
getX = x
x' }) ([x] -> [Coordinates x y]) -> [x] -> [Coordinates x y]
forall a b. (a -> b) -> a -> b
$ x -> [x]
forall x. (Enum x, Eq x) => x -> [x]
Cartesian.Abscissa.getAdjacents x
x
extrapolate'
:: (Enum x, Enum y)
=> Attribute.Direction.Direction
-> Coordinates x y
-> [Coordinates x y]
Direction
direction MkCoordinates {
getX :: forall x y. Coordinates x y -> x
getX = x
x,
getY :: forall x y. Coordinates x y -> y
getY = y
y
} = (x -> y -> Coordinates x y) -> [x] -> [y] -> [Coordinates x y]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith x -> y -> Coordinates x y
forall x y. x -> y -> Coordinates x y
MkCoordinates (
case Direction -> Ordering
Attribute.Direction.getXDirection Direction
direction of
Ordering
GT -> [x -> x
forall y. Enum y => y -> y
succ x
x .. x
forall x. Enum x => x
Cartesian.Abscissa.xMax]
Ordering
LT -> let startX :: x
startX = x -> x
forall y. Enum y => y -> y
pred x
x in x
startX x -> [x] -> [x]
`seq` [x
startX, x -> x
forall y. Enum y => y -> y
pred x
startX .. x
forall x. Enum x => x
Cartesian.Abscissa.xMin]
Ordering
EQ -> x -> [x]
forall a. a -> [a]
repeat x
x
) (
case Direction -> Ordering
Attribute.Direction.getYDirection Direction
direction of
Ordering
GT -> [y -> y
forall y. Enum y => y -> y
succ y
y .. y
forall x. Enum x => x
Cartesian.Ordinate.yMax]
Ordering
LT -> let startY :: y
startY = y -> y
forall y. Enum y => y -> y
pred y
y in y
startY y -> [y] -> [y]
`seq` [y
startY, y -> y
forall y. Enum y => y -> y
pred y
startY .. y
forall x. Enum x => x
Cartesian.Ordinate.yMin]
Ordering
EQ -> y -> [y]
forall a. a -> [a]
repeat y
y
)
extrapolate
:: (Enum x, Enum y)
=> Attribute.Direction.Direction
-> Coordinates x y
-> [Coordinates x y]
{-# NOINLINE extrapolate #-}
{-# RULES "extrapolate/Int" extrapolate = extrapolateInt #-}
= Direction -> Coordinates x y -> [Coordinates x y]
forall x y.
(Enum x, Enum y) =>
Direction -> Coordinates x y -> [Coordinates x y]
extrapolate'
extrapolateInt :: Attribute.Direction.Direction -> Coordinates Type.Length.X Type.Length.Y -> [Coordinates Type.Length.X Type.Length.Y]
Direction
direction Coordinates Int Int
coordinates = ArrayByCoordinates Int Int (ArrayByDirection [Coordinates Int Int])
forall x y.
(NFData x, NFData y, Enum x, Enum y, Ord x, Ord y) =>
ArrayByCoordinates x y (ArrayByDirection [Coordinates x y])
extrapolationsByDirectionByCoordinates ArrayByCoordinates Int Int (ArrayByDirection [Coordinates Int Int])
-> Coordinates Int Int -> ArrayByDirection [Coordinates Int Int]
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
! Coordinates Int Int
coordinates ArrayByDirection [Coordinates Int Int]
-> Direction -> [Coordinates Int Int]
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
! Direction
direction
extrapolationsByDirectionByCoordinates :: (
#ifdef USE_PARALLEL
Control.DeepSeq.NFData x,
Control.DeepSeq.NFData y,
#endif
Enum x,
Enum y,
Ord x,
Ord y
) => ArrayByCoordinates x y (Attribute.Direction.ArrayByDirection [Coordinates x y])
{-# SPECIALISE extrapolationsByDirectionByCoordinates :: ArrayByCoordinates Type.Length.X Type.Length.Y (Attribute.Direction.ArrayByDirection [Coordinates Type.Length.X Type.Length.Y]) #-}
= [ArrayByDirection [Coordinates x y]]
-> ArrayByCoordinates x y (ArrayByDirection [Coordinates x y])
forall (a :: * -> * -> *) e x y.
(IArray a e, Enum x, Enum y, Ord x, Ord y) =>
[e] -> a (Coordinates x y) e
listArrayByCoordinates
#ifdef USE_PARALLEL
([ArrayByDirection [Coordinates x y]]
-> ArrayByCoordinates x y (ArrayByDirection [Coordinates x y]))
-> ([ArrayByDirection [Coordinates x y]]
-> [ArrayByDirection [Coordinates x y]])
-> [ArrayByDirection [Coordinates x y]]
-> ArrayByCoordinates x y (ArrayByDirection [Coordinates x y])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Strategy [ArrayByDirection [Coordinates x y]]
-> [ArrayByDirection [Coordinates x y]]
-> [ArrayByDirection [Coordinates x y]]
forall a. Strategy a -> a -> a
Control.Parallel.Strategies.withStrategy (Strategy (ArrayByDirection [Coordinates x y])
-> Strategy [ArrayByDirection [Coordinates x y]]
forall a. Strategy a -> Strategy [a]
Control.Parallel.Strategies.parList Strategy (ArrayByDirection [Coordinates x y])
forall a. NFData a => Strategy a
Control.Parallel.Strategies.rdeepseq)
#endif
([ArrayByDirection [Coordinates x y]]
-> ArrayByCoordinates x y (ArrayByDirection [Coordinates x y]))
-> [ArrayByDirection [Coordinates x y]]
-> ArrayByCoordinates x y (ArrayByDirection [Coordinates x y])
forall a b. (a -> b) -> a -> b
$ (Coordinates x y -> ArrayByDirection [Coordinates x y])
-> [Coordinates x y] -> [ArrayByDirection [Coordinates x y]]
forall a b. (a -> b) -> [a] -> [b]
map (
\Coordinates x y
coordinates -> [[Coordinates x y]] -> ArrayByDirection [Coordinates x y]
forall (a :: * -> * -> *) e. IArray a e => [e] -> a Direction e
Attribute.Direction.listArrayByDirection ([[Coordinates x y]] -> ArrayByDirection [Coordinates x y])
-> [[Coordinates x y]] -> ArrayByDirection [Coordinates x y]
forall a b. (a -> b) -> a -> b
$ (Direction -> [Coordinates x y])
-> [Direction] -> [[Coordinates x y]]
forall a b. (a -> b) -> [a] -> [b]
map (Direction -> Coordinates x y -> [Coordinates x y]
forall x y.
(Enum x, Enum y) =>
Direction -> Coordinates x y -> [Coordinates x y]
`extrapolate'` Coordinates x y
coordinates) [Direction]
forall a. FixedMembership a => [a]
Property.FixedMembership.members
) [Coordinates x y]
forall a. FixedMembership a => [a]
Property.FixedMembership.members
interpolationsByDestinationBySource :: (
#ifdef USE_PARALLEL
Control.DeepSeq.NFData x,
Control.DeepSeq.NFData y,
#endif
Enum x,
Enum y,
Ord x,
Ord y
) => ArrayByCoordinates x y (Data.Map.Map (Coordinates x y) [Coordinates x y])
{-# SPECIALISE interpolationsByDestinationBySource :: ArrayByCoordinates Type.Length.X Type.Length.Y (Data.Map.Map (Coordinates Type.Length.X Type.Length.Y) [Coordinates Type.Length.X Type.Length.Y]) #-}
interpolationsByDestinationBySource :: ArrayByCoordinates x y (Map (Coordinates x y) [Coordinates x y])
interpolationsByDestinationBySource = (Array Direction [Coordinates x y]
-> Map (Coordinates x y) [Coordinates x y])
-> Array (Coordinates x y) (Array Direction [Coordinates x y])
-> ArrayByCoordinates x y (Map (Coordinates x y) [Coordinates x y])
forall (a :: * -> * -> *) e' e i.
(IArray a e', IArray a e, Ix i) =>
(e' -> e) -> a i e' -> a i e
Data.Array.IArray.amap (
[(Coordinates x y, [Coordinates x y])]
-> Map (Coordinates x y) [Coordinates x y]
forall k a. Ord k => [(k, a)] -> Map k a
Data.Map.fromList ([(Coordinates x y, [Coordinates x y])]
-> Map (Coordinates x y) [Coordinates x y])
-> (Array Direction [Coordinates x y]
-> [(Coordinates x y, [Coordinates x y])])
-> Array Direction [Coordinates x y]
-> Map (Coordinates x y) [Coordinates x y]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Coordinates x y] -> (Coordinates x y, [Coordinates x y]))
-> [[Coordinates x y]] -> [(Coordinates x y, [Coordinates x y])]
forall a b. (a -> b) -> [a] -> [b]
map (
[Coordinates x y] -> Coordinates x y
forall a. [a] -> a
last ([Coordinates x y] -> Coordinates x y)
-> ([Coordinates x y] -> [Coordinates x y])
-> [Coordinates x y]
-> (Coordinates x y, [Coordinates x y])
forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& [Coordinates x y] -> [Coordinates x y]
forall a. a -> a
id
) ([[Coordinates x y]] -> [(Coordinates x y, [Coordinates x y])])
-> (Array Direction [Coordinates x y] -> [[Coordinates x y]])
-> Array Direction [Coordinates x y]
-> [(Coordinates x y, [Coordinates x y])]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Coordinates x y] -> [[Coordinates x y]])
-> [[Coordinates x y]] -> [[Coordinates x y]]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (
[[Coordinates x y]] -> [[Coordinates x y]]
forall a. [a] -> [a]
tail ([[Coordinates x y]] -> [[Coordinates x y]])
-> ([Coordinates x y] -> [[Coordinates x y]])
-> [Coordinates x y]
-> [[Coordinates x y]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Coordinates x y] -> [[Coordinates x y]]
forall a. [a] -> [[a]]
Data.List.inits
) ([[Coordinates x y]] -> [[Coordinates x y]])
-> (Array Direction [Coordinates x y] -> [[Coordinates x y]])
-> Array Direction [Coordinates x y]
-> [[Coordinates x y]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Array Direction [Coordinates x y] -> [[Coordinates x y]]
forall (a :: * -> * -> *) e i. (IArray a e, Ix i) => a i e -> [e]
Data.Array.IArray.elems
) Array (Coordinates x y) (Array Direction [Coordinates x y])
forall x y.
(NFData x, NFData y, Enum x, Enum y, Ord x, Ord y) =>
ArrayByCoordinates x y (ArrayByDirection [Coordinates x y])
extrapolationsByDirectionByCoordinates
interpolate :: (
Enum x,
Enum y,
Ord x,
Ord y
)
=> Coordinates x y
-> Coordinates x y
-> [Coordinates x y]
{-# NOINLINE interpolate #-}
{-# RULES "interpolate/Int" interpolate = interpolateInt #-}
interpolate :: Coordinates x y -> Coordinates x y -> [Coordinates x y]
interpolate source :: Coordinates x y
source@MkCoordinates {
getX :: forall x y. Coordinates x y -> x
getX = x
x,
getY :: forall x y. Coordinates x y -> y
getY = y
y
} destination :: Coordinates x y
destination@MkCoordinates {
getX :: forall x y. Coordinates x y -> x
getX = x
x',
getY :: forall x y. Coordinates x y -> y
getY = y
y'
}
| Coordinates x y
source Coordinates x y -> Coordinates x y -> Bool
forall a. Eq a => a -> a -> Bool
== Coordinates x y
destination = []
| Bool
otherwise = Bool -> [Coordinates x y] -> [Coordinates x y]
forall a. (?callStack::CallStack) => Bool -> a -> a
Control.Exception.assert (
x
x x -> x -> Bool
forall a. Eq a => a -> a -> Bool
== x
x' Bool -> Bool -> Bool
|| y
y y -> y -> Bool
forall a. Eq a => a -> a -> Bool
== y
y' Bool -> Bool -> Bool
|| (
let
distanceX, distanceY :: Type.Length.Distance
(Int
distanceX, Int
distanceY) = Coordinates x y -> Coordinates x y -> (Int, Int)
forall x y distance.
(Enum x, Enum y, Num distance) =>
Coordinates x y -> Coordinates x y -> (distance, distance)
measureDistance Coordinates x y
source Coordinates x y
destination
in Int -> Int
forall a. Num a => a -> a
abs Int
distanceX Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int -> Int
forall a. Num a => a -> a
abs Int
distanceY
)
) ([Coordinates x y] -> [Coordinates x y])
-> [Coordinates x y] -> [Coordinates x y]
forall a b. (a -> b) -> a -> b
$ (x -> y -> Coordinates x y) -> [x] -> [y] -> [Coordinates x y]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith x -> y -> Coordinates x y
forall x y. x -> y -> Coordinates x y
MkCoordinates (x
x x -> x -> [x]
forall a. (Enum a, Ord a) => a -> a -> [a]
`spanInterval` x
x') (y
y y -> y -> [y]
forall a. (Enum a, Ord a) => a -> a -> [a]
`spanInterval` y
y')
where
spanInterval :: (Enum a, Ord a) => a -> a -> [a]
spanInterval :: a -> a -> [a]
spanInterval a
fromAfter a
to = case a
to a -> a -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` a
fromAfter of
Ordering
GT -> [a -> a
forall y. Enum y => y -> y
succ a
fromAfter .. a
to]
Ordering
LT -> let startFromAfter :: a
startFromAfter = a -> a
forall y. Enum y => y -> y
pred a
fromAfter in a
startFromAfter a -> [a] -> [a]
`seq` [a
startFromAfter, a -> a
forall y. Enum y => y -> y
pred a
startFromAfter .. a
to]
Ordering
EQ -> a -> [a]
forall a. a -> [a]
repeat a
fromAfter
interpolateInt :: Coordinates Type.Length.X Type.Length.Y -> Coordinates Type.Length.X Type.Length.Y -> [Coordinates Type.Length.X Type.Length.Y]
interpolateInt :: Coordinates Int Int -> Coordinates Int Int -> [Coordinates Int Int]
interpolateInt Coordinates Int Int
coordinatesSource Coordinates Int Int
coordinatesDestination = ArrayByCoordinates
Int Int (Map (Coordinates Int Int) [Coordinates Int Int])
forall x y.
(NFData x, NFData y, Enum x, Enum y, Ord x, Ord y) =>
ArrayByCoordinates x y (Map (Coordinates x y) [Coordinates x y])
interpolationsByDestinationBySource ArrayByCoordinates
Int Int (Map (Coordinates Int Int) [Coordinates Int Int])
-> Coordinates Int Int
-> Map (Coordinates Int Int) [Coordinates Int Int]
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
! Coordinates Int Int
coordinatesSource Map (Coordinates Int Int) [Coordinates Int Int]
-> Coordinates Int Int -> [Coordinates Int Int]
forall k a. Ord k => Map k a -> k -> a
Data.Map.! Coordinates Int Int
coordinatesDestination
type Transformation x y = Coordinates x y -> Coordinates x y
rotate :: (Enum x, Enum y) => Attribute.Direction.Direction -> Transformation x y
rotate :: Direction -> Transformation x y
rotate Direction
direction coordinates :: Coordinates x y
coordinates@MkCoordinates {
getX :: forall x y. Coordinates x y -> x
getX = x
x,
getY :: forall x y. Coordinates x y -> y
getY = y
y
} = case Direction -> Ordering
Attribute.Direction.getXDirection (Direction -> Ordering)
-> (Direction -> Ordering) -> Direction -> (Ordering, Ordering)
forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& Direction -> Ordering
Attribute.Direction.getYDirection (Direction -> (Ordering, Ordering))
-> Direction -> (Ordering, Ordering)
forall a b. (a -> b) -> a -> b
$ Direction
direction of
(Ordering
EQ, Ordering
GT) -> Coordinates x y
coordinates
(Ordering
LT, Ordering
EQ) -> MkCoordinates :: forall x y. x -> y -> Coordinates x y
MkCoordinates {
getX :: x
getX = Int -> x
forall x. Enum x => Int -> x
Cartesian.Abscissa.fromIx (Int -> x) -> Int -> x
forall a b. (a -> b) -> a -> b
$ Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
yDistance',
getY :: y
getY = Int -> y
forall x. Enum x => Int -> x
Cartesian.Ordinate.fromIx (Int -> y) -> Int -> y
forall a b. (a -> b) -> a -> b
$ Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
xDistance
}
(Ordering
EQ, Ordering
LT) -> MkCoordinates :: forall x y. x -> y -> Coordinates x y
MkCoordinates {
getX :: x
getX = Int -> x
forall x. Enum x => Int -> x
Cartesian.Abscissa.fromIx (Int -> x) -> Int -> x
forall a b. (a -> b) -> a -> b
$ Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
xDistance',
getY :: y
getY = Int -> y
forall x. Enum x => Int -> x
Cartesian.Ordinate.fromIx (Int -> y) -> Int -> y
forall a b. (a -> b) -> a -> b
$ Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
yDistance'
}
(Ordering
GT, Ordering
EQ) -> MkCoordinates :: forall x y. x -> y -> Coordinates x y
MkCoordinates {
getX :: x
getX = Int -> x
forall x. Enum x => Int -> x
Cartesian.Abscissa.fromIx (Int -> x) -> Int -> x
forall a b. (a -> b) -> a -> b
$ Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
yDistance,
getY :: y
getY = Int -> y
forall x. Enum x => Int -> x
Cartesian.Ordinate.fromIx (Int -> y) -> Int -> y
forall a b. (a -> b) -> a -> b
$ Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
xDistance'
}
(Ordering, Ordering)
_ -> Exception -> Coordinates x y
forall a e. Exception e => e -> a
Control.Exception.throw (Exception -> Coordinates x y)
-> (String -> Exception) -> String -> Coordinates x y
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Exception
Data.Exception.mkRequestFailure (String -> Exception) -> ShowS -> String -> Exception
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ShowS
showString String
"BishBosh.Cartesian.Coordinates.rotate:\tunable to rotate to direction" ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShowS
Text.ShowList.showsAssociation (String -> Coordinates x y) -> String -> Coordinates x y
forall a b. (a -> b) -> a -> b
$ Direction -> ShowS
forall a. Show a => a -> ShowS
shows Direction
direction String
"."
where
xDistance, xDistance', yDistance, yDistance' :: Type.Length.Distance
xDistance :: Int
xDistance = Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Int) -> Int -> Int
forall a b. (a -> b) -> a -> b
$ x -> Int
forall y. Enum y => y -> Int
Cartesian.Abscissa.toIx x
x
yDistance :: Int
yDistance = Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Int) -> Int -> Int
forall a b. (a -> b) -> a -> b
$ y -> Int
forall y. Enum y => y -> Int
Cartesian.Ordinate.toIx y
y
xDistance' :: Int
xDistance' = Int -> Int
forall y. Enum y => y -> y
pred Int
Cartesian.Abscissa.xLength Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
xDistance
yDistance' :: Int
yDistance' = Int -> Int
forall y. Enum y => y -> y
pred Int
Cartesian.Ordinate.yLength Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
yDistance
measureDistance :: (
Enum x,
Enum y,
Num distance
)
=> Coordinates x y
-> Coordinates x y
-> (distance, distance)
{-# INLINE measureDistance #-}
measureDistance :: Coordinates x y -> Coordinates x y -> (distance, distance)
measureDistance MkCoordinates {
getX :: forall x y. Coordinates x y -> x
getX = x
x,
getY :: forall x y. Coordinates x y -> y
getY = y
y
} MkCoordinates {
getX :: forall x y. Coordinates x y -> x
getX = x
x',
getY :: forall x y. Coordinates x y -> y
getY = y
y'
} = (Int -> distance
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> distance) -> Int -> distance
forall a b. (a -> b) -> a -> b
$ x -> Int
forall y. Enum y => y -> Int
fromEnum x
x' Int -> Int -> Int
forall a. Num a => a -> a -> a
- x -> Int
forall y. Enum y => y -> Int
fromEnum x
x, Int -> distance
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> distance) -> Int -> distance
forall a b. (a -> b) -> a -> b
$ y -> Int
forall y. Enum y => y -> Int
fromEnum y
y' Int -> Int -> Int
forall a. Num a => a -> a -> a
- y -> Int
forall y. Enum y => y -> Int
fromEnum y
y)
getLogicalColourOfSquare :: (Enum x, Enum y) => Coordinates x y -> Attribute.LogicalColourOfSquare.LogicalColourOfSquare
getLogicalColourOfSquare :: Coordinates x y -> LogicalColourOfSquare
getLogicalColourOfSquare Coordinates x y
coordinates
| Int -> Bool
forall a. Integral a => a -> Bool
even (Int -> Bool) -> Int -> Bool
forall a b. (a -> b) -> a -> b
$ (Int -> Int -> Int) -> (Int, Int) -> Int
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Int -> Int -> Int
forall a. Num a => a -> a -> a
(+) (Int, Int)
distance = LogicalColourOfSquare
Attribute.LogicalColourOfSquare.black
| Bool
otherwise = LogicalColourOfSquare
Attribute.LogicalColourOfSquare.white
where
distance :: (Type.Length.Distance, Type.Length.Distance)
distance :: (Int, Int)
distance = Coordinates x y -> Coordinates x y -> (Int, Int)
forall x y distance.
(Enum x, Enum y, Num distance) =>
Coordinates x y -> Coordinates x y -> (distance, distance)
measureDistance Coordinates x y
forall a. Bounded a => a
minBound Coordinates x y
coordinates
areSquaresIsochromatic :: (Enum x, Enum y) => [Coordinates x y] -> Bool
areSquaresIsochromatic :: [Coordinates x y] -> Bool
areSquaresIsochromatic = (Bool -> Bool -> Bool) -> (Bool, Bool) -> Bool
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Bool -> Bool -> Bool
(||) ((Bool, Bool) -> Bool)
-> ([Coordinates x y] -> (Bool, Bool)) -> [Coordinates x y] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((LogicalColourOfSquare -> Bool) -> [LogicalColourOfSquare] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (LogicalColourOfSquare -> LogicalColourOfSquare -> Bool
forall a. Eq a => a -> a -> Bool
== LogicalColourOfSquare
forall a. Bounded a => a
minBound) ([LogicalColourOfSquare] -> Bool)
-> ([LogicalColourOfSquare] -> Bool)
-> [LogicalColourOfSquare]
-> (Bool, Bool)
forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& (LogicalColourOfSquare -> Bool) -> [LogicalColourOfSquare] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (LogicalColourOfSquare -> LogicalColourOfSquare -> Bool
forall a. Eq a => a -> a -> Bool
== LogicalColourOfSquare
forall a. Bounded a => a
maxBound)) ([LogicalColourOfSquare] -> (Bool, Bool))
-> ([Coordinates x y] -> [LogicalColourOfSquare])
-> [Coordinates x y]
-> (Bool, Bool)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Coordinates x y -> LogicalColourOfSquare)
-> [Coordinates x y] -> [LogicalColourOfSquare]
forall a b. (a -> b) -> [a] -> [b]
map Coordinates x y -> LogicalColourOfSquare
forall x y.
(Enum x, Enum y) =>
Coordinates x y -> LogicalColourOfSquare
getLogicalColourOfSquare
kingsStartingCoordinates :: (Enum x, Enum y) => Attribute.LogicalColour.LogicalColour -> Coordinates x y
kingsStartingCoordinates :: LogicalColour -> Coordinates x y
kingsStartingCoordinates LogicalColour
logicalColour = MkCoordinates :: forall x y. x -> y -> Coordinates x y
MkCoordinates {
getX :: x
getX = Int -> x
forall x. Enum x => Int -> x
Cartesian.Abscissa.fromIx Int
4,
getY :: y
getY = LogicalColour -> y
forall y. Enum y => LogicalColour -> y
Cartesian.Ordinate.firstRank LogicalColour
logicalColour
}
rooksStartingCoordinates :: (Enum x, Enum y) => Attribute.LogicalColour.LogicalColour -> [Coordinates x y]
rooksStartingCoordinates :: LogicalColour -> [Coordinates x y]
rooksStartingCoordinates LogicalColour
Attribute.LogicalColour.Black = [Coordinates x y
forall x y. (Enum x, Enum y) => Coordinates x y
topLeft, Coordinates x y
forall a. Bounded a => a
maxBound]
rooksStartingCoordinates LogicalColour
_ = [Coordinates x y
forall a. Bounded a => a
minBound, Coordinates x y
forall x y. (Enum x, Enum y) => Coordinates x y
bottomRight]
isPawnsFirstRank
:: (Enum y, Eq y)
=> Attribute.LogicalColour.LogicalColour
-> Coordinates x y
-> Bool
{-# INLINE isPawnsFirstRank #-}
isPawnsFirstRank :: LogicalColour -> Coordinates x y -> Bool
isPawnsFirstRank LogicalColour
logicalColour MkCoordinates { getY :: forall x y. Coordinates x y -> y
getY = y
y } = y
y y -> y -> Bool
forall a. Eq a => a -> a -> Bool
== LogicalColour -> y
forall y. Enum y => LogicalColour -> y
Cartesian.Ordinate.pawnsFirstRank LogicalColour
logicalColour
isEnPassantRank
:: (Enum y, Eq y)
=> Attribute.LogicalColour.LogicalColour
-> Coordinates x y
-> Bool
isEnPassantRank :: LogicalColour -> Coordinates x y -> Bool
isEnPassantRank LogicalColour
logicalColour MkCoordinates { getY :: forall x y. Coordinates x y -> y
getY = y
y } = y
y y -> y -> Bool
forall a. Eq a => a -> a -> Bool
== LogicalColour -> y
forall y. Enum y => LogicalColour -> y
Cartesian.Ordinate.enPassantRank LogicalColour
logicalColour
type ArrayByCoordinates x y = Data.Array.IArray.Array (Coordinates x y)
type UArrayByCoordinates x y = Data.Array.Unboxed.UArray (Coordinates x y)
listArrayByCoordinates :: (
Data.Array.IArray.IArray a e,
Enum x,
Enum y,
Ord x,
Ord y
) => [e] -> a (Coordinates x y) e
listArrayByCoordinates :: [e] -> a (Coordinates x y) e
listArrayByCoordinates = (Coordinates x y, Coordinates x y) -> [e] -> a (Coordinates x y) e
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
(i, i) -> [e] -> a i e
Data.Array.IArray.listArray (Coordinates x y
forall a. Bounded a => a
minBound, Coordinates x y
forall a. Bounded a => a
maxBound)
arrayByCoordinates :: (
Data.Array.IArray.IArray a e,
Enum x,
Enum y,
Ord x,
Ord y
) => [(Coordinates x y, e)] -> a (Coordinates x y) e
arrayByCoordinates :: [(Coordinates x y, e)] -> a (Coordinates x y) e
arrayByCoordinates = (Coordinates x y, Coordinates x y)
-> [(Coordinates x y, e)] -> a (Coordinates x y) e
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
(i, i) -> [(i, e)] -> a i e
Data.Array.IArray.array (Coordinates x y
forall a. Bounded a => a
minBound, Coordinates x y
forall a. Bounded a => a
maxBound)