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"