{- Copyright (C) 2018 Dr. Alistair Ward This file is part of BishBosh. BishBosh is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. BishBosh is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with BishBosh. If not, see . -} {- | [@AUTHOR@] Dr. Alistair Ward [@DESCRIPTION@] * Defines the data-type which represents the logical (rather than physical) colour of the two players & of /piece/s. * N.B.: conceptually different from the logical colour of squares on the board. -} module BishBosh.Attribute.LogicalColour( -- * Types -- ** Type-synonyms ByLogicalColour, -- ** Data-types LogicalColour(..), -- * Constants -- tag, range, nDistinctLogicalColours, -- * Functions -- ** Constructor listArrayByLogicalColour, -- ** Predicates isBlack -- isWhite ) where import qualified BishBosh.Property.ForsythEdwards as Property.ForsythEdwards import qualified BishBosh.Property.Opposable as Property.Opposable import qualified Control.DeepSeq import qualified Control.Exception import qualified Data.Array.IArray import qualified Data.List.Extra import qualified Text.XML.HXT.Arrow.Pickle as HXT import qualified Text.XML.HXT.Arrow.Pickle.Schema -- | Used to qualify XML. tag :: String tag = "logicalColour" -- | The /logical colour/ associated with a player or a piece. data LogicalColour = Black | White deriving ( Bounded, Enum, Eq, Ord, Read, Show ) instance Control.DeepSeq.NFData LogicalColour where rnf _ = () instance Data.Array.IArray.Ix LogicalColour where range (lower, upper) = Control.Exception.assert (lower == minBound && upper == maxBound) range inRange (lower, upper) logicalColour = Control.Exception.assert (logicalColour >= lower && logicalColour <= upper) True index (lower, upper) = Control.Exception.assert (lower == minBound && upper == maxBound) . fromEnum -- | The constant ascending range of /logical colour/s. range :: [LogicalColour] range = [minBound, maxBound] -- | The constant number of distinct /logical colour/s. nDistinctLogicalColours :: Int nDistinctLogicalColours = length range instance HXT.XmlPickler LogicalColour where xpickle = HXT.xpAttr tag . HXT.xpWrap (read, show) . HXT.xpTextDT . Text.XML.HXT.Arrow.Pickle.Schema.scEnum $ map show range instance Property.Opposable.Opposable LogicalColour where getOpposite Black = White getOpposite _ = Black instance Property.ForsythEdwards.ReadsFEN LogicalColour where readsFEN s = case Data.List.Extra.trimStart s of 'b' : remainder -> [(Black, remainder)] 'w' : remainder -> [(White, remainder)] _ -> [] instance Property.ForsythEdwards.ShowsFEN LogicalColour where showsFEN logicalColour = showChar $ case logicalColour of Black -> 'b' White -> 'w' -- | Whether the specified /logical colour/ is @Black@. isBlack :: LogicalColour -> Bool {-# INLINE isBlack #-} isBlack Black = True isBlack _ = False -- | Whether the specified /logical colour/ is @White@. isWhite :: LogicalColour -> Bool isWhite = not . isBlack -- | A boxed array indexed by /logical colour/, of arbitrary elements. type ByLogicalColour = Data.Array.IArray.Array LogicalColour -- | Array-constructor. listArrayByLogicalColour :: Data.Array.IArray.IArray a e => [e] -> a LogicalColour e {-# INLINE listArrayByLogicalColour #-} listArrayByLogicalColour = Data.Array.IArray.listArray (minBound, maxBound)