{-|
Functions for adding new cards to the board.

> withLocation Hand $ do
>   withAttributes ["angel", token] $ addCreature (4, 4) "Angel"
-}
module Dovin.Builder (
  -- * Builders
  -- | Each of these terminates a build chain, and will add a card with the
  -- specified type to the board.
    addCard
  , addAura
  , addArtifact
  , addCreature
  , addEnchantment
  , addInstant
  , addLand
  , addLands
  , addPlaneswalker
  , addSorcery
  -- * Fluid interface
  -- | These methods can be chained together to specify different properties of
  -- the card to be created.
  , as
  , withAttribute
  , withAttributes
  , withCMC
  , withEffect
  , withEffectWhen
  , withLocation
  , withOwner
  , withPlusOneCounters
  , withMinusOneCounters
  ) where

import Dovin.Attributes
import Dovin.Prelude
import Dovin.Types
import Dovin.Helpers (getTimestamp)
import Dovin.Matchers (matchNone)
import Dovin.Effects (resolveEffects, enabledInPlay)

import Control.Monad.Reader (local)
import Control.Lens (_1)
import qualified Data.HashMap.Strict as M
import qualified Data.Set as S

addCard :: CardName -> GameMonad ()
addCard :: CardName -> GameMonad ()
addCard CardName
name = do
  Maybe BaseCard
card <- Getting (Maybe BaseCard) Board (Maybe BaseCard)
-> ExceptT
     CardName
     (ReaderT Env (StateT Board (WriterT [Step] Identity)))
     (Maybe BaseCard)
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use (Getting (Maybe BaseCard) Board (Maybe BaseCard)
 -> ExceptT
      CardName
      (ReaderT Env (StateT Board (WriterT [Step] Identity)))
      (Maybe BaseCard))
-> Getting (Maybe BaseCard) Board (Maybe BaseCard)
-> ExceptT
     CardName
     (ReaderT Env (StateT Board (WriterT [Step] Identity)))
     (Maybe BaseCard)
forall a b. (a -> b) -> a -> b
$ (HashMap CardName BaseCard
 -> Const (Maybe BaseCard) (HashMap CardName BaseCard))
-> Board -> Const (Maybe BaseCard) Board
Lens' Board (HashMap CardName BaseCard)
cards ((HashMap CardName BaseCard
  -> Const (Maybe BaseCard) (HashMap CardName BaseCard))
 -> Board -> Const (Maybe BaseCard) Board)
-> ((Maybe BaseCard -> Const (Maybe BaseCard) (Maybe BaseCard))
    -> HashMap CardName BaseCard
    -> Const (Maybe BaseCard) (HashMap CardName BaseCard))
-> Getting (Maybe BaseCard) Board (Maybe BaseCard)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Index (HashMap CardName BaseCard)
-> Lens'
     (HashMap CardName BaseCard)
     (Maybe (IxValue (HashMap CardName BaseCard)))
forall m. At m => Index m -> Lens' m (Maybe (IxValue m))
at CardName
Index (HashMap CardName BaseCard)
name
  Timestamp
now <- GameMonad Timestamp
getTimestamp

  case Maybe BaseCard
card of
    Just BaseCard
_ -> CardName -> GameMonad ()
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (CardName -> GameMonad ()) -> CardName -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ CardName
"Card should be removed: " CardName -> CardName -> CardName
forall a. Semigroup a => a -> a -> a
<> CardName
name
    Maybe BaseCard
Nothing -> do
      Card
template <- Getting Card Env Card
-> ExceptT
     CardName
     (ReaderT Env (StateT Board (WriterT [Step] Identity)))
     Card
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Card Env Card
Lens' Env Card
envTemplate
      Maybe Player
owner <- Getting (Maybe Player) Env (Maybe Player)
-> ExceptT
     CardName
     (ReaderT Env (StateT Board (WriterT [Step] Identity)))
     (Maybe Player)
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting (Maybe Player) Env (Maybe Player)
Lens' Env (Maybe Player)
envOwner
      ASetter
  Board Board (HashMap CardName BaseCard) (HashMap CardName BaseCard)
-> (HashMap CardName BaseCard -> HashMap CardName BaseCard)
-> GameMonad ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> (a -> b) -> m ()
modifying ASetter
  Board Board (HashMap CardName BaseCard) (HashMap CardName BaseCard)
