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