module BishBosh.State.EnPassantAbscissa (
EnPassantAbscissa(getAbscissa),
mkMaybeEnPassantAbscissa
) where
import qualified BishBosh.Attribute.Rank as Attribute.Rank
import qualified BishBosh.Cartesian.Coordinates as Cartesian.Coordinates
import qualified BishBosh.Colour.LogicalColour as Colour.LogicalColour
import qualified BishBosh.Component.Move as Component.Move
import qualified BishBosh.Component.Piece as Component.Piece
import qualified BishBosh.Component.QualifiedMove as Component.QualifiedMove
import qualified BishBosh.Component.Turn as Component.Turn
import qualified BishBosh.Component.Zobrist as Component.Zobrist
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.Hashable as StateProperty.Hashable
import qualified BishBosh.Type.Length as Type.Length
import qualified Control.DeepSeq
import qualified Data.Maybe
newtype EnPassantAbscissa = MkEnPassantAbscissa {
EnPassantAbscissa -> X
getAbscissa :: Type.Length.X
} deriving (EnPassantAbscissa -> EnPassantAbscissa -> Bool
(EnPassantAbscissa -> EnPassantAbscissa -> Bool)
-> (EnPassantAbscissa -> EnPassantAbscissa -> Bool)
-> Eq EnPassantAbscissa
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: EnPassantAbscissa -> EnPassantAbscissa -> Bool
$c/= :: EnPassantAbscissa -> EnPassantAbscissa -> Bool
== :: EnPassantAbscissa -> EnPassantAbscissa -> Bool
$c== :: EnPassantAbscissa -> EnPassantAbscissa -> Bool
Eq, Eq EnPassantAbscissa
Eq EnPassantAbscissa
-> (EnPassantAbscissa -> EnPassantAbscissa -> Ordering)
-> (EnPassantAbscissa -> EnPassantAbscissa -> Bool)
-> (EnPassantAbscissa -> EnPassantAbscissa -> Bool)
-> (EnPassantAbscissa -> EnPassantAbscissa -> Bool)
-> (EnPassantAbscissa -> EnPassantAbscissa -> Bool)
-> (EnPassantAbscissa -> EnPassantAbscissa -> EnPassantAbscissa)
-> (EnPassantAbscissa -> EnPassantAbscissa -> EnPassantAbscissa)
-> Ord EnPassantAbscissa
EnPassantAbscissa -> EnPassantAbscissa -> Bool
EnPassantAbscissa -> EnPassantAbscissa -> Ordering
EnPassantAbscissa -> EnPassantAbscissa -> EnPassantAbscissa
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: EnPassantAbscissa -> EnPassantAbscissa -> EnPassantAbscissa
$cmin :: EnPassantAbscissa -> EnPassantAbscissa -> EnPassantAbscissa
max :: EnPassantAbscissa -> EnPassantAbscissa -> EnPassantAbscissa
$cmax :: EnPassantAbscissa -> EnPassantAbscissa -> EnPassantAbscissa
>= :: EnPassantAbscissa -> EnPassantAbscissa -> Bool
$c>= :: EnPassantAbscissa -> EnPassantAbscissa -> Bool
> :: EnPassantAbscissa -> EnPassantAbscissa -> Bool
$c> :: EnPassantAbscissa -> EnPassantAbscissa -> Bool
<= :: EnPassantAbscissa -> EnPassantAbscissa -> Bool
$c<= :: EnPassantAbscissa -> EnPassantAbscissa -> Bool
< :: EnPassantAbscissa -> EnPassantAbscissa -> Bool
$c< :: EnPassantAbscissa -> EnPassantAbscissa -> Bool
compare :: EnPassantAbscissa -> EnPassantAbscissa -> Ordering
$ccompare :: EnPassantAbscissa -> EnPassantAbscissa -> Ordering
$cp1Ord :: Eq EnPassantAbscissa
Ord)
instance Control.DeepSeq.NFData EnPassantAbscissa where
rnf :: EnPassantAbscissa -> ()
rnf MkEnPassantAbscissa { getAbscissa :: EnPassantAbscissa -> X
getAbscissa = X
x } = X -> ()
forall a. NFData a => a -> ()
Control.DeepSeq.rnf X
x
instance StateProperty.Hashable.Hashable EnPassantAbscissa where
listRandoms :: Zobrist positionHash -> EnPassantAbscissa -> [positionHash]
listRandoms Zobrist positionHash
zobrist MkEnPassantAbscissa { getAbscissa :: EnPassantAbscissa -> X
getAbscissa = X
x } = positionHash -> [positionHash]
forall (m :: * -> *) a. Monad m => a -> m a
return (positionHash -> [positionHash]) -> positionHash -> [positionHash]
forall a b. (a -> b) -> a -> b
$! Zobrist positionHash -> X -> positionHash
forall positionHash. Zobrist positionHash -> X -> positionHash
Component.Zobrist.dereferenceRandomByEnPassantAbscissa Zobrist positionHash
zobrist X
x
mkMaybeEnPassantAbscissa
:: Colour.LogicalColour.LogicalColour
-> State.MaybePieceByCoordinates.MaybePieceByCoordinates
-> Component.Turn.Turn
-> Maybe EnPassantAbscissa
mkMaybeEnPassantAbscissa :: LogicalColour
-> MaybePieceByCoordinates -> Turn -> Maybe EnPassantAbscissa
mkMaybeEnPassantAbscissa LogicalColour
nextLogicalColour MaybePieceByCoordinates
maybePieceByCoordinates Turn
lastTurn
| Turn -> LogicalColour -> Bool
Component.Turn.isPawnDoubleAdvance Turn
lastTurn (LogicalColour -> Bool) -> LogicalColour -> Bool
forall a b. (a -> b) -> a -> b
$! LogicalColour -> LogicalColour
forall a. Opposable a => a -> a
Property.Opposable.getOpposite LogicalColour
nextLogicalColour
, let lastMoveDestination :: Coordinates
lastMoveDestination = Move -> Coordinates
Component.Move.getDestination (Move -> Coordinates)
-> (QualifiedMove -> Move) -> QualifiedMove -> Coordinates
forall b c a. (b -> c) -> (a -> b) -> a -> c
. QualifiedMove -> Move
Component.QualifiedMove.getMove (QualifiedMove -> Coordinates) -> QualifiedMove -> Coordinates
forall a b. (a -> b) -> a -> b
$! Turn -> QualifiedMove
Component.Turn.getQualifiedMove Turn
lastTurn
, 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
adjacentPawnCoordinates |
Coordinates
adjacentPawnCoordinates <- (Coordinates -> Bool) -> [Coordinates] -> [Coordinates]
forall a. (a -> Bool) -> [a] -> [a]
filter (
(Maybe Piece -> Maybe Piece -> Bool
forall a. Eq a => a -> a -> Bool
== Piece -> Maybe Piece
forall a. a -> Maybe a
Just (LogicalColour -> Piece
Component.Piece.mkPawn LogicalColour
nextLogicalColour)) (Maybe Piece -> Bool)
-> (Coordinates -> Maybe Piece) -> Coordinates -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MaybePieceByCoordinates -> Coordinates -> Maybe Piece
State.MaybePieceByCoordinates.dereference MaybePieceByCoordinates
maybePieceByCoordinates
) ([Coordinates] -> [Coordinates]) -> [Coordinates] -> [Coordinates]
forall a b. (a -> b) -> a -> b
$ Coordinates -> [Coordinates]
Cartesian.Coordinates.getAdjacents Coordinates
lastMoveDestination,
((Direction, Rank) -> Bool) -> [(Direction, Rank)] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (
\(Direction
direction, Rank
rank) -> Rank
rank Rank -> [Rank] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Rank]
Attribute.Rank.plodders Bool -> Bool -> Bool
|| (
Maybe Piece -> Maybe Piece -> Bool
forall a. Eq a => a -> a -> Bool
/= Piece -> Maybe Piece
forall a. a -> Maybe a
Just (LogicalColour -> Piece
Component.Piece.mkKing LogicalColour
nextLogicalColour)
) (
((Coordinates, Piece) -> Piece)
-> Maybe (Coordinates, Piece) -> Maybe Piece
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Coordinates, Piece) -> Piece
forall a b. (a, b) -> b
snd (Maybe (Coordinates, Piece) -> Maybe Piece)
-> (Direction -> Maybe (Coordinates, Piece))
-> Direction
-> Maybe Piece
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MaybePieceByCoordinates
-> Coordinates -> Direction -> Maybe (Coordinates, Piece)
State.MaybePieceByCoordinates.findBlockingPiece MaybePieceByCoordinates
maybePieceByCoordinates Coordinates
adjacentPawnCoordinates (Direction -> Maybe Piece) -> Direction -> Maybe Piece
forall a b. (a -> b) -> a -> b
$ Direction -> Direction
forall a. Opposable a => a -> a
Property.Opposable.getOpposite Direction
direction
)
) ([(Direction, Rank)] -> Bool) -> [(Direction, Rank)] -> Bool
forall a b. (a -> b) -> a -> b
$ (Direction -> Maybe (Direction, Rank))
-> [Direction] -> [(Direction, Rank)]
forall a b. (a -> Maybe b) -> [a] -> [b]
Data.Maybe.mapMaybe (
\Direction
direction -> (,) Direction
direction (Rank -> (Direction, Rank))
-> ((Coordinates, Rank) -> Rank)
-> (Coordinates, Rank)
-> (Direction, Rank)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Coordinates, Rank) -> Rank
forall a b. (a, b) -> b
snd ((Coordinates, Rank) -> (Direction, Rank))
-> Maybe (Coordinates, Rank) -> Maybe (Direction, Rank)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MaybePieceByCoordinates
-> LogicalColour
-> Coordinates
-> Direction
-> Maybe (Coordinates, Rank)
State.MaybePieceByCoordinates.findAttackerInDirection MaybePieceByCoordinates
maybePieceByCoordinates LogicalColour
nextLogicalColour Coordinates
adjacentPawnCoordinates Direction
direction
) [Direction]
forall a. FixedMembership a => [a]
Property.FixedMembership.members
] = EnPassantAbscissa -> Maybe EnPassantAbscissa
forall a. a -> Maybe a
Just (EnPassantAbscissa -> Maybe EnPassantAbscissa)
-> (X -> EnPassantAbscissa) -> X -> Maybe EnPassantAbscissa
forall b c a. (b -> c) -> (a -> b) -> a -> c
. X -> EnPassantAbscissa
MkEnPassantAbscissa (X -> Maybe EnPassantAbscissa) -> X -> Maybe EnPassantAbscissa
forall a b. (a -> b) -> a -> b
$ Coordinates -> X
Cartesian.Coordinates.getX Coordinates
lastMoveDestination
| Bool
otherwise = Maybe EnPassantAbscissa
forall a. Maybe a
Nothing