module BishBosh.State.CoordinatesByRankByLogicalColour(
CoordinatesByLogicalColour,
CoordinatesByRankByLogicalColour(
deconstruct
),
findPassedPawnCoordinatesByLogicalColour,
findPiecesOfColour,
assocs,
listCoordinates,
getKingsCoordinates,
dereference,
fromMaybePieceByCoordinates,
movePiece,
sortCoordinates
) 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.Rank as Attribute.Rank
import qualified BishBosh.Cartesian.Abscissa as Cartesian.Abscissa
import qualified BishBosh.Cartesian.Coordinates as Cartesian.Coordinates
import qualified BishBosh.Cartesian.Vector as Cartesian.Vector
import qualified BishBosh.Component.Accountant as Component.Accountant
import qualified BishBosh.Component.Move as Component.Move
import qualified BishBosh.Component.Piece as Component.Piece
import qualified BishBosh.Component.PieceSquareByCoordinatesByRank as Component.PieceSquareByCoordinatesByRank
import qualified BishBosh.Component.Zobrist as Component.Zobrist
import qualified BishBosh.Property.Empty as Property.Empty
import qualified BishBosh.Property.FixedMembership as Property.FixedMembership
import qualified BishBosh.Property.Opposable as Property.Opposable
import qualified BishBosh.State.MaybePieceByCoordinates as State.MaybePieceByCoordinates
import qualified BishBosh.StateProperty.Censor as StateProperty.Censor
import qualified BishBosh.StateProperty.Hashable as StateProperty.Hashable
import qualified BishBosh.StateProperty.Seeker as StateProperty.Seeker
import qualified Control.Arrow
import qualified Control.DeepSeq
import qualified Control.Exception
import qualified Data.Array.IArray
import qualified Data.Foldable
import qualified Data.List
import qualified Data.Map.Strict as Map
import qualified Data.Maybe
type CoordinatesByRank = Attribute.Rank.ArrayByRank [Cartesian.Coordinates.Coordinates]
newtype CoordinatesByRankByLogicalColour = MkCoordinatesByRankByLogicalColour {
CoordinatesByRankByLogicalColour
-> ArrayByLogicalColour CoordinatesByRank
deconstruct :: Attribute.LogicalColour.ArrayByLogicalColour CoordinatesByRank
}
instance Control.DeepSeq.NFData CoordinatesByRankByLogicalColour where
rnf :: CoordinatesByRankByLogicalColour -> ()
rnf MkCoordinatesByRankByLogicalColour { deconstruct :: CoordinatesByRankByLogicalColour
-> ArrayByLogicalColour CoordinatesByRank
deconstruct = ArrayByLogicalColour CoordinatesByRank
byLogicalColour } = ArrayByLogicalColour CoordinatesByRank -> ()
forall a. NFData a => a -> ()
Control.DeepSeq.rnf ArrayByLogicalColour CoordinatesByRank
byLogicalColour
instance StateProperty.Censor.Censor CoordinatesByRankByLogicalColour where
countPiecesByLogicalColour :: CoordinatesByRankByLogicalColour -> (NPieces, NPieces)
countPiecesByLogicalColour MkCoordinatesByRankByLogicalColour { deconstruct :: CoordinatesByRankByLogicalColour
-> ArrayByLogicalColour CoordinatesByRank
deconstruct = ArrayByLogicalColour CoordinatesByRank
byLogicalColour } = ((LogicalColour -> NPieces) -> LogicalColour -> NPieces
forall a b. (a -> b) -> a -> b
$ LogicalColour
Attribute.LogicalColour.Black) ((LogicalColour -> NPieces) -> NPieces)
-> ((LogicalColour -> NPieces) -> NPieces)
-> (LogicalColour -> NPieces)
-> (NPieces, NPieces)
forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& ((LogicalColour -> NPieces) -> LogicalColour -> NPieces
forall a b. (a -> b) -> a -> b
$ LogicalColour
Attribute.LogicalColour.White) ((LogicalColour -> NPieces) -> (NPieces, NPieces))
-> (LogicalColour -> NPieces) -> (NPieces, NPieces)
forall a b. (a -> b) -> a -> b
$ (NPieces -> [Coordinates] -> NPieces)
-> NPieces -> CoordinatesByRank -> NPieces
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
Data.List.foldl' (\NPieces
acc -> (NPieces -> NPieces -> NPieces
forall a. Num a => a -> a -> a
+ NPieces
acc) (NPieces -> NPieces)
-> ([Coordinates] -> NPieces) -> [Coordinates] -> NPieces
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NPieces -> NPieces
forall a b. (Integral a, Num b) => a -> b
fromIntegral (NPieces -> NPieces)
-> ([Coordinates] -> NPieces) -> [Coordinates] -> NPieces
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Coordinates] -> NPieces
forall (t :: * -> *) a. Foldable t => t a -> NPieces
length) NPieces
0 (CoordinatesByRank -> NPieces)
-> (LogicalColour -> CoordinatesByRank) -> LogicalColour -> NPieces
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ArrayByLogicalColour CoordinatesByRank
byLogicalColour ArrayByLogicalColour CoordinatesByRank
-> LogicalColour -> CoordinatesByRank
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
!)
countPieces :: CoordinatesByRankByLogicalColour -> NPieces
countPieces MkCoordinatesByRankByLogicalColour { deconstruct :: CoordinatesByRankByLogicalColour
-> ArrayByLogicalColour CoordinatesByRank
deconstruct = ArrayByLogicalColour CoordinatesByRank
byLogicalColour } = (NPieces -> CoordinatesByRank -> NPieces)
-> NPieces -> ArrayByLogicalColour CoordinatesByRank -> NPieces
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
Data.Foldable.foldl' (
(NPieces -> [Coordinates] -> NPieces)
-> NPieces -> CoordinatesByRank -> NPieces
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
Data.List.foldl' ((NPieces -> [Coordinates] -> NPieces)
-> NPieces -> CoordinatesByRank -> NPieces)
-> (NPieces -> [Coordinates] -> NPieces)
-> NPieces
-> CoordinatesByRank
-> NPieces
forall a b. (a -> b) -> a -> b
$ \NPieces
acc -> (NPieces -> NPieces -> NPieces
forall a. Num a => a -> a -> a
+ NPieces
acc) (NPieces -> NPieces)
-> ([Coordinates] -> NPieces) -> [Coordinates] -> NPieces
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NPieces -> NPieces
forall a b. (Integral a, Num b) => a -> b
fromIntegral (NPieces -> NPieces)
-> ([Coordinates] -> NPieces) -> [Coordinates] -> NPieces
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Coordinates] -> NPieces
forall (t :: * -> *) a. Foldable t => t a -> NPieces
length
) NPieces
0 ArrayByLogicalColour CoordinatesByRank
byLogicalColour
countPieceDifferenceByRank :: CoordinatesByRankByLogicalColour -> NPiecesByRank
countPieceDifferenceByRank MkCoordinatesByRankByLogicalColour { deconstruct :: CoordinatesByRankByLogicalColour
-> ArrayByLogicalColour CoordinatesByRank
deconstruct = ArrayByLogicalColour CoordinatesByRank
byLogicalColour } = [NPieces] -> NPiecesByRank
forall (a :: * -> * -> *) e. IArray a e => [e] -> a Rank e
Attribute.Rank.listArrayByRank ([NPieces] -> NPiecesByRank)
-> ((LogicalColour -> [NPieces]) -> [NPieces])
-> (LogicalColour -> [NPieces])
-> NPiecesByRank
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([NPieces] -> [NPieces] -> [NPieces])
-> ([NPieces], [NPieces]) -> [NPieces]
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (
(NPieces -> NPieces -> NPieces)
-> [NPieces] -> [NPieces] -> [NPieces]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (-)
) (([NPieces], [NPieces]) -> [NPieces])
-> ((LogicalColour -> [NPieces]) -> ([NPieces], [NPieces]))
-> (LogicalColour -> [NPieces])
-> [NPieces]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (
((LogicalColour -> [NPieces]) -> LogicalColour -> [NPieces]
forall a b. (a -> b) -> a -> b
$ LogicalColour
Attribute.LogicalColour.White) ((LogicalColour -> [NPieces]) -> [NPieces])
-> ((LogicalColour -> [NPieces]) -> [NPieces])
-> (LogicalColour -> [NPieces])
-> ([NPieces], [NPieces])
forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& ((LogicalColour -> [NPieces]) -> LogicalColour -> [NPieces]
forall a b. (a -> b) -> a -> b
$ LogicalColour
Attribute.LogicalColour.Black)
) ((LogicalColour -> [NPieces]) -> NPiecesByRank)
-> (LogicalColour -> [NPieces]) -> NPiecesByRank
forall a b. (a -> b) -> a -> b
$ ([Coordinates] -> NPieces) -> [[Coordinates]] -> [NPieces]
forall a b. (a -> b) -> [a] -> [b]
map (NPieces -> NPieces
forall a b. (Integral a, Num b) => a -> b
fromIntegral (NPieces -> NPieces)
-> ([Coordinates] -> NPieces) -> [Coordinates] -> NPieces
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Coordinates] -> NPieces
forall (t :: * -> *) a. Foldable t => t a -> NPieces
length) ([[Coordinates]] -> [NPieces])
-> (LogicalColour -> [[Coordinates]]) -> LogicalColour -> [NPieces]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CoordinatesByRank -> [[Coordinates]]
forall (t :: * -> *) a. Foldable t => t a -> [a]
Data.Foldable.toList (CoordinatesByRank -> [[Coordinates]])
-> (LogicalColour -> CoordinatesByRank)
-> LogicalColour
-> [[Coordinates]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ArrayByLogicalColour CoordinatesByRank
byLogicalColour ArrayByLogicalColour CoordinatesByRank
-> LogicalColour -> CoordinatesByRank
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
!)
hasInsufficientMaterial :: CoordinatesByRankByLogicalColour -> Bool
hasInsufficientMaterial MkCoordinatesByRankByLogicalColour { deconstruct :: CoordinatesByRankByLogicalColour
-> ArrayByLogicalColour CoordinatesByRank
deconstruct = ArrayByLogicalColour CoordinatesByRank
byLogicalColour } = (CoordinatesByRank -> Bool)
-> ArrayByLogicalColour CoordinatesByRank -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
Data.Foldable.all (
\CoordinatesByRank
byRank -> (Rank -> Bool) -> [Rank] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (
[Coordinates] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null ([Coordinates] -> Bool) -> (Rank -> [Coordinates]) -> Rank -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (CoordinatesByRank
byRank CoordinatesByRank -> Rank -> [Coordinates]
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
!)
) [Rank]
Attribute.Rank.individuallySufficientMaterial
) ArrayByLogicalColour CoordinatesByRank
byLogicalColour Bool -> Bool -> Bool
&& case [Coordinates]
blackKnights [Coordinates] -> [Coordinates] -> [Coordinates]
forall a. [a] -> [a] -> [a]
++ [Coordinates]
whiteKnights of
[] -> [Coordinates] -> Bool
Cartesian.Coordinates.areSquaresIsochromatic [Coordinates]
bishops
[Coordinates
_] -> [Coordinates] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Coordinates]
bishops
[Coordinates]
_ -> Bool
False
where
[[Coordinates]
blackKnights, [Coordinates]
blackBishops, [Coordinates]
whiteKnights, [Coordinates]
whiteBishops] = [
CoordinatesByRank
byRank CoordinatesByRank -> Rank -> [Coordinates]
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
! Rank
rank |
CoordinatesByRank
byRank <- ArrayByLogicalColour CoordinatesByRank -> [CoordinatesByRank]
forall (t :: * -> *) a. Foldable t => t a -> [a]
Data.Foldable.toList ArrayByLogicalColour CoordinatesByRank
byLogicalColour,
Rank
rank <- [Rank
Attribute.Rank.Knight, Rank
Attribute.Rank.Bishop]
]
bishops :: [Coordinates]
bishops = [Coordinates]
blackBishops [Coordinates] -> [Coordinates] -> [Coordinates]
forall a. [a] -> [a] -> [a]
++ [Coordinates]
whiteBishops
hasBothKings :: CoordinatesByRankByLogicalColour -> Bool
hasBothKings MkCoordinatesByRankByLogicalColour { deconstruct :: CoordinatesByRankByLogicalColour
-> ArrayByLogicalColour CoordinatesByRank
deconstruct = ArrayByLogicalColour CoordinatesByRank
byLogicalColour } = Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ (CoordinatesByRank -> Bool)
-> ArrayByLogicalColour CoordinatesByRank -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
Data.Foldable.any ([Coordinates] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null ([Coordinates] -> Bool)
-> (CoordinatesByRank -> [Coordinates])
-> CoordinatesByRank
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (CoordinatesByRank -> Rank -> [Coordinates]
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
! Rank
Attribute.Rank.King)) ArrayByLogicalColour CoordinatesByRank
byLogicalColour
instance StateProperty.Hashable.Hashable CoordinatesByRankByLogicalColour where
listRandoms :: CoordinatesByRankByLogicalColour
-> Zobrist positionHash -> [positionHash]
listRandoms MkCoordinatesByRankByLogicalColour { deconstruct :: CoordinatesByRankByLogicalColour
-> ArrayByLogicalColour CoordinatesByRank
deconstruct = ArrayByLogicalColour CoordinatesByRank
byLogicalColour } Zobrist positionHash
zobrist = [
Index -> Zobrist positionHash -> positionHash
forall positionHash. Index -> Zobrist positionHash -> positionHash
Component.Zobrist.dereferenceRandomByCoordinatesByRankByLogicalColour (LogicalColour
logicalColour, Rank
rank, Coordinates
coordinates) Zobrist positionHash
zobrist |
(LogicalColour
logicalColour, CoordinatesByRank
byRank) <- ArrayByLogicalColour CoordinatesByRank
-> [(LogicalColour, CoordinatesByRank)]
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> [(i, e)]
Data.Array.IArray.assocs ArrayByLogicalColour CoordinatesByRank
byLogicalColour,
(Rank
rank, [Coordinates]
coordinatesList) <- CoordinatesByRank -> [(Rank, [Coordinates])]
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> [(i, e)]
Data.Array.IArray.assocs CoordinatesByRank
byRank,
Coordinates
coordinates <- [Coordinates]
coordinatesList
]
instance StateProperty.Seeker.Seeker CoordinatesByRankByLogicalColour where
findProximateKnights :: LogicalColour
-> Coordinates -> CoordinatesByRankByLogicalColour -> [Coordinates]
findProximateKnights LogicalColour
logicalColour Coordinates
destination MkCoordinatesByRankByLogicalColour { deconstruct :: CoordinatesByRankByLogicalColour
-> ArrayByLogicalColour CoordinatesByRank
deconstruct = ArrayByLogicalColour CoordinatesByRank
byLogicalColour } = (Coordinates -> Bool) -> [Coordinates] -> [Coordinates]
forall a. (a -> Bool) -> [a] -> [a]
filter (
\Coordinates
source -> Coordinates
source Coordinates -> Coordinates -> Bool
forall a. Eq a => a -> a -> Bool
/= Coordinates
destination Bool -> Bool -> Bool
&& Vector -> Bool
Cartesian.Vector.isKnightsMove (
Coordinates -> Coordinates -> Vector
Cartesian.Vector.measureDistance Coordinates
source Coordinates
destination
)
) ([Coordinates] -> [Coordinates]) -> [Coordinates] -> [Coordinates]
forall a b. (a -> b) -> a -> b
$ ArrayByLogicalColour CoordinatesByRank
byLogicalColour ArrayByLogicalColour CoordinatesByRank
-> LogicalColour -> CoordinatesByRank
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
! LogicalColour
logicalColour CoordinatesByRank -> Rank -> [Coordinates]
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
! Rank
Attribute.Rank.Knight
findPieces :: (Piece -> Bool)
-> CoordinatesByRankByLogicalColour -> [LocatedPiece]
findPieces Piece -> Bool
predicate MkCoordinatesByRankByLogicalColour { deconstruct :: CoordinatesByRankByLogicalColour
-> ArrayByLogicalColour CoordinatesByRank
deconstruct = ArrayByLogicalColour CoordinatesByRank
byLogicalColour } = [
(Coordinates
coordinates, Piece
piece) |
(LogicalColour
logicalColour, CoordinatesByRank
byRank) <- ArrayByLogicalColour CoordinatesByRank
-> [(LogicalColour, CoordinatesByRank)]
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> [(i, e)]
Data.Array.IArray.assocs ArrayByLogicalColour CoordinatesByRank
byLogicalColour,
(Rank
rank, [Coordinates]
coordinatesList) <- CoordinatesByRank -> [(Rank, [Coordinates])]
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> [(i, e)]
Data.Array.IArray.assocs CoordinatesByRank
byRank,
let piece :: Piece
piece = LogicalColour -> Rank -> Piece
Component.Piece.mkPiece LogicalColour
logicalColour Rank
rank,
Piece -> Bool
predicate Piece
piece,
Coordinates
coordinates <- [Coordinates]
coordinatesList
]
countPawnsByFileByLogicalColour :: CoordinatesByRankByLogicalColour -> NPiecesByFileByLogicalColour
countPawnsByFileByLogicalColour MkCoordinatesByRankByLogicalColour { deconstruct :: CoordinatesByRankByLogicalColour
-> ArrayByLogicalColour CoordinatesByRank
deconstruct = ArrayByLogicalColour CoordinatesByRank
byLogicalColour } = (CoordinatesByRank -> NPiecesByFile)
-> ArrayByLogicalColour CoordinatesByRank
-> NPiecesByFileByLogicalColour
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 (
(NPiecesByFile -> Coordinates -> NPiecesByFile)
-> NPiecesByFile -> [Coordinates] -> NPiecesByFile
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
Data.List.foldl' (
\NPiecesByFile
m Coordinates
coordinates -> NPieces -> NPiecesByFile -> NPiecesByFile
StateProperty.Seeker.accumulatePawnsByFile (Coordinates -> NPieces
Cartesian.Coordinates.getX Coordinates
coordinates) NPiecesByFile
m
) NPiecesByFile
forall a. Empty a => a
Property.Empty.empty ([Coordinates] -> NPiecesByFile)
-> (CoordinatesByRank -> [Coordinates])
-> CoordinatesByRank
-> NPiecesByFile
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (CoordinatesByRank -> Rank -> [Coordinates]
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
! Rank
Attribute.Rank.Pawn)
) ArrayByLogicalColour CoordinatesByRank
byLogicalColour
instance Component.Accountant.Accountant CoordinatesByRankByLogicalColour where
sumPieceSquareValueByLogicalColour :: PieceSquareByCoordinatesByRank pieceSquareValue
-> NPieces
-> CoordinatesByRankByLogicalColour
-> [pieceSquareValue]
sumPieceSquareValueByLogicalColour PieceSquareByCoordinatesByRank pieceSquareValue
pieceSquareByCoordinatesByRank NPieces
nPieces MkCoordinatesByRankByLogicalColour { deconstruct :: CoordinatesByRankByLogicalColour
-> ArrayByLogicalColour CoordinatesByRank
deconstruct = ArrayByLogicalColour CoordinatesByRank
byLogicalColour } = ((LogicalColour, CoordinatesByRank) -> pieceSquareValue)
-> [(LogicalColour, CoordinatesByRank)] -> [pieceSquareValue]
forall a b. (a -> b) -> [a] -> [b]
map (
\(LogicalColour
logicalColour, CoordinatesByRank
byRank) -> (pieceSquareValue -> (Rank, [Coordinates]) -> pieceSquareValue)
-> pieceSquareValue -> [(Rank, [Coordinates])] -> pieceSquareValue
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
Data.List.foldl' (
\pieceSquareValue
acc (Rank
rank, [Coordinates]
coordinatesList) -> (pieceSquareValue -> Coordinates -> pieceSquareValue)
-> pieceSquareValue -> [Coordinates] -> pieceSquareValue
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
Data.List.foldl' (
\pieceSquareValue
acc' -> (pieceSquareValue -> pieceSquareValue -> pieceSquareValue
forall a. Num a => a -> a -> a
+ pieceSquareValue
acc') (pieceSquareValue -> pieceSquareValue)
-> (Coordinates -> pieceSquareValue)
-> Coordinates
-> pieceSquareValue
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PieceSquareByCoordinatesByRank pieceSquareValue
-> NPieces
-> LogicalColour
-> Rank
-> Coordinates
-> pieceSquareValue
forall pieceSquareValue.
PieceSquareByCoordinatesByRank pieceSquareValue
-> NPieces
-> LogicalColour
-> Rank
-> Coordinates
-> pieceSquareValue
Component.PieceSquareByCoordinatesByRank.findPieceSquareValue PieceSquareByCoordinatesByRank pieceSquareValue
pieceSquareByCoordinatesByRank NPieces
nPieces LogicalColour
logicalColour Rank
rank
) pieceSquareValue
acc [Coordinates]
coordinatesList
) pieceSquareValue
0 ([(Rank, [Coordinates])] -> pieceSquareValue)
-> [(Rank, [Coordinates])] -> pieceSquareValue
forall a b. (a -> b) -> a -> b
$ CoordinatesByRank -> [(Rank, [Coordinates])]
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> [(i, e)]
Data.Array.IArray.assocs CoordinatesByRank
byRank
) ([(LogicalColour, CoordinatesByRank)] -> [pieceSquareValue])
-> [(LogicalColour, CoordinatesByRank)] -> [pieceSquareValue]
forall a b. (a -> b) -> a -> b
$ ArrayByLogicalColour CoordinatesByRank
-> [(LogicalColour, CoordinatesByRank)]
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> [(i, e)]
Data.Array.IArray.assocs ArrayByLogicalColour CoordinatesByRank
byLogicalColour
fromMaybePieceByCoordinates :: State.MaybePieceByCoordinates.MaybePieceByCoordinates -> CoordinatesByRankByLogicalColour
fromMaybePieceByCoordinates :: MaybePieceByCoordinates -> CoordinatesByRankByLogicalColour
fromMaybePieceByCoordinates MaybePieceByCoordinates
maybePieceByCoordinates = ArrayByLogicalColour CoordinatesByRank
-> CoordinatesByRankByLogicalColour
MkCoordinatesByRankByLogicalColour (ArrayByLogicalColour CoordinatesByRank
-> CoordinatesByRankByLogicalColour)
-> (([(Piece, [Coordinates])], [(Piece, [Coordinates])])
-> ArrayByLogicalColour CoordinatesByRank)
-> ([(Piece, [Coordinates])], [(Piece, [Coordinates])])
-> CoordinatesByRankByLogicalColour
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (
\([(Piece, [Coordinates])]
b, [(Piece, [Coordinates])]
w) -> [CoordinatesByRank] -> ArrayByLogicalColour CoordinatesByRank
forall (a :: * -> * -> *) e. IArray a e => [e] -> a LogicalColour e
Attribute.LogicalColour.listArrayByLogicalColour ([CoordinatesByRank] -> ArrayByLogicalColour CoordinatesByRank)
-> [CoordinatesByRank] -> ArrayByLogicalColour CoordinatesByRank
forall a b. (a -> b) -> a -> b
$ ([(Piece, [Coordinates])] -> CoordinatesByRank)
-> [[(Piece, [Coordinates])]] -> [CoordinatesByRank]
forall a b. (a -> b) -> [a] -> [b]
map (
([Coordinates] -> [Coordinates] -> [Coordinates])
-> [Coordinates]
-> (Rank, Rank)
-> [(Rank, [Coordinates])]
-> CoordinatesByRank
forall (a :: * -> * -> *) e i e'.
(IArray a e, Ix i) =>
(e -> e' -> e) -> e -> (i, i) -> [(i, e')] -> a i e
Data.Array.IArray.accumArray [Coordinates] -> [Coordinates] -> [Coordinates]
forall a. [a] -> [a] -> [a]
(++) [] (Rank
forall a. Bounded a => a
minBound, Rank
forall a. Bounded a => a
maxBound) ([(Rank, [Coordinates])] -> CoordinatesByRank)
-> ([(Piece, [Coordinates])] -> [(Rank, [Coordinates])])
-> [(Piece, [Coordinates])]
-> CoordinatesByRank
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Piece, [Coordinates]) -> (Rank, [Coordinates]))
-> [(Piece, [Coordinates])] -> [(Rank, [Coordinates])]
forall a b. (a -> b) -> [a] -> [b]
map ((Piece -> Rank) -> (Piece, [Coordinates]) -> (Rank, [Coordinates])
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
Control.Arrow.first Piece -> Rank
Component.Piece.getRank)
) [[(Piece, [Coordinates])]
b, [(Piece, [Coordinates])]
w]
) (([(Piece, [Coordinates])], [(Piece, [Coordinates])])
-> CoordinatesByRankByLogicalColour)
-> ([(Piece, [Coordinates])], [(Piece, [Coordinates])])
-> CoordinatesByRankByLogicalColour
forall a b. (a -> b) -> a -> b
$ ((Piece, [Coordinates]) -> Bool)
-> [(Piece, [Coordinates])]
-> ([(Piece, [Coordinates])], [(Piece, [Coordinates])])
forall a. (a -> Bool) -> [a] -> ([a], [a])
Data.List.partition (
Piece -> Bool
Component.Piece.isBlack (Piece -> Bool)
-> ((Piece, [Coordinates]) -> Piece)
-> (Piece, [Coordinates])
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Piece, [Coordinates]) -> Piece
forall a b. (a, b) -> a
fst
) [
(Piece
piece, [Coordinates
coordinates]) |
(Coordinates
coordinates, Piece
piece) <- MaybePieceByCoordinates -> [LocatedPiece]
forall seeker. Seeker seeker => seeker -> [LocatedPiece]
StateProperty.Seeker.findAllPieces MaybePieceByCoordinates
maybePieceByCoordinates
]
dereference
:: Attribute.LogicalColour.LogicalColour
-> Attribute.Rank.Rank
-> CoordinatesByRankByLogicalColour
-> [Cartesian.Coordinates.Coordinates]
{-# INLINE dereference #-}
dereference :: LogicalColour
-> Rank -> CoordinatesByRankByLogicalColour -> [Coordinates]
dereference LogicalColour
logicalColour Rank
rank MkCoordinatesByRankByLogicalColour { deconstruct :: CoordinatesByRankByLogicalColour
-> ArrayByLogicalColour CoordinatesByRank
deconstruct = ArrayByLogicalColour CoordinatesByRank
byLogicalColour } = ArrayByLogicalColour CoordinatesByRank
byLogicalColour ArrayByLogicalColour CoordinatesByRank
-> LogicalColour -> CoordinatesByRank
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
! LogicalColour
logicalColour CoordinatesByRank -> Rank -> [Coordinates]
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
! Rank
rank
assocs :: CoordinatesByRankByLogicalColour -> [(Component.Piece.Piece, [Cartesian.Coordinates.Coordinates])]
assocs :: CoordinatesByRankByLogicalColour -> [(Piece, [Coordinates])]
assocs MkCoordinatesByRankByLogicalColour { deconstruct :: CoordinatesByRankByLogicalColour
-> ArrayByLogicalColour CoordinatesByRank
deconstruct = ArrayByLogicalColour CoordinatesByRank
byLogicalColour } = [
(LogicalColour -> Rank -> Piece
Component.Piece.mkPiece LogicalColour
logicalColour Rank
rank, [Coordinates]
coordinatesList) |
(LogicalColour
logicalColour, CoordinatesByRank
byRank) <- ArrayByLogicalColour CoordinatesByRank
-> [(LogicalColour, CoordinatesByRank)]
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> [(i, e)]
Data.Array.IArray.assocs ArrayByLogicalColour CoordinatesByRank
byLogicalColour,
(Rank
rank, [Coordinates]
coordinatesList) <- CoordinatesByRank -> [(Rank, [Coordinates])]
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> [(i, e)]
Data.Array.IArray.assocs CoordinatesByRank
byRank
]
listCoordinates :: CoordinatesByRankByLogicalColour -> [Cartesian.Coordinates.Coordinates]
listCoordinates :: CoordinatesByRankByLogicalColour -> [Coordinates]
listCoordinates MkCoordinatesByRankByLogicalColour { deconstruct :: CoordinatesByRankByLogicalColour
-> ArrayByLogicalColour CoordinatesByRank
deconstruct = ArrayByLogicalColour CoordinatesByRank
byLogicalColour } = [
Coordinates
coordinates |
CoordinatesByRank
byRank <- ArrayByLogicalColour CoordinatesByRank -> [CoordinatesByRank]
forall (t :: * -> *) a. Foldable t => t a -> [a]
Data.Foldable.toList ArrayByLogicalColour CoordinatesByRank
byLogicalColour,
[Coordinates]
coordinatesList <- CoordinatesByRank -> [[Coordinates]]
forall (t :: * -> *) a. Foldable t => t a -> [a]
Data.Foldable.toList CoordinatesByRank
byRank,
Coordinates
coordinates <- [Coordinates]
coordinatesList
]
getKingsCoordinates
:: Attribute.LogicalColour.LogicalColour
-> CoordinatesByRankByLogicalColour
-> Cartesian.Coordinates.Coordinates
{-# INLINE getKingsCoordinates #-}
getKingsCoordinates :: LogicalColour -> CoordinatesByRankByLogicalColour -> Coordinates
getKingsCoordinates LogicalColour
logicalColour MkCoordinatesByRankByLogicalColour { deconstruct :: CoordinatesByRankByLogicalColour
-> ArrayByLogicalColour CoordinatesByRank
deconstruct = ArrayByLogicalColour CoordinatesByRank
byLogicalColour } = Bool -> Coordinates -> Coordinates
forall a. (?callStack::CallStack) => Bool -> a -> a
Control.Exception.assert (Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [Coordinates] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Coordinates]
coordinates) (Coordinates -> Coordinates) -> Coordinates -> Coordinates
forall a b. (a -> b) -> a -> b
$ [Coordinates] -> Coordinates
forall a. [a] -> a
head [Coordinates]
coordinates where
coordinates :: [Coordinates]
coordinates = ArrayByLogicalColour CoordinatesByRank
byLogicalColour ArrayByLogicalColour CoordinatesByRank
-> LogicalColour -> CoordinatesByRank
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
! LogicalColour
logicalColour CoordinatesByRank -> Rank -> [Coordinates]
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
! Rank
Attribute.Rank.King
findPiecesOfColour
:: Attribute.LogicalColour.LogicalColour
-> CoordinatesByRankByLogicalColour
-> [Component.Piece.LocatedPiece]
findPiecesOfColour :: LogicalColour -> CoordinatesByRankByLogicalColour -> [LocatedPiece]
findPiecesOfColour LogicalColour
logicalColour MkCoordinatesByRankByLogicalColour { deconstruct :: CoordinatesByRankByLogicalColour
-> ArrayByLogicalColour CoordinatesByRank
deconstruct = ArrayByLogicalColour CoordinatesByRank
byLogicalColour } = [
(Coordinates
coordinates, LogicalColour -> Rank -> Piece
Component.Piece.mkPiece LogicalColour
logicalColour Rank
rank) |
(Rank
rank, [Coordinates]
coordinatesList) <- CoordinatesByRank -> [(Rank, [Coordinates])]
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> [(i, e)]
Data.Array.IArray.assocs (CoordinatesByRank -> [(Rank, [Coordinates])])
-> CoordinatesByRank -> [(Rank, [Coordinates])]
forall a b. (a -> b) -> a -> b
$ ArrayByLogicalColour CoordinatesByRank
byLogicalColour ArrayByLogicalColour CoordinatesByRank
-> LogicalColour -> CoordinatesByRank
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
! LogicalColour
logicalColour,
Coordinates
coordinates <- [Coordinates]
coordinatesList
]
type CoordinatesByLogicalColour = Attribute.LogicalColour.ArrayByLogicalColour [Cartesian.Coordinates.Coordinates]
findPassedPawnCoordinatesByLogicalColour :: CoordinatesByRankByLogicalColour -> CoordinatesByLogicalColour
findPassedPawnCoordinatesByLogicalColour :: CoordinatesByRankByLogicalColour -> CoordinatesByLogicalColour
findPassedPawnCoordinatesByLogicalColour MkCoordinatesByRankByLogicalColour { deconstruct :: CoordinatesByRankByLogicalColour
-> ArrayByLogicalColour CoordinatesByRank
deconstruct = ArrayByLogicalColour CoordinatesByRank
byLogicalColour } = [[Coordinates]] -> CoordinatesByLogicalColour
forall (a :: * -> * -> *) e. IArray a e => [e] -> a LogicalColour e
Attribute.LogicalColour.listArrayByLogicalColour ([[Coordinates]] -> CoordinatesByLogicalColour)
-> [[Coordinates]] -> CoordinatesByLogicalColour
forall a b. (a -> b) -> a -> b
$ (LogicalColour -> [Coordinates])
-> [LogicalColour] -> [[Coordinates]]
forall a b. (a -> b) -> [a] -> [b]
map (
\LogicalColour
logicalColour -> let
opponentsLogicalColour :: LogicalColour
opponentsLogicalColour = LogicalColour -> LogicalColour
forall a. Opposable a => a -> a
Property.Opposable.getOpposite LogicalColour
logicalColour
opposingPawnYByX :: NPiecesByFile
opposingPawnYByX = (NPiecesByFile -> Coordinates -> NPiecesByFile)
-> NPiecesByFile -> [Coordinates] -> NPiecesByFile
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
Data.List.foldl' (
\NPiecesByFile
m Coordinates
coordinates -> (NPieces -> NPieces -> NPiecesByFile -> NPiecesByFile)
-> (NPieces, NPieces) -> NPiecesByFile -> NPiecesByFile
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (
(NPieces -> NPieces -> NPieces)
-> NPieces -> NPieces -> NPiecesByFile -> NPiecesByFile
forall k a. Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
Map.insertWith ((NPieces -> NPieces -> NPieces)
-> NPieces -> NPieces -> NPiecesByFile -> NPiecesByFile)
-> (NPieces -> NPieces -> NPieces)
-> NPieces
-> NPieces
-> NPiecesByFile
-> NPiecesByFile
forall a b. (a -> b) -> a -> b
$ if LogicalColour -> Bool
Attribute.LogicalColour.isBlack LogicalColour
opponentsLogicalColour
then NPieces -> NPieces -> NPieces
forall a. Ord a => a -> a -> a
max
else NPieces -> NPieces -> NPieces
forall a. Ord a => a -> a -> a
min
) (
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
) NPiecesByFile
m
) NPiecesByFile
forall a. Empty a => a
Property.Empty.empty ([Coordinates] -> NPiecesByFile) -> [Coordinates] -> NPiecesByFile
forall a b. (a -> b) -> a -> b
$ LogicalColour -> [Coordinates]
findPawns LogicalColour
opponentsLogicalColour
in (Coordinates -> Bool) -> [Coordinates] -> [Coordinates]
forall a. (a -> Bool) -> [a] -> [a]
filter (
\Coordinates
coordinates -> (NPieces -> Bool) -> [NPieces] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (
Bool -> (NPieces -> Bool) -> Maybe NPieces -> Bool
forall b a. b -> (a -> b) -> Maybe a -> b
Data.Maybe.maybe Bool
True (
(
Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
/= LogicalColour -> Ordering
Attribute.Direction.advanceDirection LogicalColour
logicalColour
) (Ordering -> Bool) -> (NPieces -> Ordering) -> NPieces -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (
NPieces -> NPieces -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` Coordinates -> NPieces
Cartesian.Coordinates.getY Coordinates
coordinates
)
) (Maybe NPieces -> Bool)
-> (NPieces -> Maybe NPieces) -> NPieces -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (NPieces -> NPiecesByFile -> Maybe NPieces
forall k a. Ord k => k -> Map k a -> Maybe a
`Map.lookup` NPiecesByFile
opposingPawnYByX)
) ([NPieces] -> Bool) -> (NPieces -> [NPieces]) -> NPieces -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (NPieces -> [NPieces] -> [NPieces])
-> (NPieces, [NPieces]) -> [NPieces]
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (:) ((NPieces, [NPieces]) -> [NPieces])
-> (NPieces -> (NPieces, [NPieces])) -> NPieces -> [NPieces]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (
NPieces -> NPieces
forall a. a -> a
id (NPieces -> NPieces)
-> (NPieces -> [NPieces]) -> NPieces -> (NPieces, [NPieces])
forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& NPieces -> [NPieces]
Cartesian.Abscissa.getAdjacents
) (NPieces -> Bool) -> NPieces -> Bool
forall a b. (a -> b) -> a -> b
$ Coordinates -> NPieces
Cartesian.Coordinates.getX Coordinates
coordinates
) ([Coordinates] -> [Coordinates]) -> [Coordinates] -> [Coordinates]
forall a b. (a -> b) -> a -> b
$ LogicalColour -> [Coordinates]
findPawns LogicalColour
logicalColour
) [LogicalColour]
forall a. FixedMembership a => [a]
Property.FixedMembership.members where
findPawns :: LogicalColour -> [Coordinates]
findPawns = (CoordinatesByRank -> Rank -> [Coordinates]
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
! Rank
Attribute.Rank.Pawn) (CoordinatesByRank -> [Coordinates])
-> (LogicalColour -> CoordinatesByRank)
-> LogicalColour
-> [Coordinates]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ArrayByLogicalColour CoordinatesByRank
byLogicalColour ArrayByLogicalColour CoordinatesByRank
-> LogicalColour -> CoordinatesByRank
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
!)
type Transformation = CoordinatesByRankByLogicalColour -> CoordinatesByRankByLogicalColour
deleteCoordinates
:: Cartesian.Coordinates.Coordinates
-> Attribute.Rank.Rank
-> CoordinatesByRank
-> CoordinatesByRank
deleteCoordinates :: Coordinates -> Rank -> CoordinatesByRank -> CoordinatesByRank
deleteCoordinates Coordinates
coordinates Rank
rank CoordinatesByRank
byRank = CoordinatesByRank
byRank CoordinatesByRank -> [(Rank, [Coordinates])] -> CoordinatesByRank
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> [(i, e)] -> a i e
// [(Rank
rank, Coordinates -> [Coordinates] -> [Coordinates]
forall a. Eq a => a -> [a] -> [a]
Data.List.delete Coordinates
coordinates ([Coordinates] -> [Coordinates]) -> [Coordinates] -> [Coordinates]
forall a b. (a -> b) -> a -> b
$ CoordinatesByRank
byRank CoordinatesByRank -> Rank -> [Coordinates]
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
! Rank
rank)]
movePiece
:: Component.Move.Move
-> Component.Piece.Piece
-> Maybe Attribute.Rank.Rank
-> Either Cartesian.Coordinates.Coordinates (Maybe Attribute.Rank.Rank)
-> Transformation
movePiece :: Move
-> Piece
-> Maybe Rank
-> Either Coordinates (Maybe Rank)
-> Transformation
movePiece Move
move Piece
sourcePiece Maybe Rank
maybePromotionRank Either Coordinates (Maybe Rank)
eitherPassingPawnsDestinationOrMaybeTakenRank MkCoordinatesByRankByLogicalColour { deconstruct :: CoordinatesByRankByLogicalColour
-> ArrayByLogicalColour CoordinatesByRank
deconstruct = ArrayByLogicalColour CoordinatesByRank
byLogicalColour } = ArrayByLogicalColour CoordinatesByRank
-> CoordinatesByRankByLogicalColour
MkCoordinatesByRankByLogicalColour (ArrayByLogicalColour CoordinatesByRank
-> CoordinatesByRankByLogicalColour)
-> ArrayByLogicalColour CoordinatesByRank
-> CoordinatesByRankByLogicalColour
forall a b. (a -> b) -> a -> b
$ ArrayByLogicalColour CoordinatesByRank
byLogicalColour ArrayByLogicalColour CoordinatesByRank
-> [(LogicalColour, CoordinatesByRank)]
-> ArrayByLogicalColour CoordinatesByRank
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> [(i, e)] -> a i e
// (
(:) ((LogicalColour, CoordinatesByRank)
-> [(LogicalColour, CoordinatesByRank)]
-> [(LogicalColour, CoordinatesByRank)])
-> (Coordinates -> (LogicalColour, CoordinatesByRank))
-> Coordinates
-> [(LogicalColour, CoordinatesByRank)]
-> [(LogicalColour, CoordinatesByRank)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Coordinates -> Rank -> (LogicalColour, CoordinatesByRank)
`deleteOpponentsCoordinates` Rank
Attribute.Rank.Pawn) (Coordinates
-> [(LogicalColour, CoordinatesByRank)]
-> [(LogicalColour, CoordinatesByRank)])
-> (Maybe Rank
-> [(LogicalColour, CoordinatesByRank)]
-> [(LogicalColour, CoordinatesByRank)])
-> Either Coordinates (Maybe Rank)
-> [(LogicalColour, CoordinatesByRank)]
-> [(LogicalColour, CoordinatesByRank)]
forall (a :: * -> * -> *) b d c.
ArrowChoice a =>
a b d -> a c d -> a (Either b c) d
||| ([(LogicalColour, CoordinatesByRank)]
-> [(LogicalColour, CoordinatesByRank)])
-> (Rank
-> [(LogicalColour, CoordinatesByRank)]
-> [(LogicalColour, CoordinatesByRank)])
-> Maybe Rank
-> [(LogicalColour, CoordinatesByRank)]
-> [(LogicalColour, CoordinatesByRank)]
forall b a. b -> (a -> b) -> Maybe a -> b
Data.Maybe.maybe [(LogicalColour, CoordinatesByRank)]
-> [(LogicalColour, CoordinatesByRank)]
forall a. a -> a
id (
(:) ((LogicalColour, CoordinatesByRank)
-> [(LogicalColour, CoordinatesByRank)]
-> [(LogicalColour, CoordinatesByRank)])
-> (Rank -> (LogicalColour, CoordinatesByRank))
-> Rank
-> [(LogicalColour, CoordinatesByRank)]
-> [(LogicalColour, CoordinatesByRank)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Coordinates -> Rank -> (LogicalColour, CoordinatesByRank)
deleteOpponentsCoordinates Coordinates
destination
) (Either Coordinates (Maybe Rank)
-> [(LogicalColour, CoordinatesByRank)]
-> [(LogicalColour, CoordinatesByRank)])
-> Either Coordinates (Maybe Rank)
-> [(LogicalColour, CoordinatesByRank)]
-> [(LogicalColour, CoordinatesByRank)]
forall a b. (a -> b) -> a -> b
$ Either Coordinates (Maybe Rank)
eitherPassingPawnsDestinationOrMaybeTakenRank
) [
let
byRank :: CoordinatesByRank
byRank = ArrayByLogicalColour CoordinatesByRank
byLogicalColour ArrayByLogicalColour CoordinatesByRank
-> LogicalColour -> CoordinatesByRank
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
! LogicalColour
logicalColour
in (
LogicalColour
logicalColour,
CoordinatesByRank
byRank CoordinatesByRank -> [(Rank, [Coordinates])] -> CoordinatesByRank
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> [(i, e)] -> a i e
// ((Rank, [Coordinates]) -> [(Rank, [Coordinates])])
-> (Rank -> (Rank, [Coordinates]) -> [(Rank, [Coordinates])])
-> Maybe Rank
-> (Rank, [Coordinates])
-> [(Rank, [Coordinates])]
forall b a. b -> (a -> b) -> Maybe a -> b
Data.Maybe.maybe (
(Rank, [Coordinates]) -> [(Rank, [Coordinates])]
forall (m :: * -> *) a. Monad m => a -> m a
return ((Rank, [Coordinates]) -> [(Rank, [Coordinates])])
-> ((Rank, [Coordinates]) -> (Rank, [Coordinates]))
-> (Rank, [Coordinates])
-> [(Rank, [Coordinates])]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Coordinates] -> [Coordinates])
-> (Rank, [Coordinates]) -> (Rank, [Coordinates])
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
Control.Arrow.second (Coordinates
destination Coordinates -> [Coordinates] -> [Coordinates]
forall a. a -> [a] -> [a]
:)
) (
\Rank
promotionRank -> (:) (
Rank
promotionRank,
Coordinates
destination Coordinates -> [Coordinates] -> [Coordinates]
forall a. a -> [a] -> [a]
: CoordinatesByRank
byRank CoordinatesByRank -> Rank -> [Coordinates]
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
! Rank
promotionRank
) ([(Rank, [Coordinates])] -> [(Rank, [Coordinates])])
-> ((Rank, [Coordinates]) -> [(Rank, [Coordinates])])
-> (Rank, [Coordinates])
-> [(Rank, [Coordinates])]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Rank, [Coordinates]) -> [(Rank, [Coordinates])]
forall (m :: * -> *) a. Monad m => a -> m a
return
) Maybe Rank
maybePromotionRank (
Rank -> Rank
forall a. a -> a
id (Rank -> Rank)
-> (Rank -> [Coordinates]) -> Rank -> (Rank, [Coordinates])
forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& Coordinates -> [Coordinates] -> [Coordinates]
forall a. Eq a => a -> [a] -> [a]
Data.List.delete (Move -> Coordinates
Component.Move.getSource Move
move) ([Coordinates] -> [Coordinates])
-> (Rank -> [Coordinates]) -> Rank -> [Coordinates]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (CoordinatesByRank
byRank CoordinatesByRank -> Rank -> [Coordinates]
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
!) (Rank -> (Rank, [Coordinates])) -> Rank -> (Rank, [Coordinates])
forall a b. (a -> b) -> a -> b
$ Piece -> Rank
Component.Piece.getRank Piece
sourcePiece
)
)
] where
destination :: Coordinates
destination = Move -> Coordinates
Component.Move.getDestination Move
move
logicalColour :: LogicalColour
logicalColour = Piece -> LogicalColour
Component.Piece.getLogicalColour Piece
sourcePiece
deleteOpponentsCoordinates :: Coordinates -> Rank -> (LogicalColour, CoordinatesByRank)
deleteOpponentsCoordinates Coordinates
coordinates Rank
rank = LogicalColour -> LogicalColour
forall a. a -> a
id (LogicalColour -> LogicalColour)
-> (LogicalColour -> CoordinatesByRank)
-> LogicalColour
-> (LogicalColour, CoordinatesByRank)
forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& Coordinates -> Rank -> CoordinatesByRank -> CoordinatesByRank
deleteCoordinates Coordinates
coordinates Rank
rank (CoordinatesByRank -> CoordinatesByRank)
-> (LogicalColour -> CoordinatesByRank)
-> LogicalColour
-> CoordinatesByRank
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ArrayByLogicalColour CoordinatesByRank
byLogicalColour ArrayByLogicalColour CoordinatesByRank
-> LogicalColour -> CoordinatesByRank
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
!) (LogicalColour -> (LogicalColour, CoordinatesByRank))
-> LogicalColour -> (LogicalColour, CoordinatesByRank)
forall a b. (a -> b) -> a -> b
$ LogicalColour -> LogicalColour
forall a. Opposable a => a -> a
Property.Opposable.getOpposite LogicalColour
logicalColour
sortCoordinates :: Transformation
sortCoordinates :: Transformation
sortCoordinates MkCoordinatesByRankByLogicalColour { deconstruct :: CoordinatesByRankByLogicalColour
-> ArrayByLogicalColour CoordinatesByRank
deconstruct = ArrayByLogicalColour CoordinatesByRank
byLogicalColour } = ArrayByLogicalColour CoordinatesByRank
-> CoordinatesByRankByLogicalColour
MkCoordinatesByRankByLogicalColour (ArrayByLogicalColour CoordinatesByRank
-> CoordinatesByRankByLogicalColour)
-> ArrayByLogicalColour CoordinatesByRank
-> CoordinatesByRankByLogicalColour
forall a b. (a -> b) -> a -> b
$ (CoordinatesByRank -> CoordinatesByRank)
-> ArrayByLogicalColour CoordinatesByRank
-> ArrayByLogicalColour CoordinatesByRank
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] -> [Coordinates])
-> CoordinatesByRank -> CoordinatesByRank
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] -> [Coordinates]
forall a. Ord a => [a] -> [a]
Data.List.sort) ArrayByLogicalColour CoordinatesByRank
byLogicalColour