module Solutions.RavnicaAllegiance3 where

import Dovin.V2
import Dovin.Prelude

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
15

    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
"Godless Shrine"
      Int -> String -> GameMonad ()
addLands Int
2 String
"Stomping Ground"
      (Int, Int) -> String -> GameMonad ()
addCreature (Int
1, Int
1) String
"Elenda, the Dusk Rose"
      String -> GameMonad () -> GameMonad ()
withAttribute String
legendary
        (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ CardMatcher
-> (Card -> CardMatcher)
-> (Card -> Identity Card)
-> GameMonad ()
-> GameMonad ()
withEffect
           CardMatcher
matchInPlay
           (Card -> CardMatcher
matchOtherCreatures (Card -> CardMatcher)
-> (Card -> CardMatcher) -> Card -> CardMatcher
forall a. Semigroup a => a -> a -> a
<> CardMatcher -> Card -> CardMatcher
forall a b. a -> b -> a
const (String -> CardMatcher
matchAttribute String
token))
           (Card -> Identity Card
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Card -> Identity Card) -> (Card -> Card) -> Card -> Identity Card
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Card -> Card
setAttribute String
vigilance (Card -> Card) -> (Card -> Card) -> Card -> Card
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Card -> Card
setAttribute String
lifelink)
        (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ (Int, Int) -> String -> GameMonad ()
addCreature (Int
2, Int
4) String
"Teysa Karlov"
      (Int, Int) -> String -> GameMonad ()
addCreature (Int
2, Int
2) String
"Pitiless Pontiff"
      String -> GameMonad () -> GameMonad ()
withAttribute String
defender (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ (Int, Int) -> String -> GameMonad ()
addCreature (Int
2, Int
3) String
"Novice Knight"
      String -> GameMonad () -> GameMonad ()
withAttribute String
legendary
        (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ CardMatcher
-> (Card -> CardMatcher)
-> (Card -> Identity Card)
-> GameMonad ()
-> GameMonad ()
withEffect
            CardMatcher
matchInPlay
            Card -> CardMatcher
matchOtherCreatures
            (Card -> Identity Card
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Card -> Identity Card) -> (Card -> Card) -> Card -> Identity Card
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASetter Card Card CardStrength CardStrength
-> (CardStrength -> CardStrength) -> Card -> Card
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over ASetter Card Card CardStrength CardStrength
Lens' Card CardStrength
cardStrength ((Int, Int) -> CardStrength
mkStrength (Int
1, Int
0) CardStrength -> CardStrength -> CardStrength
forall a. Semigroup a => a -> a -> a
<>))
        (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ (Int, Int) -> String -> GameMonad ()
addCreature (Int
2, Int
2) String
"Judith, the Scourge Diva"

    Location -> GameMonad () -> GameMonad ()
withLocation Location
Hand (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
      String -> GameMonad () -> GameMonad ()
withAttribute String
haste (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ (Int, Int) -> String -> GameMonad ()
addCreature (Int
3, Int
4) String
"Grand Warlord Radha"
      String -> GameMonad ()
addInstant String
"Status // Statue"

    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
        -- Note: opponent has hexproof too! Not modeled here.
        [String] -> GameMonad () -> GameMonad ()
withAttributes [String
flying]
          (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ CardMatcher
-> (Card -> CardMatcher)
-> (Card -> Identity Card)
-> GameMonad ()
-> GameMonad ()
withEffect
              CardMatcher
matchInPlay
              Card -> CardMatcher
matchOtherCreatures
              (Card -> Identity Card
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Card -> Identity Card) -> (Card -> Card) -> Card -> Identity Card
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Card -> Card
setAttribute String
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"

        (Int, Int) -> String -> GameMonad ()
addCreature (Int
2, Int
5) String
"Humongulus"
        (Int, Int) -> String -> GameMonad ()
addCreature (Int
6, Int
6) String
"Rakdos, the Showstopper"

  String -> GameMonad () -> GameMonad ()
forall a. String -> GameMonad a -> GameMonad a
step String
"Play Radha" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
    String -> String -> GameMonad ()
tapForMana String
"R" String
"Stomping Ground 1"
    String -> String -> GameMonad ()
tapForMana String
"G" String
"Stomping Ground 2"
    String -> String -> GameMonad ()
tapForMana String
"W" String
"Godless Shrine 1"
    String -> String -> GameMonad ()
tapForMana String
"W" String
"Godless Shrine 2"

    String -> String -> GameMonad ()
cast String
"2RW" String
"Grand Warlord Radha" GameMonad () -> GameMonad () -> GameMonad ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> GameMonad ()
resolveTop
  
  String -> GameMonad () -> GameMonad ()
forall a. String -> GameMonad a -> GameMonad a
step String
"Attack with all except knight, generating mana" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
    [String] -> GameMonad ()
attackWith
      [ String
"Judith, the Scourge Diva"
      , String
"Pitiless Pontiff"
      , String
"Teysa Karlov"
      , String
"Elenda, the Dusk Rose"
      , String
"Grand Warlord Radha"
      ]

    String -> String -> GameMonad ()
trigger String
"Generate Mana" String
"Grand Warlord Radha" GameMonad () -> GameMonad () -> GameMonad ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> GameMonad ()
resolveTop
    CardMatcher -> (String -> GameMonad ()) -> GameMonad ()
forCards
      (String -> CardMatcher
matchAttribute String
attacking)
      (GameMonad () -> String -> GameMonad ()
forall a b. a -> b -> a
const (GameMonad () -> String -> GameMonad ())
-> GameMonad () -> String -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ String -> GameMonad ()
addMana String
"G")

  String -> GameMonad () -> GameMonad ()
forall a. String -> GameMonad a -> GameMonad a
step String
"Status Judith to give her +1/+1 and deathtouch" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
    String -> String -> GameMonad ()
cast String
"G" String
"Status // Statue" GameMonad () -> GameMonad () -> GameMonad ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> GameMonad ()
resolveTop
    String -> (String -> GameMonad ()) -> GameMonad ()
with String
"Judith, the Scourge Diva" ((String -> GameMonad ()) -> GameMonad ())
-> (String -> GameMonad ()) -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ \String
cn -> do
      String -> String -> GameMonad ()
gainAttribute String
deathtouch String
cn
      String -> ASetter Card Card Int Int -> (Int -> Int) -> GameMonad ()
forall a b.
String -> ASetter Card Card a b -> (a -> b) -> GameMonad ()
modifyCardDeprecated String
cn ASetter Card Card Int Int
Lens' Card Int
cardPlusOneCounters (Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)

  String -> GameMonad () -> GameMonad ()
forall a. String -> GameMonad a -> GameMonad a
step String
"Sacrifice Knight to make Pontiff indestructible, ping Shalai and Rakdos with Judith" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
    String -> String -> String -> GameMonad ()
activate String
"Indestructible" String
"1" String
"Pitiless Pontiff"
    String -> GameMonad ()
sacrifice String
"Novice Knight"

    String -> String -> GameMonad ()
trigger String
"+1 1" String
"Elenda, the Dusk Rose"
    String -> String -> GameMonad ()
trigger String
"+1 2" String
"Elenda, the Dusk Rose"
    String -> String -> GameMonad ()
trigger String
"Judith for Elenda 1" String
"Judith, the Scourge Diva"
    String -> String -> GameMonad ()
trigger String
"Judith for Elenda 2" String
"Judith, the Scourge Diva"

    -- Need to put Shalai in the bin to remove hexproof from Rakdos
    GameMonad () -> GameMonad ()
forall a. GameMonad a -> GameMonad a
withStateBasedActions (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
      GameMonad ()
resolveTop
      (Card -> Int) -> Target -> String -> GameMonad ()
damage (Int -> Card -> Int
forall a b. a -> b -> a
const Int
1) (String -> Target
targetCard String
"Shalai, Voice of Plenty") String
"Judith, the Scourge Diva"

    GameMonad ()
resolveTop
    (Card -> Int) -> Target -> String -> GameMonad ()
damage (Int -> Card -> Int
forall a b. a -> b -> a
const Int
1) (String -> Target
targetCard String
"Rakdos, the Showstopper") String
"Judith, the Scourge Diva"

    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
"Elenda, the Dusk Rose" ASetter Card Card Int Int
Lens' Card Int
cardPlusOneCounters (Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
    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
"Elenda, the Dusk Rose" ASetter Card Card Int Int
Lens' Card Int
cardPlusOneCounters (Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)

    String -> GameMonad ()
resolve String
"Indestructible"
    String -> String -> GameMonad ()
gainAttribute String
indestructible String
"Pitiless Pontiff"
    String -> String -> GameMonad ()
gainAttribute String
deathtouch String
"Pitiless Pontiff"
    
  String -> GameMonad () -> GameMonad ()
forall a. String -> GameMonad a -> GameMonad a
step String
"Apply combat damage, doesn't matter what Humongulus blocks, can't kill them" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
    [String] -> String -> GameMonad ()
combatDamage [] String
"Grand Warlord Radha"
    [String] -> String -> GameMonad ()
combatDamage [] String
"Judith, the Scourge Diva"
    [String] -> String -> GameMonad ()
combatDamage [] String
"Pitiless Pontiff"
    [String] -> String -> GameMonad ()
combatDamage [] String
"Teysa Karlov"
    [String] -> String -> GameMonad ()
combatDamage [String
"Humongulus"] String
"Elenda, the Dusk Rose"

  String -> GameMonad () -> GameMonad ()
forall a. String -> GameMonad a -> GameMonad a
step String
"Sacrifice Radha, ping opponent (ignore Elenda triggers, irrelevant)" (GameMonad () -> GameMonad ()) -> GameMonad () -> GameMonad ()
forall a b. (a -> b) -> a -> b
$ do
    String -> String -> String -> GameMonad ()
activate String
"Indestructible" String
"1" String
"Pitiless Pontiff"
    String -> GameMonad ()
sacrifice String
"Grand Warlord Radha"

    String -> String -> GameMonad ()
trigger String
"Judith for Elenda 1" String
"Judith, the Scourge Diva"
    String -> String -> GameMonad ()
trigger String
"Judith for Elenda 2" String
"Judith, the Scourge Diva"

    GameMonad ()
resolveTop
    (Card -> Int) -> Target -> String -> GameMonad ()
damage (Int -> Card -> Int
forall a b. a -> b -> a
const Int
1) (Player -> Target
targetPlayer Player
Opponent) String
"Judith, the Scourge Diva"
    GameMonad ()
resolveTop
    (Card -> Int) -> Target -> String -> GameMonad ()
damage (Int -> Card -> Int
forall a b. a -> b -> a
const Int
1) (Player -> Target
targetPlayer Player
Opponent) String
"Judith, the Scourge Diva"

    String -> GameMonad ()
resolve String
"Indestructible"
    String -> String -> GameMonad ()
gainAttribute String
indestructible String
"Pitiless Pontiff"
    String -> String -> GameMonad ()
gainAttribute String
deathtouch String
"Pitiless Pontiff"

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
"pool" (GameMonad Int -> FormatMonad ())
-> GameMonad Int -> FormatMonad ()
forall a b. (a -> b) -> a -> b
$ Player -> GameMonad Int
countManaPool Player
Active
    
formatter :: p -> Formatter
formatter p
_ = Formatter
attributes Formatter -> Formatter -> Formatter
forall a. Semigroup a => a -> a -> a
<> Formatter
boardFormatter