{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}
module BishBosh.State.Position(
Position(
getMaybeEnPassantAbscissa
),
mkPosition
) where
import qualified BishBosh.Attribute.LogicalColour as Attribute.LogicalColour
import qualified BishBosh.Component.Turn as Component.Turn
import qualified BishBosh.Component.Zobrist as Component.Zobrist
import qualified BishBosh.Property.Opposable as Property.Opposable
import qualified BishBosh.Property.Reflectable as Property.Reflectable
import qualified BishBosh.State.CastleableRooksByLogicalColour as State.CastleableRooksByLogicalColour
import qualified BishBosh.State.EnPassantAbscissa as State.EnPassantAbscissa
import qualified BishBosh.State.MaybePieceByCoordinates as State.MaybePieceByCoordinates
import qualified BishBosh.Types as T
import qualified Control.DeepSeq
import qualified Data.Array.IArray
import qualified Data.Maybe
data Position x y = MkPosition {
getNextLogicalColour :: Attribute.LogicalColour.LogicalColour,
getMaybePieceByCoordinates :: State.MaybePieceByCoordinates.MaybePieceByCoordinates x y,
getCastleableRooksByLogicalColour :: State.CastleableRooksByLogicalColour.CastleableRooksByLogicalColour x,
getMaybeEnPassantAbscissa :: Maybe (State.EnPassantAbscissa.EnPassantAbscissa x)
} deriving Eq
instance (
Enum x,
Enum y,
Ord x,
Ord y
) => Ord (Position x y) where
{-# SPECIALISE instance Ord (Position T.X T.Y) #-}
position@MkPosition {
getNextLogicalColour = nextLogicalColour,
getMaybePieceByCoordinates = maybePieceByCoordinates
} `compare` position'@MkPosition {
getNextLogicalColour = nextLogicalColour',
getMaybePieceByCoordinates = maybePieceByCoordinates'
} = (
nextLogicalColour,
maybePieceByCoordinates,
getCastleableRooksByLogicalColour position,
getMaybeEnPassantAbscissa position
) `compare` (
nextLogicalColour',
maybePieceByCoordinates',
getCastleableRooksByLogicalColour position',
getMaybeEnPassantAbscissa position'
)
instance (
Control.DeepSeq.NFData x,
Control.DeepSeq.NFData y
) => Control.DeepSeq.NFData (Position x y) where
rnf MkPosition {
getNextLogicalColour = nextLogicalColour,
getMaybePieceByCoordinates = maybePieceByCoordinates,
getCastleableRooksByLogicalColour = castleableRooksByLogicalColour,
getMaybeEnPassantAbscissa = maybeEnPassantAbscissa
} = Control.DeepSeq.rnf (nextLogicalColour, maybePieceByCoordinates, castleableRooksByLogicalColour, maybeEnPassantAbscissa)
instance (
Enum x,
Enum y,
Ord x,
Ord y
) => Property.Reflectable.ReflectableOnX (Position x y) where
reflectOnX position@MkPosition {
getNextLogicalColour = nextLogicalColour,
getMaybePieceByCoordinates = maybePieceByCoordinates,
getCastleableRooksByLogicalColour = castleableRooksByLogicalColour
} = position {
getNextLogicalColour = Property.Opposable.getOpposite nextLogicalColour,
getMaybePieceByCoordinates = Property.Reflectable.reflectOnX maybePieceByCoordinates,
getCastleableRooksByLogicalColour = Property.Reflectable.reflectOnX castleableRooksByLogicalColour
}
instance (Data.Array.IArray.Ix x, Enum x, Enum y, Ord y) => Component.Zobrist.Hashable2D Position x y where
listRandoms2D MkPosition {
getNextLogicalColour = nextLogicalColour,
getMaybePieceByCoordinates = maybePieceByCoordinates,
getCastleableRooksByLogicalColour = castleableRooksByLogicalColour,
getMaybeEnPassantAbscissa = maybeEnPassantAbscissa
} zobrist = (
if Attribute.LogicalColour.isBlack nextLogicalColour
then (Component.Zobrist.getRandomForBlacksMove zobrist :)
else id
) . Data.Maybe.maybe id (
(++) . (`Component.Zobrist.listRandoms1D` zobrist)
) maybeEnPassantAbscissa $ Component.Zobrist.listRandoms1D castleableRooksByLogicalColour zobrist ++ Component.Zobrist.listRandoms2D maybePieceByCoordinates zobrist
mkPosition :: (
Enum x,
Enum y,
Ord x,
Ord y
)
=> Attribute.LogicalColour.LogicalColour
-> State.MaybePieceByCoordinates.MaybePieceByCoordinates x y
-> State.CastleableRooksByLogicalColour.CastleableRooksByLogicalColour x
-> Maybe (Component.Turn.Turn x y)
-> Position x y
mkPosition nextLogicalColour maybePieceByCoordinates castleableRooksByLogicalColour maybeLastTurn = MkPosition {
getNextLogicalColour = nextLogicalColour,
getMaybePieceByCoordinates = maybePieceByCoordinates,
getCastleableRooksByLogicalColour = castleableRooksByLogicalColour,
getMaybeEnPassantAbscissa = maybeLastTurn >>= State.EnPassantAbscissa.mkMaybeEnPassantAbscissa nextLogicalColour maybePieceByCoordinates
}