Lens' Board (HashMap CardName BaseCard)
cards (CardName
-> BaseCard
-> HashMap CardName BaseCard
-> HashMap CardName BaseCard
forall k v.
(Eq k, Hashable k) =>
k -> v -> HashMap k v -> HashMap k v
M.insert CardName
name (Card -> BaseCard
BaseCard
        (Card -> BaseCard) -> Card -> BaseCard
forall a b. (a -> b) -> a -> b
$ ASetter Card Card CardName CardName -> CardName -> Card -> Card
forall s t a b. ASetter s t a b -> b -> s -> t
set ASetter Card Card CardName CardName
Lens' Card CardName
cardName CardName
name
        (Card -> Card) -> (Card -> Card) -> Card -> Card
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASetter Card Card Timestamp Timestamp -> Timestamp -> Card -> Card
forall s t a b. ASetter s t a b -> b -> s -> t
set ASetter Card Card Timestamp Timestamp
Lens' Card Timestamp
cardTimestamp Timestamp
now
        (Card -> Card) -> (Card -> Card) -> Card -> Card
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASetter Card Card Player Player -> Player -> Card -> Card
forall s t a b. ASetter s t a b -> b -> s -> t
set ASetter Card Card Player Player
Lens' Card Player
cardOwner (Player -> (Player -> Player) -> Maybe Player -> Player
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Getting Player Card Player -> Card -> Player
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view (((Player, Location) -> Const Player (Player, Location))
-> Card -> Const Player Card
Lens' Card (Player, Location)
cardLocation (((Player, Location) -> Const Player (Player, Location))
 -> Card -> Const Player Card)
-> ((Player -> Const Player Player)
    -> (Player, Location) -> Const Player (Player, Location))
-> Getting Player Card Player
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Player -> Const Player Player)
-> (Player, Location) -> Const Player (Player, Location)
forall s t a b. Field1 s t a b => Lens s t a b
_1) Card
template) Player -> Player
forall a. a -> a
id Maybe Player
owner)
        (Card -> Card) -> Card -> Card
forall a b. (a -> b) -> a -> b
$ Card
template))
      GameMonad ()
resolveEffects

