{-# LANGUAGE CPP #-}
module BishBosh.Component.PieceSquareByCoordinatesByRank(
PieceSquareByCoordinatesByRank(
),
nPiecesBounds,
gnuPlotComment,
findPieceSquareValue,
interpolatePieceSquareValues,
formatForGNUPlot,
mkPieceSquareByCoordinatesByRank
) where
import Control.Arrow((&&&), (|||))
import Data.Array.IArray((!))
import qualified BishBosh.Attribute.Rank as Attribute.Rank
import qualified BishBosh.Cartesian.Abscissa as Cartesian.Abscissa
import qualified BishBosh.Cartesian.Coordinates as Cartesian.Coordinates
import qualified BishBosh.Colour.LogicalColour as Colour.LogicalColour
import qualified BishBosh.Component.Piece as Component.Piece
import qualified BishBosh.Property.FixedMembership as Property.FixedMembership
import qualified BishBosh.Property.Reflectable as Property.Reflectable
import qualified BishBosh.Text.ShowList as Text.ShowList
import qualified BishBosh.Type.Count as Type.Count
import qualified BishBosh.Type.Mass as Type.Mass
import qualified Control.DeepSeq
import qualified Data.Array.IArray
import qualified Data.Foldable
import qualified Data.List
#if defined(USE_UNBOXED_ARRAYS) && !(defined(USE_NEWTYPE_WRAPPERS) || defined(USE_PRECISION))
#define UNBOX
import qualified Data.Array.Unboxed
#endif
type PieceSquareValueByNPieces =
#ifdef UNBOX
Data.Array.Unboxed.UArray
#else
Data.Array.IArray.Array
#endif
Type.Count.NPieces Type.Mass.PieceSquareValue
nPiecesBounds :: (Type.Count.NPieces, Type.Count.NPieces)
nPiecesBounds :: (NPieces, NPieces)
nPiecesBounds = (
NPieces
3 ,
NPieces -> NPieces
forall a b. (Integral a, Num b) => a -> b
fromIntegral NPieces
Colour.LogicalColour.nDistinctLogicalColours NPieces -> NPieces -> NPieces
forall a. Num a => a -> a -> a
* NPieces
Component.Piece.nPiecesPerSide
)
type EitherPieceSquareValueByNPiecesByCoordinates = Either (
#ifdef UNBOX
Cartesian.Coordinates.UArrayByCoordinates
#else
Cartesian.Coordinates.ArrayByCoordinates
#endif
Type.Mass.PieceSquareValue
) (
Cartesian.Coordinates.ArrayByCoordinates PieceSquareValueByNPieces
)
newtype PieceSquareByCoordinatesByRank = MkPieceSquareByCoordinatesByRank {
PieceSquareByCoordinatesByRank
-> ArrayByRank EitherPieceSquareValueByNPiecesByCoordinates
deconstruct :: Attribute.Rank.ArrayByRank EitherPieceSquareValueByNPiecesByCoordinates
} deriving (PieceSquareByCoordinatesByRank
-> PieceSquareByCoordinatesByRank -> Bool
(PieceSquareByCoordinatesByRank
-> PieceSquareByCoordinatesByRank -> Bool)
-> (PieceSquareByCoordinatesByRank
-> PieceSquareByCoordinatesByRank -> Bool)
-> Eq PieceSquareByCoordinatesByRank
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PieceSquareByCoordinatesByRank
-> PieceSquareByCoordinatesByRank -> Bool
$c/= :: PieceSquareByCoordinatesByRank
-> PieceSquareByCoordinatesByRank -> Bool
== :: PieceSquareByCoordinatesByRank
-> PieceSquareByCoordinatesByRank -> Bool
$c== :: PieceSquareByCoordinatesByRank
-> PieceSquareByCoordinatesByRank -> Bool
Eq, NPieces -> PieceSquareByCoordinatesByRank -> ShowS
[PieceSquareByCoordinatesByRank] -> ShowS
PieceSquareByCoordinatesByRank -> String
(NPieces -> PieceSquareByCoordinatesByRank -> ShowS)
-> (PieceSquareByCoordinatesByRank -> String)
-> ([PieceSquareByCoordinatesByRank] -> ShowS)
-> Show PieceSquareByCoordinatesByRank
forall a.
(NPieces -> a -> ShowS)
-> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PieceSquareByCoordinatesByRank] -> ShowS
$cshowList :: [PieceSquareByCoordinatesByRank] -> ShowS
show :: PieceSquareByCoordinatesByRank -> String
$cshow :: PieceSquareByCoordinatesByRank -> String
showsPrec :: NPieces -> PieceSquareByCoordinatesByRank -> ShowS
$cshowsPrec :: NPieces -> PieceSquareByCoordinatesByRank -> ShowS
Show)
instance Control.DeepSeq.NFData PieceSquareByCoordinatesByRank where
rnf :: PieceSquareByCoordinatesByRank -> ()
rnf
#ifdef UNBOX
_ = ()
#else
MkPieceSquareByCoordinatesByRank { deconstruct :: PieceSquareByCoordinatesByRank
-> ArrayByRank EitherPieceSquareValueByNPiecesByCoordinates
deconstruct = ArrayByRank EitherPieceSquareValueByNPiecesByCoordinates
byRank } = ArrayByRank EitherPieceSquareValueByNPiecesByCoordinates -> ()
forall a. NFData a => a -> ()
Control.DeepSeq.rnf ArrayByRank EitherPieceSquareValueByNPiecesByCoordinates
byRank
#endif
mkPieceSquareByCoordinatesByRank
:: (Attribute.Rank.Rank -> EitherPieceSquareValueByNPiecesByCoordinates)
-> PieceSquareByCoordinatesByRank
mkPieceSquareByCoordinatesByRank :: (Rank -> EitherPieceSquareValueByNPiecesByCoordinates)
-> PieceSquareByCoordinatesByRank
mkPieceSquareByCoordinatesByRank = ArrayByRank EitherPieceSquareValueByNPiecesByCoordinates
-> PieceSquareByCoordinatesByRank
MkPieceSquareByCoordinatesByRank (ArrayByRank EitherPieceSquareValueByNPiecesByCoordinates
-> PieceSquareByCoordinatesByRank)
-> ((Rank -> EitherPieceSquareValueByNPiecesByCoordinates)
-> ArrayByRank EitherPieceSquareValueByNPiecesByCoordinates)
-> (Rank -> EitherPieceSquareValueByNPiecesByCoordinates)
-> PieceSquareByCoordinatesByRank
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [EitherPieceSquareValueByNPiecesByCoordinates]
-> ArrayByRank EitherPieceSquareValueByNPiecesByCoordinates
forall (a :: * -> * -> *) e. IArray a e => [e] -> a Rank e
Attribute.Rank.listArrayByRank ([EitherPieceSquareValueByNPiecesByCoordinates]
-> ArrayByRank EitherPieceSquareValueByNPiecesByCoordinates)
-> ((Rank -> EitherPieceSquareValueByNPiecesByCoordinates)
-> [EitherPieceSquareValueByNPiecesByCoordinates])
-> (Rank -> EitherPieceSquareValueByNPiecesByCoordinates)
-> ArrayByRank EitherPieceSquareValueByNPiecesByCoordinates
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Rank -> EitherPieceSquareValueByNPiecesByCoordinates)
-> [Rank] -> [EitherPieceSquareValueByNPiecesByCoordinates]
forall a b. (a -> b) -> [a] -> [b]
`map` [Rank]
forall a. FixedMembership a => [a]
Property.FixedMembership.members)
findPieceSquareValue
:: PieceSquareByCoordinatesByRank
-> Type.Count.NPieces
-> Colour.LogicalColour.LogicalColour
-> Attribute.Rank.Rank
-> Cartesian.Coordinates.Coordinates
-> Type.Mass.PieceSquareValue
findPieceSquareValue :: PieceSquareByCoordinatesByRank
-> NPieces
-> LogicalColour
-> Rank
-> Coordinates
-> PieceSquareValue
findPieceSquareValue MkPieceSquareByCoordinatesByRank { deconstruct :: PieceSquareByCoordinatesByRank
-> ArrayByRank EitherPieceSquareValueByNPiecesByCoordinates
deconstruct = ArrayByRank EitherPieceSquareValueByNPiecesByCoordinates
byRank } NPieces
nPieces LogicalColour
logicalColour Rank
rank = (
(!) (Array Coordinates PieceSquareValue
-> Coordinates -> PieceSquareValue)
-> (Array Coordinates (Array NPieces PieceSquareValue)
-> Coordinates -> PieceSquareValue)
-> EitherPieceSquareValueByNPiecesByCoordinates
-> Coordinates
-> PieceSquareValue
forall (a :: * -> * -> *) b d c.
ArrowChoice a =>
a b d -> a c d -> a (Either b c) d
||| (
\Array Coordinates (Array NPieces PieceSquareValue)
byNPiecesByCoordinates -> (Array NPieces PieceSquareValue -> NPieces -> PieceSquareValue
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
! NPieces
nPieces) (Array NPieces PieceSquareValue -> PieceSquareValue)
-> (Coordinates -> Array NPieces PieceSquareValue)
-> Coordinates
-> PieceSquareValue
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Array Coordinates (Array NPieces PieceSquareValue)
byNPiecesByCoordinates Array Coordinates (Array NPieces PieceSquareValue)
-> Coordinates -> Array NPieces PieceSquareValue
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
!)
) (EitherPieceSquareValueByNPiecesByCoordinates
-> Coordinates -> PieceSquareValue)
-> EitherPieceSquareValueByNPiecesByCoordinates
-> Coordinates
-> PieceSquareValue
forall a b. (a -> b) -> a -> b
$ ArrayByRank EitherPieceSquareValueByNPiecesByCoordinates
byRank ArrayByRank EitherPieceSquareValueByNPiecesByCoordinates
-> Rank -> EitherPieceSquareValueByNPiecesByCoordinates
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
! Rank
rank
) (Coordinates -> PieceSquareValue)
-> (Coordinates -> Coordinates) -> Coordinates -> PieceSquareValue
forall b c a. (b -> c) -> (a -> b) -> a -> c
. if LogicalColour -> Bool
Colour.LogicalColour.isBlack LogicalColour
logicalColour
then Coordinates -> Coordinates
forall a. ReflectableOnX a => a -> a
Property.Reflectable.reflectOnX
else Coordinates -> Coordinates
forall a. a -> a
id
interpolatePieceSquareValues
:: Type.Mass.PieceSquareValue
-> Type.Mass.PieceSquareValue
-> PieceSquareValueByNPieces
interpolatePieceSquareValues :: PieceSquareValue
-> PieceSquareValue -> Array NPieces PieceSquareValue
interpolatePieceSquareValues PieceSquareValue
openingGame PieceSquareValue
endGame = (NPieces, NPieces)
-> [PieceSquareValue] -> Array NPieces PieceSquareValue
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
(i, i) -> [e] -> a i e
Data.Array.IArray.listArray (NPieces, NPieces)
nPiecesBounds ([PieceSquareValue] -> Array NPieces PieceSquareValue)
-> ([NPieces] -> [PieceSquareValue])
-> [NPieces]
-> Array NPieces PieceSquareValue
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (NPieces -> PieceSquareValue) -> [NPieces] -> [PieceSquareValue]
forall a b. (a -> b) -> [a] -> [b]
map (
Rational -> PieceSquareValue
forall a. Fractional a => Rational -> a
fromRational (Rational -> PieceSquareValue)
-> (NPieces -> Rational) -> NPieces -> PieceSquareValue
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Rational -> Rational -> Rational)
-> (Rational, Rational) -> Rational
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
(+) ((Rational, Rational) -> Rational)
-> (NPieces -> (Rational, Rational)) -> NPieces -> Rational
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (
(Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* PieceSquareValue -> Rational
forall a. Real a => a -> Rational
toRational PieceSquareValue
openingGame) (Rational -> Rational)
-> (Rational -> Rational) -> Rational -> (Rational, Rational)
forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& (Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* PieceSquareValue -> Rational
forall a. Real a => a -> Rational
toRational PieceSquareValue
endGame) (Rational -> Rational)
-> (Rational -> Rational) -> Rational -> Rational
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Rational
1 Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
-)
) (Rational -> (Rational, Rational))
-> (NPieces -> Rational) -> NPieces -> (Rational, Rational)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (
Rational -> Rational -> Rational
forall a. Fractional a => a -> a -> a
/ NPieces -> Rational
forall a b. (Integral a, Num b) => a -> b
fromIntegral (
(NPieces -> NPieces -> NPieces) -> (NPieces, NPieces) -> NPieces
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry NPieces -> NPieces -> NPieces
forall a. Num a => a -> a -> a
subtract (NPieces, NPieces)
nPiecesBounds
)
) (Rational -> Rational)
-> (NPieces -> Rational) -> NPieces -> Rational
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NPieces -> Rational
forall a b. (Integral a, Num b) => a -> b
fromIntegral (NPieces -> Rational)
-> (NPieces -> NPieces) -> NPieces -> Rational
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NPieces -> NPieces -> NPieces
forall a. Num a => a -> a -> a
subtract (
(NPieces, NPieces) -> NPieces
forall a b. (a, b) -> a
fst (NPieces, NPieces)
nPiecesBounds
)
) ([NPieces] -> Array NPieces PieceSquareValue)
-> [NPieces] -> Array NPieces PieceSquareValue
forall a b. (a -> b) -> a -> b
$ (NPieces -> NPieces -> [NPieces])
-> (NPieces, NPieces) -> [NPieces]
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry NPieces -> NPieces -> [NPieces]
forall a. Enum a => a -> a -> [a]
enumFromTo (NPieces, NPieces)
nPiecesBounds
gnuPlotComment :: Char
= Char
'#'
formatForGNUPlot
:: PieceSquareByCoordinatesByRank
-> (Type.Mass.PieceSquareValue -> ShowS)
-> ShowS
-> (PieceSquareValueByNPieces -> Type.Mass.PieceSquareValue)
-> ShowS
formatForGNUPlot :: PieceSquareByCoordinatesByRank
-> (PieceSquareValue -> ShowS)
-> ShowS
-> (Array NPieces PieceSquareValue -> PieceSquareValue)
-> ShowS
formatForGNUPlot MkPieceSquareByCoordinatesByRank { deconstruct :: PieceSquareByCoordinatesByRank
-> ArrayByRank EitherPieceSquareValueByNPiecesByCoordinates
deconstruct = ArrayByRank EitherPieceSquareValueByNPiecesByCoordinates
byRank } PieceSquareValue -> ShowS
pieceSquareValueFormatter ShowS
columnDelimiter Array NPieces PieceSquareValue -> PieceSquareValue
selector = (
[ShowS] -> ShowS
showsRow (
Char -> ShowS
showChar Char
gnuPlotComment ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> ShowS
showChar Char
'x' ShowS -> [ShowS] -> [ShowS]
forall a. a -> [a] -> [a]
: Char -> ShowS
showChar Char
'y' ShowS -> [ShowS] -> [ShowS]
forall a. a -> [a] -> [a]
: (Rank -> ShowS) -> [Rank] -> [ShowS]
forall a b. (a -> b) -> [a] -> [b]
map Rank -> ShowS
forall a. Show a => a -> ShowS
shows [Rank]
Attribute.Rank.range
) ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
) (ShowS -> ShowS)
-> ([EitherPieceSquareValueByNPiecesByCoordinates] -> ShowS)
-> [EitherPieceSquareValueByNPiecesByCoordinates]
-> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Coordinates, [PieceSquareValue]) -> ShowS -> ShowS)
-> ShowS -> [(Coordinates, [PieceSquareValue])] -> ShowS
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (
\(Coordinates
coordinates, [PieceSquareValue]
byRank') ShowS
showS -> let
(NPieces
x, NPieces
y) = Coordinates -> NPieces
Cartesian.Coordinates.getX (Coordinates -> NPieces)
-> (Coordinates -> NPieces) -> Coordinates -> (NPieces, NPieces)
forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& Coordinates -> NPieces
Cartesian.Coordinates.getY (Coordinates -> (NPieces, NPieces))
-> Coordinates -> (NPieces, NPieces)
forall a b. (a -> b) -> a -> b
$ Coordinates
coordinates
in [ShowS] -> ShowS
showsRow (
NPieces -> ShowS
forall a. Show a => a -> ShowS
shows NPieces
x ShowS -> [ShowS] -> [ShowS]
forall a. a -> [a] -> [a]
: NPieces -> ShowS
forall a. Show a => a -> ShowS
shows NPieces
y ShowS -> [ShowS] -> [ShowS]
forall a. a -> [a] -> [a]
: (PieceSquareValue -> ShowS) -> [PieceSquareValue] -> [ShowS]
forall a b. (a -> b) -> [a] -> [b]
map PieceSquareValue -> ShowS
pieceSquareValueFormatter [PieceSquareValue]
byRank'
) ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (
if NPieces
x NPieces -> NPieces -> Bool
forall a. Eq a => a -> a -> Bool
== NPieces
Cartesian.Abscissa.xMax
then ShowS
terminateRow
else ShowS
forall a. a -> a
id
) ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShowS
showS
) ShowS
forall a. a -> a
id ([(Coordinates, [PieceSquareValue])] -> ShowS)
-> ([EitherPieceSquareValueByNPiecesByCoordinates]
-> [(Coordinates, [PieceSquareValue])])
-> [EitherPieceSquareValueByNPiecesByCoordinates]
-> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Coordinates]
-> [[PieceSquareValue]] -> [(Coordinates, [PieceSquareValue])]
forall a b. [a] -> [b] -> [(a, b)]
zip (
[Coordinates]
forall a. FixedMembership a => [a]
Property.FixedMembership.members :: [Cartesian.Coordinates.Coordinates]
) ([[PieceSquareValue]] -> [(Coordinates, [PieceSquareValue])])
-> ([EitherPieceSquareValueByNPiecesByCoordinates]
-> [[PieceSquareValue]])
-> [EitherPieceSquareValueByNPiecesByCoordinates]
-> [(Coordinates, [PieceSquareValue])]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[PieceSquareValue]] -> [[PieceSquareValue]]
forall a. [[a]] -> [[a]]
Data.List.transpose ([[PieceSquareValue]] -> [[PieceSquareValue]])
-> ([EitherPieceSquareValueByNPiecesByCoordinates]
-> [[PieceSquareValue]])
-> [EitherPieceSquareValueByNPiecesByCoordinates]
-> [[PieceSquareValue]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (EitherPieceSquareValueByNPiecesByCoordinates
-> [PieceSquareValue])
-> [EitherPieceSquareValueByNPiecesByCoordinates]
-> [[PieceSquareValue]]
forall a b. (a -> b) -> [a] -> [b]
map (
Array Coordinates PieceSquareValue -> [PieceSquareValue]
forall (a :: * -> * -> *) e i. (IArray a e, Ix i) => a i e -> [e]
Data.Array.IArray.elems (Array Coordinates PieceSquareValue -> [PieceSquareValue])
-> (Array Coordinates (Array NPieces PieceSquareValue)
-> [PieceSquareValue])
-> EitherPieceSquareValueByNPiecesByCoordinates
-> [PieceSquareValue]
forall (a :: * -> * -> *) b d c.
ArrowChoice a =>
a b d -> a c d -> a (Either b c) d
||| (Array NPieces PieceSquareValue -> PieceSquareValue)
-> [Array NPieces PieceSquareValue] -> [PieceSquareValue]
forall a b. (a -> b) -> [a] -> [b]
map Array NPieces PieceSquareValue -> PieceSquareValue
selector ([Array NPieces PieceSquareValue] -> [PieceSquareValue])
-> (Array Coordinates (Array NPieces PieceSquareValue)
-> [Array NPieces PieceSquareValue])
-> Array Coordinates (Array NPieces PieceSquareValue)
-> [PieceSquareValue]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Array Coordinates (Array NPieces PieceSquareValue)
-> [Array NPieces PieceSquareValue]
forall (t :: * -> *) a. Foldable t => t a -> [a]
Data.Foldable.toList
) ([EitherPieceSquareValueByNPiecesByCoordinates] -> ShowS)
-> [EitherPieceSquareValueByNPiecesByCoordinates] -> ShowS
forall a b. (a -> b) -> a -> b
$ ArrayByRank EitherPieceSquareValueByNPiecesByCoordinates
-> [EitherPieceSquareValueByNPiecesByCoordinates]
forall (t :: * -> *) a. Foldable t => t a -> [a]
Data.Foldable.toList ArrayByRank EitherPieceSquareValueByNPiecesByCoordinates
byRank where
terminateRow :: ShowS
terminateRow = Char -> ShowS
showChar Char
'\n'
showsRow :: [ShowS] -> ShowS
showsRow = ShowS -> ShowS -> ShowS -> [ShowS] -> ShowS
Text.ShowList.showsDelimitedList ShowS
columnDelimiter ShowS
forall a. a -> a
id ShowS
terminateRow