module Solutions.Example where

import Dovin

solution :: GameMonad ()
solution :: GameMonad ()
solution = do
  String -> GameMonad () -> GameMonad ()
forall a. String -> GameMonad a -> GameMonad a
step String
"Initial state" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
    Player -> GameMonad () -> GameMonad ()
as Player
Opponent (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ Int -> GameMonad ()
setLife Int
3

    Location -> GameMonad () -> GameMonad ()
withLocation Location
Hand (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ String -> GameMonad ()
addInstant String
"Plummet"
    Location -> GameMonad () -> GameMonad ()
withLocation Location
Play (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
      Int -> String -> GameMonad ()
addLands Int
2 String
"Forest"

    Player -> GameMonad () -> GameMonad ()
as Player
Opponent (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
      Location -> GameMonad () -> GameMonad ()
withLocation Location
Play (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
        [String] -> GameMonad () -> GameMonad ()
withAttributes [String
flying, String
token] (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ (Int, Int) -> String -> GameMonad ()
addCreature (Int
4, Int
4) String
"Angel"
        [String] -> GameMonad () -> GameMonad ()
withAttributes [String
flying]
          (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ EffectMonad CardMatcher
-> [LayeredEffectPart] -> String -> GameMonad () -> GameMonad ()
withEffect
              (Card -> CardMatcher
matchOtherCreatures (Card -> CardMatcher)
-> ReaderT EffectMonadEnv Identity Card -> EffectMonad CardMatcher
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReaderT EffectMonadEnv Identity Card
askSelf)
              [ String -> LayeredEffectPart
effectAddAbility String
hexproof
              ]
              String
"Other creatures gain hexproof"
          (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ (Int, Int) -> String -> GameMonad ()
addCreature (Int
3, Int
4) String
"Shalai, Voice of Plenty"

  String -> GameMonad () -> GameMonad ()
forall a. String -> GameMonad a -> GameMonad a
step String
"Plummet to destroy Shalai" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
    String -> String -> GameMonad ()
tapForMana String
"G" (Int -> String -> String
numbered Int
1 String
"Forest")
    String -> String -> GameMonad ()
tapForMana String
"G" (Int -> String -> String
numbered Int
2 String
"Forest")
    String -> String -> GameMonad ()
cast String
"1G" String
"Plummet"
    String -> GameMonad ()
resolve String
"Plummet"
    String -> (String -> GameMonad ()) -> GameMonad ()
with String
"Shalai, Voice of Plenty" ((String -> GameMonad ()) -> GameMonad ())
-> (String -> GameMonad ()) -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ \String
enemy -> do
      String -> GameMonad ()
target String
enemy
      CardMatcher -> String -> GameMonad ()
validate (String -> CardMatcher
matchAttribute String
flying) String
enemy
      String -> GameMonad ()
destroy String
enemy

formatter :: Step -> Formatter
formatter :: Step -> Formatter
formatter Step
step = case Getting Int Step Int -> Step -> Int
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Int Step Int
Lens' Step Int
stepNumber Step
step of
  Int
1 -> Formatter
manaFormatter
    Formatter -> Formatter -> Formatter
forall a. Semigroup a => a -> a -> a
<> String -> CardMatcher -> Formatter
cardFormatter String
"opponent creatures" (CardLocation -> CardMatcher
matchLocation (Player
Opponent, Location
Play))
  Int
_ -> Formatter
boardFormatter

manaFormatter :: Formatter
manaFormatter = FormatMonad () -> Formatter
attributeFormatter (FormatMonad () -> Formatter) -> FormatMonad () -> Formatter
forall a b. (a -> b) -> a -> b
$ do
  String -> GameMonad Int -> FormatMonad ()
forall a. Show a => String -> GameMonad a -> FormatMonad ()
attribute String
"availble mana" (GameMonad Int -> FormatMonad ())
-> GameMonad Int -> FormatMonad ()
forall a b. (a -> b) -> a -> b
$
    CardMatcher -> GameMonad Int
countCards (String -> CardMatcher
matchAttribute String
land CardMatcher -> CardMatcher -> CardMatcher
forall a. Semigroup a => a -> a -> a
<> String -> CardMatcher
missingAttribute String
tapped)