addAura :: CardName -> GameMonad ()
addAura :: CardName -> GameMonad ()
addAura CardName
name = CardName -> GameMonad () -> GameMonad ()
withAttribute CardName
aura (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ CardName -> GameMonad ()
addEnchantment CardName
name

addArtifact :: CardName -> GameMonad ()
addArtifact :: CardName -> GameMonad ()
addArtifact CardName
name = CardName -> GameMonad () -> GameMonad ()
withAttribute CardName
artifact (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ CardName -> GameMonad ()
addEnchantment CardName
name

addCreature :: (Int, Int) -> CardName -> GameMonad ()
addCreature :: (Int, Int) -> CardName -> GameMonad ()
addCreature (Int, Int)
strength CardName
name = (Env -> Env) -> GameMonad () -> GameMonad ()
forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
local (ASetter Env Env CardStrength CardStrength
-> CardStrength -> Env -> Env
forall s t a b. ASetter s t a b -> b -> s -> t
set ((Card -> Identity Card) -> Env -> Identity Env
Lens' Env Card
envTemplate ((Card -> Identity Card) -> Env -> Identity Env)
-> ((CardStrength -> Identity CardStrength)
    -> Card -> Identity Card)
-> ASetter Env Env CardStrength CardStrength
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (CardStrength -> Identity CardStrength) -> Card -> Identity Card
Lens' Card CardStrength
cardStrength) (CardStrength -> Env -> Env) -> CardStrength -> Env -> Env
forall a b. (a -> b) -> a -> b
$ (Int, Int) -> CardStrength
mkStrength (Int, Int)
strength)
  (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ CardName -> GameMonad () -> GameMonad ()
withAttribute CardName
creature
  (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ CardName -> GameMonad ()
addCard CardName
name

addPlaneswalker :: Int -> CardName -> GameMonad ()
addPlaneswalker :: Int -> CardName -> GameMonad ()
addPlaneswalker Int
loyalty CardName
name = (Env -> Env) -> GameMonad () -> GameMonad ()
forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
local (ASetter Env Env Int Int -> Int -> Env -> Env
forall s t a b. ASetter s t a b -> b -> s -> t
set ((Card -> Identity Card) -> Env -> Identity Env
Lens' Env Card
envTemplate ((Card -> Identity Card) -> Env -> Identity Env)
-> ((Int -> Identity Int) -> Card -> Identity Card)
-> ASetter Env Env Int Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> Identity Int) -> Card -> Identity Card
Lens' Card Int
cardLoyalty) Int
loyalty)
  (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ CardName -> GameMonad () -> GameMonad ()
withAttribute CardName
planeswalker
  (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ CardName -> GameMonad ()
addCard CardName
name

addEnchantment :: CardName -> GameMonad ()
addEnchantment :: CardName -> GameMonad ()
addEnchantment CardName
name = CardName -> GameMonad () -> GameMonad ()
withAttribute CardName
enchantment (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ CardName -> GameMonad ()
addCard CardName
name

addInstant :: CardName -> GameMonad ()
addInstant :: CardName -> GameMonad ()
addInstant CardName
name = CardName -> GameMonad () -> GameMonad ()
withAttribute CardName
instant (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ CardName -> GameMonad ()
addCard CardName
name

addLand :: CardName -> GameMonad ()
addLand :: CardName -> GameMonad ()
addLand CardName
name = CardName -> GameMonad () -> GameMonad ()
withAttribute CardName
land (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ CardName -> GameMonad ()
addCard CardName
name

addLands :: Int -> CardName -> GameMonad ()
addLands :: Int -> CardName -> GameMonad ()
addLands Int
n CardName
name = CardName -> GameMonad () -> GameMonad ()
withAttribute CardName
land (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$
  [Int] -> (Int -> GameMonad ()) -> GameMonad ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [Int
1..Int
n] ((Int -> GameMonad ()) -> GameMonad ())
-> (Int -> GameMonad ()) -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ \Int
n -> CardName -> GameMonad ()
addCard (Int -> CardName -> CardName
numbered Int
n CardName
name)

addSorcery :: CardName -> GameMonad ()
addSorcery :: CardName -> GameMonad ()
addSorcery CardName
name = CardName -> GameMonad () -> GameMonad ()
withAttribute CardName
sorcery (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ CardName -> GameMonad ()
addCard CardName
name

-- | Perform action as the specified player.
as :: Player -> GameMonad () -> GameMonad ()
as :: Player -> GameMonad () -> GameMonad ()
as Player
player = (Env -> Env) -> GameMonad () -> GameMonad ()
forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
local (ASetter Env Env Player Player -> Player -> Env -> Env
forall s t a b. ASetter s t a b -> b -> s -> t
set ASetter Env Env Player Player
Lens' Env Player
envActor Player
player)

-- | Add an attribute to the created card, as identified by a string.
-- Attributes with that special meaning to Dovin built-ins (such as flying) are
-- defined in "Dovin.Attributes".
withAttribute :: String -> GameMonad () -> GameMonad ()
withAttribute :: CardName -> GameMonad () -> GameMonad ()
withAttribute CardName
attr = [CardName] -> GameMonad () -> GameMonad ()
withAttributes [CardName
attr]

-- | Helper version of 'withAttribute' for adding multiple attributes at a
-- time.
withAttributes :: [String] -> GameMonad () -> GameMonad ()
withAttributes :: [CardName] -> GameMonad () -> GameMonad ()
withAttributes [CardName]
attrs =
  let f :: Set CardName -> Set CardName
f = Set CardName -> Set CardName -> Set CardName
forall a. Ord a => Set a -> Set a -> Set a
S.union (Set CardName -> Set CardName -> Set CardName)
-> ([CardName] -> Set CardName)
-> [CardName]
-> Set CardName
-> Set CardName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [CardName] -> Set CardName
forall a. Ord a => [a] -> Set a
S.fromList ([CardName] -> Set CardName -> Set CardName)
-> [CardName] -> Set CardName -> Set CardName
forall a b. (a -> b) -> a -> b
$ [CardName]
attrs in
  (Env -> Env) -> GameMonad () -> GameMonad ()
forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
local (ASetter Env Env (Set CardName) (Set CardName)
-> (Set CardName -> Set CardName) -> Env -> Env
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over ((Card -> Identity Card) -> Env -> Identity Env
Lens' Env Card
envTemplate ((Card -> Identity Card) -> Env -> Identity Env)
-> ((Set CardName -> Identity (Set CardName))
    -> Card -> Identity Card)
-> ASetter Env Env (Set CardName) (Set CardName)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Set CardName -> Identity (Set CardName)) -> Card -> Identity Card
Lens' Card (Set CardName)
cardAttributes) Set CardName -> Set CardName
f
       (Env -> Env) -> (Env -> Env) -> Env -> Env
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASetter Env Env (Set CardName) (Set CardName)
-> (Set CardName -> Set CardName) -> Env -> Env
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over ((Card -> Identity Card) -> Env -> Identity Env
Lens' Env Card
envTemplate ((Card -> Identity Card) -> Env -> Identity Env)
-> ((Set CardName -> Identity (Set CardName))
    -> Card -> Identity Card)
-> ASetter Env Env (Set CardName) (Set CardName)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Set CardName -> Identity (Set CardName)) -> Card -> Identity Card
Lens' Card (Set CardName)
cardDefaultAttributes) Set CardName -> Set CardName
f)

-- | Add an effect to the created card. The effect will only apply when the
-- card is in play.
withEffect ::
    EffectMonad CardMatcher -- ^ The set of cards to apply the effect to
 -> [LayeredEffectPart]     -- ^ The effect to apply
 -> EffectName              -- ^ Human-readable description, cosmetic only.
 -> GameMonad ()
 -> GameMonad ()
withEffect :: EffectMonad CardMatcher
-> [LayeredEffectPart] -> CardName -> GameMonad () -> GameMonad ()
withEffect = EffectMonad Bool
-> EffectMonad CardMatcher
-> [LayeredEffectPart]
-> CardName
-> GameMonad ()
-> GameMonad ()
withEffectWhen EffectMonad Bool
enabledInPlay

-- | A more flexible version of 'withEffect' that allows customization of then
-- the effect should apply.
withEffectWhen ::
    EffectMonad Bool        -- ^ Effect only applies when this returns true
 -> EffectMonad CardMatcher -- ^ The set of cards to apply the effect to
 -> [LayeredEffectPart]     -- ^ The effect to apply
 -> EffectName              -- ^ Human-readable description, cosmetic only.
 -> GameMonad ()
 -> GameMonad ()
withEffectWhen :: EffectMonad Bool
-> EffectMonad CardMatcher
-> [LayeredEffectPart]
-> CardName
-> GameMonad ()
-> GameMonad ()
withEffectWhen EffectMonad Bool
enabled EffectMonad CardMatcher
appliesTo [LayeredEffectPart]
effect CardName
name =
  (Env -> Env) -> GameMonad () -> GameMonad ()
forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
local (ASetter Env Env [LayeredEffectDefinition] [LayeredEffectDefinition]
-> ([LayeredEffectDefinition] -> [LayeredEffectDefinition])
-> Env
-> Env
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over ((Card -> Identity Card) -> Env -> Identity Env
Lens' Env Card
envTemplate ((Card -> Identity Card) -> Env -> Identity Env)
-> (([LayeredEffectDefinition]
     -> Identity [LayeredEffectDefinition])
    -> Card -> Identity Card)
-> ASetter
     Env Env [LayeredEffectDefinition] [LayeredEffectDefinition]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([LayeredEffectDefinition] -> Identity [LayeredEffectDefinition])
-> Card -> Identity Card
Lens' Card [LayeredEffectDefinition]
cardPassiveEffects)
  (EffectMonad CardMatcher
-> [LayeredEffectPart] -> CardName -> LayeredEffectDefinition
mkLayeredEffectPart EffectMonad CardMatcher
combinedMatcher [LayeredEffectPart]
effect CardName
nameLayeredEffectDefinition
-> [LayeredEffectDefinition] -> [LayeredEffectDefinition]
forall a. a -> [a] -> [a]
:))

  where
    combinedMatcher :: EffectMonad CardMatcher
    combinedMatcher :: EffectMonad CardMatcher
combinedMatcher = do
      Bool
isEnabled <- EffectMonad Bool
enabled

      if Bool
isEnabled then
        EffectMonad CardMatcher
appliesTo
      else
        CardMatcher -> EffectMonad CardMatcher
forall (m :: * -> *) a. Monad m => a -> m a
return CardMatcher
matchNone

-- | Set the converted mana cost of the created card.
withCMC :: Int -> GameMonad () -> GameMonad ()
withCMC :: Int -> GameMonad () -> GameMonad ()
withCMC Int
n =
  (Env -> Env) -> GameMonad () -> GameMonad ()
forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
local (ASetter Env Env Int Int -> Int -> Env -> Env
forall s t a b. ASetter s t a b -> b -> s -> t
set ((Card -> Identity Card) -> Env -> Identity Env
Lens' Env Card
envTemplate ((Card -> Identity Card) -> Env -> Identity Env)
-> ((Int -> Identity Int) -> Card -> Identity Card)
-> ASetter Env Env Int Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> Identity Int) -> Card -> Identity Card
Lens' Card Int
cardCmc) Int
n)

-- | Place the created card into a specific location.
withLocation :: Location -> GameMonad () -> GameMonad ()
withLocation :: Location -> GameMonad () -> GameMonad ()
withLocation Location
loc GameMonad ()
m = do
  Player
p <- Getting Player Env Player
-> ExceptT
     CardName
     (ReaderT Env (StateT Board (WriterT [Step] Identity)))
     Player
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Player Env Player
Lens' Env Player
envActor

  (Env -> Env) -> GameMonad () -> GameMonad ()
forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
local (ASetter Env Env (Player, Location) (Player, Location)
-> (Player, Location) -> Env -> Env
forall s t a b. ASetter s t a b -> b -> s -> t
set ((Card -> Identity Card) -> Env -> Identity Env
Lens' Env Card
envTemplate ((Card -> Identity Card) -> Env -> Identity Env)
-> (((Player, Location) -> Identity (Player, Location))
    -> Card -> Identity Card)
-> ASetter Env Env (Player, Location) (Player, Location)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Player, Location) -> Identity (Player, Location))
-> Card -> Identity Card
Lens' Card (Player, Location)
cardLocation) (Player
p, Location
loc)) GameMonad ()
m

-- | Set the owner for the created card. If not specified, defaults to the
-- owner of the card location.
withOwner :: Player -> GameMonad () -> GameMonad ()
withOwner :: Player -> GameMonad () -> GameMonad ()
withOwner Player
owner = (Env -> Env) -> GameMonad () -> GameMonad ()
forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
local (ASetter Env Env (Maybe Player) (Maybe Player)
-> Maybe Player -> Env -> Env
forall s t a b. ASetter s t a b -> b -> s -> t
set ASetter Env Env (Maybe Player) (Maybe Player)
Lens' Env (Maybe Player)
envOwner (Player -> Maybe Player
forall a. a -> Maybe a
Just Player
owner))

-- | Set the number of +1/+1 counters of the created card.
withPlusOneCounters :: Int -> GameMonad () -> GameMonad ()
withPlusOneCounters :: Int -> GameMonad () -> GameMonad ()
withPlusOneCounters = (Env -> Env) -> GameMonad () -> GameMonad ()
forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
local ((Env -> Env) -> GameMonad () -> GameMonad ())
-> (Int -> Env -> Env) -> Int -> GameMonad () -> GameMonad ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASetter Env Env Int Int -> Int -> Env -> Env
forall s t a b. ASetter s t a b -> b -> s -> t
set ((Card -> Identity Card) -> Env -> Identity Env
Lens' Env Card
envTemplate ((Card -> Identity Card) -> Env -> Identity Env)
-> ((Int -> Identity Int) -> Card -> Identity Card)
-> ASetter Env Env Int Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> Identity Int) -> Card -> Identity Card
Lens' Card Int
cardPlusOneCounters)

-- | Set the number of -1/-1 counters of the created card.
withMinusOneCounters :: Int -> GameMonad () -> GameMonad ()
withMinusOneCounters :: Int -> GameMonad () -> GameMonad ()
withMinusOneCounters = (Env -> Env) -> GameMonad () -> GameMonad ()
forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
local ((Env -> Env) -> GameMonad () -> GameMonad ())
-> (Int -> Env -> Env) -> Int -> GameMonad () -> GameMonad ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASetter Env Env Int Int -> Int -> Env -> Env
forall s t a b. ASetter s t a b -> b -> s -> t
set ((Card -> Identity Card) -> Env -> Identity Env
Lens' Env Card
envTemplate ((Card -> Identity Card) -> Env -> Identity Env)
-> ((Int -> Identity Int) -> Card -> Identity Card)
-> ASetter Env Env Int Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> Identity Int) -> Card -> Identity Card
Lens' Card Int
cardMinusOneCounters)