module BishBosh.Notation.MoveNotation(
ShowNotation(..),
ShowNotationFloat(..),
MoveNotation(),
tag,
coordinate,
range,
readsQualifiedMove,
showNotation,
showsMoveSyntax,
getOrigin,
showsNotationFloatToNDecimals,
isCoordinate
) where
import Control.Arrow((&&&))
import qualified BishBosh.Attribute.Rank as Attribute.Rank
import qualified BishBosh.Cartesian.Coordinates as Cartesian.Coordinates
import qualified BishBosh.Component.EitherQualifiedMove as Component.EitherQualifiedMove
import qualified BishBosh.Component.QualifiedMove as Component.QualifiedMove
import qualified BishBosh.Component.Turn as Component.Turn
import qualified BishBosh.Notation.Coordinate as Notation.Coordinate
import qualified BishBosh.Notation.ICCFNumeric as Notation.ICCFNumeric
import qualified BishBosh.Notation.Smith as Notation.Smith
import qualified BishBosh.Property.ShowFloat as Property.ShowFloat
import qualified Control.Arrow
import qualified Control.DeepSeq
import qualified Data.Default
import qualified Numeric
import qualified Text.XML.HXT.Arrow.Pickle as HXT
import qualified Text.XML.HXT.Arrow.Pickle.Schema
tag :: String
tag = "moveNotation"
data MoveNotation
= Coordinate
| ICCFNumeric
| Smith
deriving (Eq, Read, Show)
instance Control.DeepSeq.NFData MoveNotation where
rnf _ = ()
instance Data.Default.Default MoveNotation where
def = Smith
instance HXT.XmlPickler MoveNotation where
xpickle = HXT.xpDefault Data.Default.def . HXT.xpWrap (read, show) . HXT.xpAttr tag . HXT.xpTextDT . Text.XML.HXT.Arrow.Pickle.Schema.scEnum $ map show range
coordinate :: MoveNotation
coordinate = Coordinate
range :: [MoveNotation]
range = [Coordinate, ICCFNumeric, Smith]
readsQualifiedMove :: (
Enum x,
Enum y,
Ord x,
Ord y
)
=> MoveNotation
-> ReadS (Component.EitherQualifiedMove.EitherQualifiedMove x y)
readsQualifiedMove Coordinate = map (Control.Arrow.first $ uncurry Component.EitherQualifiedMove.mkPartiallyQualifiedMove . (Notation.Coordinate.getMove &&& Attribute.Rank.getMaybePromotionRank)) . reads
readsQualifiedMove ICCFNumeric = map (Control.Arrow.first $ uncurry Component.EitherQualifiedMove.mkPartiallyQualifiedMove . (Notation.ICCFNumeric.getMove &&& Attribute.Rank.getMaybePromotionRank)) . reads
readsQualifiedMove Smith = map (Control.Arrow.first $ uncurry Component.EitherQualifiedMove.mkFullyQualifiedMove . (Component.QualifiedMove.getMove &&& Component.QualifiedMove.getMoveType) . Notation.Smith.getQualifiedMove) . reads
showsMoveSyntax :: MoveNotation -> ShowS
showsMoveSyntax moveNotation = showChar '/' . showString (
case moveNotation of
Coordinate -> Notation.Coordinate.regexSyntax
ICCFNumeric -> Notation.ICCFNumeric.regexSyntax
Smith -> Notation.Smith.regexSyntax
) . showChar '/'
getOrigin :: MoveNotation -> (Int, Int)
getOrigin Coordinate = Notation.Coordinate.origin
getOrigin ICCFNumeric = Notation.ICCFNumeric.origin
getOrigin Smith = Notation.Smith.origin
isCoordinate :: MoveNotation -> Bool
isCoordinate Coordinate = True
isCoordinate _ = False
class ShowNotation a where
showsNotation :: MoveNotation -> a -> ShowS
instance (Enum x, Enum y) => ShowNotation (Component.QualifiedMove.QualifiedMove x y) where
showsNotation moveNotation qualifiedMove = case moveNotation of
Coordinate -> shows $ Notation.Coordinate.mkCoordinate' move moveType
ICCFNumeric -> shows $ Notation.ICCFNumeric.mkICCFNumeric' move moveType
Smith -> shows $ Notation.Smith.fromQualifiedMove qualifiedMove
where
(move, moveType) = Component.QualifiedMove.getMove &&& Component.QualifiedMove.getMoveType $ qualifiedMove
instance (Enum x, Enum y) => ShowNotation (Component.Turn.Turn x y) where
showsNotation moveNotation = showsNotation moveNotation . Component.Turn.getQualifiedMove
instance (Enum x, Enum y) => ShowNotation (Cartesian.Coordinates.Coordinates x y) where
showsNotation Coordinate = Notation.Coordinate.showsCoordinates
showsNotation ICCFNumeric = Notation.ICCFNumeric.showsCoordinates
showsNotation Smith = Notation.Smith.showsCoordinates
showNotation :: (ShowNotation a) => MoveNotation -> a -> String
showNotation moveNotation = ($ "") . showsNotation moveNotation
class ShowNotationFloat a where
showsNotationFloat :: MoveNotation -> (Double -> ShowS) -> a -> ShowS
showsNotationFloatToNDecimals :: ShowNotationFloat a => MoveNotation -> Property.ShowFloat.NDecimalDigits -> a -> ShowS
showsNotationFloatToNDecimals moveNotation nDecimalDigits = showsNotationFloat moveNotation (Numeric.showFFloat $ Just nDecimalDigits)