bishbosh-0.1.2.0: src-lib/BishBosh/StateProperty/Mutator.hs
{-# LANGUAGE MultiParamTypeClasses #-}
{-
Copyright (C) 2021 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 <http://www.gnu.org/licenses/>.
-}
{- |
[@AUTHOR@] Dr. Alistair Ward
[@DESCRIPTION@] Permits a board to be mutated.
-}
module BishBosh.StateProperty.Mutator(
-- * Type-classes
Mutator(..),
-- * Functions
-- ** Mutators
placePiece,
placeFirstPiece,
placeAllPieces,
removePiece
) where
import qualified BishBosh.Cartesian.Coordinates as Cartesian.Coordinates
import qualified BishBosh.Component.Piece as Component.Piece
import qualified BishBosh.Property.Empty as Property.Empty
{- |
* Defines the specified /coordinates/, by either placing or removing a /piece/.
* CAVEAT: this function should only be used to construct custom scenarios, since /piece/s don't normally spring into existence.
* CAVEAT: doesn't validate the request, so @King@s can be placed /in check/ & @Pawn@s can be placed behind their starting rank or unpromoted on their last /rank/.
* CAVEAT: this function isn't called during normal play.
-}
class Mutator mutator where
defineCoordinates
:: Maybe Component.Piece.Piece -- ^ The optional /piece/ to place (or remove if @Nothing@ is specified).
-> Cartesian.Coordinates.Coordinates -- ^ The /coordinates/ to define.
-> mutator
-> mutator
{- |
* Place a /piece/ at the specified /coordinates/.
* CAVEAT: any /piece/ previously at the specified /coordinates/ will be obliterated.
-}
placePiece
:: Mutator mutator
=> Component.Piece.Piece
-> Cartesian.Coordinates.Coordinates
-> mutator
-> mutator
placePiece piece = defineCoordinates $ Just piece
-- | Place the first /piece/.
placeFirstPiece :: (
Property.Empty.Empty mutator,
Mutator mutator
)
=> Component.Piece.Piece
-> Cartesian.Coordinates.Coordinates
-> mutator
placeFirstPiece piece coordinates = placePiece piece coordinates Property.Empty.empty
-- | Place /pieces/ from scratch.
placeAllPieces :: (
Property.Empty.Empty mutator,
Mutator mutator
)
=> [(Component.Piece.Piece, Cartesian.Coordinates.Coordinates)]
-> mutator
placeAllPieces = foldr (uncurry placePiece) Property.Empty.empty
-- | Remove a /piece/ from the /board/.
removePiece
:: Mutator mutator
=> Cartesian.Coordinates.Coordinates
-> mutator
-> mutator
removePiece = defineCoordinates Nothing