module Solutions.Dominaria5 where

import Dovin.V1
import Dovin.Prelude

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
8
    CardLocation -> GameMonad () -> GameMonad ()
withLocation (Player
Active, Location
Hand) (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
      Int -> String -> GameMonad ()
addPlaneswalker Int
5 String
"Karn, Scion of Urza 2"

    CardLocation -> GameMonad () -> GameMonad ()
withLocation (Player
Active, Location
Play) (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
      Int -> String -> GameMonad ()
addPlaneswalker Int
2 String
"Karn, Scion of Urza 1"
      (Int, Int) -> String -> GameMonad ()
addCreature (Int
3, Int
3) String
"Weldfast Wingsmith"
      String -> GameMonad () -> GameMonad ()
withAttribute String
doublestrike (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$
        (Int, Int) -> String -> GameMonad ()
addCreature (Int
2, Int
2) String
"Storm Fleet Swashbuckler"
      (Int, Int) -> String -> GameMonad ()
addCreature (Int
1, Int
3) String
"Reckless Fireweaver"

      Int -> String -> GameMonad ()
addLands Int
3 String
"Sulfur Falls"
      Int -> String -> GameMonad ()
addLands Int
3 String
"Canyon Slough"

    CardLocation -> GameMonad () -> GameMonad ()
withLocation (Player
Active, Location
Exile) (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
      String -> GameMonad ()
addInstant String
"Fatal Push"
      String -> GameMonad ()
addSorcery String
"Mutiny"

    CardLocation -> GameMonad () -> GameMonad ()
withLocation (Player
Opponent, Location
Play) (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
      (Int, Int) -> String -> GameMonad ()
addCreature (Int
2, Int
3) String
"Aerial Responder 1"
      (Int, Int) -> String -> GameMonad ()
addCreature (Int
2, Int
3) String
"Aerial Responder 2"
      (Int, Int) -> String -> GameMonad ()
addCreature (Int
5, Int
5) String
"Bonded Horncrest"

  String -> GameMonad () -> GameMonad ()
forall a. String -> GameMonad a -> GameMonad a
step String
"Activate Karn to return Mutiny" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
    String -> Int -> String -> GameMonad ()
activatePlaneswalker String
"Get card" (-Int
1) String
"Karn, Scion of Urza 1" GameMonad () -> GameMonad () -> GameMonad ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> GameMonad ()
resolveTop
    Location -> String -> GameMonad ()
moveTo Location
Hand String
"Mutiny"

  String -> GameMonad () -> GameMonad ()
forall a. String -> GameMonad a -> GameMonad a
step String
"Cast Mutiny, using Horncrest to destroy a Responder" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
    String -> String -> GameMonad ()
tapForMana String
"R" String
"Sulfur Falls 1"
    String -> String -> GameMonad ()
cast String
"R" String
"Mutiny" GameMonad () -> GameMonad () -> GameMonad ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> GameMonad ()
resolveTop
    String -> GameMonad ()
target String
"Bonded Horncrest"
    String -> GameMonad ()
target String
"Aerial Responder 1"
    (Card -> Int) -> Target -> String -> GameMonad ()
damage (Getting Int Card Int -> Card -> Int
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Int Card Int
Lens' Card Int
cardPower) (String -> Target
targetCard String
"Aerial Responder 1") String
"Bonded Horncrest"

  String -> GameMonad () -> GameMonad ()
forall a. String -> GameMonad a -> GameMonad a
step String
"Cast Karn, using legend rule to remove the existing one" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
    String -> String -> GameMonad ()
tapForMana String
"U" String
"Sulfur Falls 2"
    String -> String -> GameMonad ()
tapForMana String
"U" String
"Sulfur Falls 3"
    String -> String -> GameMonad ()
tapForMana String
"B" String
"Canyon Slough 1"
    String -> String -> GameMonad ()
tapForMana String
"B" String
"Canyon Slough 2"
    String -> String -> GameMonad ()
cast String
"4" String
"Karn, Scion of Urza 2" GameMonad () -> GameMonad () -> GameMonad ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> GameMonad ()
resolveTop
    Location -> String -> GameMonad ()
moveTo Location
Graveyard String
"Karn, Scion of Urza 1"

  String -> GameMonad () -> GameMonad ()
forall a. String -> GameMonad a -> GameMonad a
step String
"Activate Karn to return Fatal Push" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
    String -> Int -> String -> GameMonad ()
activatePlaneswalker String
"Get card" (-Int
1) String
"Karn, Scion of Urza 2" GameMonad () -> GameMonad () -> GameMonad ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> GameMonad ()
resolveTop
    Location -> String -> GameMonad ()
moveTo Location
Hand String
"Fatal Push"

  String -> GameMonad () -> GameMonad ()
forall a. String -> GameMonad a -> GameMonad a
step String
"Cast Fatal Push destroying remaining Responder with Revolt from first Karn" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
    String -> String -> GameMonad ()
tapForMana String
"B" String
"Canyon Slough 3"
    String -> String -> GameMonad ()
cast String
"B" String
"Fatal Push" GameMonad () -> GameMonad () -> GameMonad ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> GameMonad ()
resolveTop
    String -> GameMonad ()
target String
"Aerial Responder 2"
    String -> GameMonad ()
destroy String
"Aerial Responder 2"

  String -> GameMonad () -> GameMonad ()
forall a. String -> GameMonad a -> GameMonad a
step String
"Attack with all for lethal, since Horncrest can't block alone" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
    String -> CardMatcher -> GameMonad ()
validate String
"Aerial Responder 1" (CardMatcher -> GameMonad ()) -> CardMatcher -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ CardMatcher -> CardMatcher
invert CardMatcher
matchInPlay
    String -> CardMatcher -> GameMonad ()
validate String
"Aerial Responder 2" (CardMatcher -> GameMonad ()) -> CardMatcher -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ CardMatcher -> CardMatcher
invert CardMatcher
matchInPlay

    [String] -> GameMonad ()
attackWith
      [ String
"Weldfast Wingsmith"
      , String
"Storm Fleet Swashbuckler"
      , String
"Reckless Fireweaver"
      ]

    CardMatcher -> (String -> GameMonad ()) -> GameMonad ()
forCards
      ([String] -> CardMatcher
matchAttributes [String
attacking, String
doublestrike])
      ([String] -> String -> GameMonad ()
combatDamage [])

    CardMatcher -> (String -> GameMonad ()) -> GameMonad ()
forCards
      ([String] -> CardMatcher
matchAttributes [String
attacking])
      ([String] -> String -> GameMonad ()
combatDamage [])

    Player -> Int -> GameMonad ()
validateLife Player
Opponent Int
0

attributes :: Formatter
attributes = 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
"life" (GameMonad Int -> FormatMonad ())
-> GameMonad Int -> FormatMonad ()
forall a b. (a -> b) -> a -> b
$ Player -> GameMonad Int
countLife Player
Opponent
  String -> GameMonad Int -> FormatMonad ()
forall a. Show a => String -> GameMonad a -> FormatMonad ()
attribute String
"mana" (GameMonad Int -> FormatMonad ())
-> GameMonad Int -> FormatMonad ()
forall a b. (a -> b) -> a -> b
$
    Int -> Int -> Int
forall a. Num a => a -> a -> a
(+) (Int -> Int -> Int)
-> GameMonad Int
-> ExceptT
     String
     (ReaderT Env (StateT Board (WriterT [Step] Identity)))
     (Int -> Int)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f 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"
              CardMatcher -> CardMatcher -> CardMatcher
forall a. Semigroup a => a -> a -> a
<> Player -> CardMatcher
matchController Player
Active
              )
        ExceptT
  String
  (ReaderT Env (StateT Board (WriterT [Step] Identity)))
  (Int -> Int)
-> GameMonad Int -> GameMonad Int
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Player -> GameMonad Int
countManaPool Player
Active
formatter :: a -> Formatter
formatter a
1 = Formatter
boardFormatter
formatter a
3 = Formatter
attributes
  Formatter -> Formatter -> Formatter
forall a. Semigroup a => a -> a -> a
<> String -> CardMatcher -> Formatter
cardFormatter
       String
"remaining creatures"
       (CardLocation -> CardMatcher
matchLocation (Player
Opponent, Location
Play) CardMatcher -> CardMatcher -> CardMatcher
forall a. Semigroup a => a -> a -> a
<> String -> CardMatcher
matchAttribute String
creature)
formatter a
6 = Formatter
attributes
  Formatter -> Formatter -> Formatter
forall a. Semigroup a => a -> a -> a
<> String -> CardMatcher -> Formatter
cardFormatter
       String
"remaining creatures"
       (CardLocation -> CardMatcher
matchLocation (Player
Opponent, Location
Play) CardMatcher -> CardMatcher -> CardMatcher
forall a. Semigroup a => a -> a -> a
<> String -> CardMatcher
matchAttribute String
creature)
formatter a
7 = Formatter
attributes
  Formatter -> Formatter -> Formatter
forall a. Semigroup a => a -> a -> a
<> String -> CardMatcher -> Formatter
cardFormatter
      String
"unblocked creatures"
      (CardLocation -> CardMatcher
matchLocation (Player
Active, Location
Play)
      CardMatcher -> CardMatcher -> CardMatcher
forall a. Semigroup a => a -> a -> a
<> String -> CardMatcher
matchAttribute String
creature
      CardMatcher -> CardMatcher -> CardMatcher
forall a. Semigroup a => a -> a -> a
<> CardMatcher -> CardMatcher
invert (String -> CardMatcher
matchAttribute String
"blocked")
      )
formatter a
_ = Formatter
attributes