module Solutions.RavnicaAllegiancePre2 where import Dovin.V2 solution :: GameMonad () solution :: GameMonad () solution = do String -> GameMonad () -> GameMonad () forall a. String -> GameMonad a -> GameMonad a step String "Initial Setup" (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 7 Location -> GameMonad () -> GameMonad () withLocation Location Play (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad () forall a b. (a -> b) -> a -> b $ do Int -> String -> GameMonad () addLands Int 3 String "Blood Crypt" Int -> String -> GameMonad () addLands Int 3 String "Overgrown Tomb" String -> GameMonad () -> GameMonad () withAttribute String flying (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad () forall a b. (a -> b) -> a -> b $ (Int, Int) -> String -> GameMonad () addCreature (Int 3, Int 3) String "Mausoleum Harpy" String -> GameMonad () -> GameMonad () withAttribute String defender (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad () forall a b. (a -> b) -> a -> b $ (Int, Int) -> String -> GameMonad () addCreature (Int 4, Int 3) String "Piston-Fist Cyclops" String -> GameMonad () -> GameMonad () withAttribute String defender (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad () forall a b. (a -> b) -> a -> b $ (Int, Int) -> String -> GameMonad () addCreature (Int 0, Int 2) String "Dragon Egg" String -> GameMonad () addEnchantment String "Rhythm of the Wild 1" String -> GameMonad () addEnchantment String "Rhythm of the Wild 2" Location -> GameMonad () -> GameMonad () withLocation Location Hand (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad () forall a b. (a -> b) -> a -> b $ do String -> GameMonad () addInstant String "Ancient Animus" (Int, Int) -> String -> GameMonad () addCreature (Int 2, Int 2) String "Growth-Chamber Guardian 1" Location -> GameMonad () -> GameMonad () withLocation Location Deck (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad () forall a b. (a -> b) -> a -> b $ do (Int, Int) -> String -> GameMonad () addCreature (Int 2, Int 2) String "Growth-Chamber Guardian 2" 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 () withAttribute String doublestrike (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad () forall a b. (a -> b) -> a -> b $ (Int, Int) -> String -> GameMonad () addCreature (Int 3, Int 3) String "Goring Ceratops" String -> GameMonad () -> GameMonad () withAttribute String firststrike (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad () forall a b. (a -> b) -> a -> b $ (Int, Int) -> String -> GameMonad () addCreature (Int 3, Int 3) String "Goblin Chainwhirler 1" String -> GameMonad () -> GameMonad () withAttribute String firststrike (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad () forall a b. (a -> b) -> a -> b $ (Int, Int) -> String -> GameMonad () addCreature (Int 3, Int 3) String "Goblin Chainwhirler 2" String -> GameMonad () -> GameMonad () forall a. String -> GameMonad a -> GameMonad a step String "Cast Guardian, get haste/+1 from Rhythm triggers" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad () forall a b. (a -> b) -> a -> b $ do String -> String -> GameMonad () tapForMana String "G" String "Overgrown Tomb 1" String -> String -> GameMonad () tapForMana String "R" String "Blood Crypt 1" String -> String -> GameMonad () cast String "1G" String "Growth-Chamber Guardian 1" GameMonad () -> GameMonad () -> GameMonad () forall (m :: * -> *) a b. Monad m => m a -> m b -> m b >> GameMonad () resolveTop String -> String -> GameMonad () trigger String "Haste" String "Rhythm of the Wild 1" String -> String -> GameMonad () trigger String "+1/+1" String "Rhythm of the Wild 2" GameMonad () resolveTop String -> ASetter Card Card Int Int -> (Int -> Int) -> GameMonad () forall a b. String -> ASetter Card Card a b -> (a -> b) -> GameMonad () modifyCardDeprecated String "Growth-Chamber Guardian 1" ASetter Card Card Int Int Lens' Card Int cardPlusOneCounters (Int -> Int -> Int forall a. Num a => a -> a -> a + Int 1) String -> String -> GameMonad () trigger String "Search" String "Growth-Chamber Guardian 1" GameMonad () resolveTop CardLocation -> CardLocation -> String -> GameMonad () move (Player Active, Location Deck) (Player Active, Location Hand) String "Growth-Chamber Guardian 2" GameMonad () resolveTop String -> String -> GameMonad () gainAttribute String haste String "Growth-Chamber Guardian 1" String -> GameMonad () -> GameMonad () forall a. String -> GameMonad a -> GameMonad a step String "Cast second Guardian, same haste/+1 combo (decline search)" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad () forall a b. (a -> b) -> a -> b $ do String -> String -> GameMonad () tapForMana String "G" String "Overgrown Tomb 2" String -> String -> GameMonad () tapForMana String "R" String "Blood Crypt 2" String -> String -> GameMonad () cast String "1G" String "Growth-Chamber Guardian 2" GameMonad () -> GameMonad () -> GameMonad () forall (m :: * -> *) a b. Monad m => m a -> m b -> m b >> GameMonad () resolveTop String -> String -> GameMonad () trigger String "Haste" String "Rhythm of the Wild 1" String -> String -> GameMonad () trigger String "+1/+1" String "Rhythm of the Wild 2" GameMonad () resolveTop String -> ASetter Card Card Int Int -> (Int -> Int) -> GameMonad () forall a b. String -> ASetter Card Card a b -> (a -> b) -> GameMonad () modifyCardDeprecated String "Growth-Chamber Guardian 2" ASetter Card Card Int Int Lens' Card Int cardPlusOneCounters (Int -> Int -> Int forall a. Num a => a -> a -> a + Int 1) String -> String -> GameMonad () trigger String "Search" String "Growth-Chamber Guardian 1" GameMonad () resolveTop GameMonad () resolveTop String -> String -> GameMonad () gainAttribute String haste String "Growth-Chamber Guardian 2" String -> GameMonad () -> GameMonad () forall a. String -> GameMonad a -> GameMonad a step String "Cast Animus on Egg. Enables Piston-Fist, triggers Harpy" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad () forall a b. (a -> b) -> a -> b $ do String -> String -> GameMonad () tapForMana String "G" String "Overgrown Tomb 3" String -> String -> GameMonad () tapForMana String "R" String "Blood Crypt 3" String -> String -> GameMonad () cast String "1G" String "Ancient Animus" GameMonad () -> GameMonad () -> GameMonad () forall (m :: * -> *) a b. Monad m => m a -> m b -> m b >> GameMonad () resolveTop String -> GameMonad () target String "Dragon Egg" String -> String -> GameMonad () loseAttribute String defender String "Piston-Fist Cyclops" String -> String -> GameMonad () fight String "Dragon Egg" String "Goring Ceratops" String -> String -> GameMonad () trigger String "Make Dragon" String "Dragon Egg" String -> String -> GameMonad () trigger String "+1/+1" String "Mausoleum Harpy" GameMonad () resolveHarpyTrigger GameMonad () resolveTop Location -> GameMonad () -> GameMonad () withLocation Location Play (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad () forall a b. (a -> b) -> a -> b $ do [String] -> GameMonad () -> GameMonad () withAttributes [String token, String flying, String summoned] (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad () forall a b. (a -> b) -> a -> b $ (Int, Int) -> String -> GameMonad () addCreature (Int 2, Int 2) String "Dragon" String -> GameMonad () -> GameMonad () forall a. String -> GameMonad a -> GameMonad a step String "Attack with all except dragon" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad () forall a b. (a -> b) -> a -> b $ do [String] -> GameMonad () attackWith [ String "Mausoleum Harpy" , String "Piston-Fist Cyclops" , String "Growth-Chamber Guardian 1" , String "Growth-Chamber Guardian 2" ] String -> GameMonad () -> GameMonad () fork String "Opponent doesn't block one ground attacker, damage is lethal" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad () forall a b. (a -> b) -> a -> b $ do String -> GameMonad () -> GameMonad () forall a. String -> GameMonad a -> GameMonad a step String "First-strike damage" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad () forall a b. (a -> b) -> a -> b $ do [String] -> String -> GameMonad () combatDamage [String "Goring Ceratops"] String "Piston-Fist Cyclops" [String] -> String -> GameMonad () combatDamage [String "Goblin Chainwhirler 1"] String "Growth-Chamber Guardian 1" String -> GameMonad () -> GameMonad () forall a. String -> GameMonad a -> GameMonad a step String "Death triggers for harpy" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad () forall a b. (a -> b) -> a -> b $ do String -> String -> GameMonad () trigger String "Cyclops" String "Mausoleum Harpy" String -> String -> GameMonad () trigger String "Guardian 1" String "Mausoleum Harpy" GameMonad () resolveTop GameMonad () -> GameMonad () -> GameMonad () forall (m :: * -> *) a b. Monad m => m a -> m b -> m b >> (Int, Int) -> String -> GameMonad () modifyStrength (Int 1, Int 1) String "Mausoleum Harpy" GameMonad () resolveTop GameMonad () -> GameMonad () -> GameMonad () forall (m :: * -> *) a b. Monad m => m a -> m b -> m b >> (Int, Int) -> String -> GameMonad () modifyStrength (Int 1, Int 1) String "Mausoleum Harpy" String -> GameMonad () -> GameMonad () forall a. String -> GameMonad a -> GameMonad a step String "Regular damage" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad () forall a b. (a -> b) -> a -> b $ do [String] -> String -> GameMonad () combatDamage [] String "Mausoleum Harpy" [String] -> String -> GameMonad () combatDamage [] String "Growth-Chamber Guardian 2" Int -> Player -> GameMonad () validateLife (-Int 2) Player Opponent String -> GameMonad () -> GameMonad () forall a. String -> GameMonad a -> GameMonad a step String "First-strike damage" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad () forall a b. (a -> b) -> a -> b $ do [String] -> String -> GameMonad () combatDamage [String "Goring Ceratops"] String "Piston-Fist Cyclops" [String] -> String -> GameMonad () combatDamage [String "Goblin Chainwhirler 1"] String "Growth-Chamber Guardian 1" [String] -> String -> GameMonad () combatDamage [String "Goblin Chainwhirler 2"] String "Growth-Chamber Guardian 2" String -> GameMonad () -> GameMonad () forall a. String -> GameMonad a -> GameMonad a step String "Death triggers for harpy" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad () forall a b. (a -> b) -> a -> b $ do String -> String -> GameMonad () trigger String "Cyclops" String "Mausoleum Harpy" String -> String -> GameMonad () trigger String "Guardian 1" String "Mausoleum Harpy" String -> String -> GameMonad () trigger String "Guardian 2" String "Mausoleum Harpy" GameMonad () resolveTop GameMonad () -> GameMonad () -> GameMonad () forall (m :: * -> *) a b. Monad m => m a -> m b -> m b >> (Int, Int) -> String -> GameMonad () modifyStrength (Int 1, Int 1) String "Mausoleum Harpy" GameMonad () resolveTop GameMonad () -> GameMonad () -> GameMonad () forall (m :: * -> *) a b. Monad m => m a -> m b -> m b >> (Int, Int) -> String -> GameMonad () modifyStrength (Int 1, Int 1) String "Mausoleum Harpy" GameMonad () resolveTop GameMonad () -> GameMonad () -> GameMonad () forall (m :: * -> *) a b. Monad m => m a -> m b -> m b >> (Int, Int) -> String -> GameMonad () modifyStrength (Int 1, Int 1) String "Mausoleum Harpy" String -> GameMonad () -> GameMonad () forall a. String -> GameMonad a -> GameMonad a step String "Regular damage" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad () forall a b. (a -> b) -> a -> b $ do [String] -> String -> GameMonad () combatDamage [] String "Mausoleum Harpy" Int -> Player -> GameMonad () validateLife Int 0 Player Opponent formatter :: Step -> Formatter formatter Step step = Formatter attributes Formatter -> Formatter -> Formatter forall a. Semigroup a => a -> a -> a <> 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 boardFormatter Int 5 -> String -> CardMatcher -> Formatter cardFormatter String "attacking creatures" (CardLocation -> CardMatcher matchLocation (Player Active, Location Play) CardMatcher -> CardMatcher -> CardMatcher forall a. Semigroup a => a -> a -> a <> String -> CardMatcher matchAttribute String attacking ) Int _ -> Formatter forall a. Monoid a => a mempty resolveHarpyTrigger :: GameMonad () resolveHarpyTrigger = do GameMonad () resolveTop String -> ASetter Card Card Int Int -> (Int -> Int) -> GameMonad () forall a b. String -> ASetter Card Card a b -> (a -> b) -> GameMonad () modifyCardDeprecated String "Mausoleum Harpy" ASetter Card Card Int Int Lens' Card Int cardPlusOneCounters (Int -> Int -> Int forall a. Num a => a -> a -> a + Int 1) 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 $ CardMatcher -> GameMonad Int countCards (CardMatcher -> GameMonad Int) -> CardMatcher -> GameMonad Int forall a b. (a -> b) -> a -> b $ String -> CardMatcher matchAttribute String land CardMatcher -> CardMatcher -> CardMatcher forall a. Semigroup a => a -> a -> a <> String -> CardMatcher missingAttribute String tapped String -> GameMonad CardStrength -> FormatMonad () forall a. Show a => String -> GameMonad a -> FormatMonad () attribute String "harpy" (GameMonad CardStrength -> FormatMonad ()) -> GameMonad CardStrength -> FormatMonad () forall a b. (a -> b) -> a -> b $ Getting CardStrength Card CardStrength -> Card -> CardStrength forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a view Getting CardStrength Card CardStrength Lens' Card CardStrength cardStrength (Card -> CardStrength) -> ExceptT String (ReaderT Env (StateT Board (WriterT [Step] Identity))) Card -> GameMonad CardStrength forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> String -> CardMatcher -> ExceptT String (ReaderT Env (StateT Board (WriterT [Step] Identity))) Card requireCard String "Mausoleum Harpy" CardMatcher forall a. Monoid a => a mempty blocked :: String blocked = String "blocked"